{"id":13508773,"url":"https://github.com/posthtml/posthtml","last_synced_at":"2025-05-13T15:12:21.489Z","repository":{"id":44955819,"uuid":"37989511","full_name":"posthtml/posthtml","owner":"posthtml","description":"PostHTML is a tool to transform HTML/XML with JS plugins","archived":false,"fork":false,"pushed_at":"2024-06-16T15:54:19.000Z","size":1268,"stargazers_count":2946,"open_issues_count":18,"forks_count":117,"subscribers_count":49,"default_branch":"master","last_synced_at":"2025-04-30T22:32:26.409Z","etag":null,"topics":["html","html-parser","parser","posthtml","transformer","xml","xml-parser"],"latest_commit_sha":null,"homepage":"https://posthtml.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/posthtml.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":".github/contributing.md","funding":".github/funding.yml","license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/codeowners","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":"posthtml","open_collective":"posthtml","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2015-06-24T14:28:28.000Z","updated_at":"2025-04-30T08:51:32.000Z","dependencies_parsed_at":"2024-11-05T23:34:46.272Z","dependency_job_id":"0222ebc3-b721-4751-8e93-8d0caebdb6ce","html_url":"https://github.com/posthtml/posthtml","commit_stats":{"total_commits":449,"total_committers":62,"mean_commits":7.241935483870968,"dds":0.7193763919821826,"last_synced_commit":"b161177ef63edfc3f36d4e86aa9dab9718be33a1"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/posthtml%2Fposthtml/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/posthtml","download_url":"https://codeload.github.com/posthtml/posthtml/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251904151,"owners_count":21662725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","html-parser","parser","posthtml","transformer","xml","xml-parser"],"created_at":"2024-08-01T02:00:58.207Z","updated_at":"2025-05-13T15:12:16.462Z","avatar_url":"https://github.com/posthtml.png","language":"JavaScript","readme":"[![NPM][npm]][npm-url]\n[![Tests][build]][build-url]\n[![Coverage][cover]][cover-url]\n[![Standard Code Style][code-style]][code-style-url]\n\n# PostHTML \u003cimg align=\"right\" width=\"220\" height=\"200\" title=\"PostHTML\" src=\"http://posthtml.github.io/posthtml/logo.svg\"\u003e\n\nPostHTML is a tool for transforming HTML/XML with JS plugins. PostHTML itself is very small. It includes only a HTML parser, a HTML node tree API and a node tree stringifier.\n\nAll HTML transformations are made by plugins. And these plugins are just small plain JS functions, which receive a HTML node tree, transform it, and return a modified tree.\n\nFor more detailed information about PostHTML in general take a look at the [docs][docs-url].\n\n### Dependencies\n\n| Name | Status | Description |\n|:----:|:------:|:-----------:|\n|[posthtml-parser][parser]|[![npm][parser-badge]][parser-npm]| Parser HTML/XML to PostHTMLTree |\n|[posthtml-render][render]|[![npm][render-badge]][render-npm]| Render PostHTMLTree to HTML/XML |\n\n\n[docs]: https://github.com/posthtml/posthtml/blob/master/docs\n\n[parser]: https://github.com/posthtml/posthtml-parser\n[parser-badge]: https://img.shields.io/npm/v/posthtml-parser.svg\n[parser-npm]: https://npmjs.com/package/posthtml-parser\n\n[render]: https://github.com/posthtml/posthtml-render\n[render-badge]: https://img.shields.io/npm/v/posthtml-render.svg\n[render-npm]: https://npmjs.com/package/posthtml-render\n\n## Create to your project\n\n```bash\nnpm init posthtml\n```\n\n## Install\n\n```bash\nnpm i -D posthtml\n```\n\n## Usage\n\n### API\n\n**Sync**\n\n```js\nimport posthtml from 'posthtml'\n\nconst html = `\n  \u003ccomponent\u003e\n    \u003ctitle\u003eSuper Title\u003c/title\u003e\n    \u003ctext\u003eAwesome Text\u003c/text\u003e\n  \u003c/component\u003e\n`\n\nconst result = posthtml()\n  .use(require('posthtml-custom-elements')())\n  .process(html, { sync: true })\n  .html\n\nconsole.log(result)\n```\n\n```html\n\u003cdiv class=\"component\"\u003e\n  \u003cdiv class=\"title\"\u003eSuper Title\u003c/div\u003e\n  \u003cdiv class=\"text\"\u003eAwesome Text\u003c/div\u003e\n\u003c/div\u003e\n```\n\n\u003e :warning: Async Plugins can't be used in sync mode and will throw an Error. It's recommended to use PostHTML asynchronously whenever possible.\n\n**Async**\n\n```js\nimport posthtml from 'posthtml'\n\nconst html = `\n  \u003chtml\u003e\n    \u003cbody\u003e\n      \u003cp class=\"wow\"\u003eOMG\u003c/p\u003e\n    \u003c/body\u003e\n  \u003c/html\u003e\n`\n\nposthtml(\n  [\n    require('posthtml-to-svg-tags')(),\n    require('posthtml-extend-attrs')({\n      attrsTree: {\n        '.wow' : {\n          id: 'wow_id',\n          fill: '#4A83B4',\n          'fill-rule': 'evenodd',\n          'font-family': 'Verdana'\n        }\n      }\n    })\n  ])\n  .process(html/*, options */)\n  .then((result) =\u003e  console.log(result.html))\n```\n\n```html\n\u003csvg xmlns=\"http://www.w3.org/2000/svg\"\u003e\n  \u003ctext\n    class=\"wow\"\n    id=\"wow_id\"\n    fill=\"#4A83B4\"\n    fill-rule=\"evenodd\" font-family=\"Verdana\"\u003e\n      OMG\n  \u003c/text\u003e\n\u003c/svg\u003e\n```\n\n**Directives**\n\n```js\nimport posthtml from 'posthtml'\n\nconst php = `\n  \u003ccomponent\u003e\n    \u003ctitle\u003e\u003c?php echo $title; ?\u003e\u003c/title\u003e\n    \u003ctext\u003e\u003c?php echo $article; ?\u003e\u003c/text\u003e\n  \u003c/component\u003e\n`\n\nconst result = posthtml()\n  .use(require('posthtml-custom-elements')())\n  .process(html, {\n    directives: [\n      { name: '?php', start: '\u003c', end: '\u003e' }\n    ]\n  })\n  .html\n\nconsole.log(result)\n```\n\n```html\n\u003cdiv class=\"component\"\u003e\n  \u003cdiv class=\"title\"\u003e\u003c?php echo $title; ?\u003e\u003c/div\u003e\n  \u003cdiv class=\"text\"\u003e\u003c?php echo $article; ?\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n### [CLI](https://npmjs.com/package/posthtml-cli)\n\n```bash\nnpm i posthtml-cli\n```\n\n```json\n\"scripts\": {\n  \"posthtml\": \"posthtml -o output.html -i input.html -c config.json\"\n}\n```\n\n```bash\nnpm run posthtml\n```\n\n### [Gulp](https://gulpjs.com)\n\n```bash\nnpm i -D gulp-posthtml\n```\n\n```js\nimport tap from 'gulp-tap'\nimport posthtml from 'gulp-posthtml'\nimport { task, src, dest } from 'gulp'\n\ntask('html', () =\u003e {\n  let path\n\n  const plugins = [ require('posthtml-include')({ root: `${path}` }) ]\n  const options = {}\n\n  src('src/**/*.html')\n    .pipe(tap((file) =\u003e path = file.path))\n    .pipe(posthtml(plugins, options))\n    .pipe(dest('build/'))\n})\n```\n\nCheck [project-stub](https://github.com/posthtml/project-stub) for an example with Gulp\n\n### [Grunt](https://gruntjs.com)\n\n```bash\nnpm i -D grunt-posthtml\n```\n\n```js\nposthtml: {\n  options: {\n    use: [\n      require('posthtml-doctype')({ doctype: 'HTML 5' }),\n      require('posthtml-include')({ root: './', encoding: 'utf-8' })\n    ]\n  },\n  build: {\n    files: [\n      {\n        dot: true,\n        cwd: 'html/',\n        src: ['*.html'],\n        dest: 'tmp/',\n        expand: true,\n      }\n    ]\n  }\n}\n```\n\n### [Webpack](https://webpack.js.org)\n\n```bash\nnpm i -D html-loader posthtml-loader\n```\n\n#### v1.x\n\n**webpack.config.js**\n\n```js\nconst config = {\n  module: {\n    loaders: [\n      {\n        test: /\\.html$/,\n        loader: 'html!posthtml'\n      }\n    ]\n  },\n  posthtml: (ctx) =\u003e ({\n    parser: require('posthtml-pug'),\n    plugins: [\n      require('posthtml-bem')()\n    ]\n  })\n}\n\nexport default config\n```\n\n#### v2.x\n\n**webpack.config.js**\n\n```js\nimport { LoaderOptionsPlugin } from 'webpack'\n\nconst config = {\n  module: {\n    rules: [\n      {\n        test: /\\.html$/,\n        use: [\n          {\n            loader: 'html-loader',\n            options: { minimize: true }\n          },\n          {\n            loader: 'posthtml-loader'\n          }\n        ]\n      }\n    ]\n  },\n  plugins: [\n    new LoaderOptionsPlugin({\n      options: {\n        posthtml(ctx) {\n          return {\n            parser: require('posthtml-pug'),\n            plugins: [\n              require('posthtml-bem')()\n            ]\n          }\n        }\n      }\n    })\n  ]\n}\n\nexport default config\n```\n\n### [Rollup](https://rollupjs.org/)\n\n```bash\n$ npm i rollup-plugin-posthtml -D\n# or\n$ npm i rollup-plugin-posthtml-template -D\n```\n\n```js\nimport { join } from 'path';\n\nimport posthtml from 'rollup-plugin-posthtml-template';\n// or\n// import posthtml from 'rollup-plugin-posthtml';\n\nimport sugarml from 'posthtml-sugarml';  // npm i posthtml-sugarml -D\nimport include from 'posthtml-include';  // npm i posthtml-include -D\n\nexport default {\n  entry: join(__dirname, 'main.js'),\n  dest: join(__dirname, 'bundle.js'),\n  format: 'iife',\n  plugins: [\n    posthtml({\n      parser: sugarml(),\n      plugins: [include()],\n      template: true  // only rollup-plugin-posthtml-template\n    })\n  ]\n};\n```\n\n## Parser\n\n```js\nimport pug from 'posthtml-pug'\n\nposthtml().process(html, { parser: pug(options) }).then((result) =\u003e result.html)\n```\n\n| Name |Status|Description|\n|:-----|:-----|:----------|\n|[posthtml-pug][pug]|[![npm][pug-badge]][pug-npm]|Pug Parser|\n|[sugarml][sugar]|[![npm][sugar-badge]][sugar-npm]|SugarML Parser|\n\n\n[pug]: https://github.com/posthtml/posthtml-pug\n[pug-badge]: https://img.shields.io/npm/v/posthtml-pug.svg\n[pug-npm]: https://npmjs.com/package/posthtml-pug\n\n[sugar]: https://github.com/posthtml/sugarml\n[sugar-badge]: https://img.shields.io/npm/v/sugarml.svg\n[sugar-npm]: https://npmjs.com/package/sugarml\n\n## Plugins\n\nIn case you want to develop your own plugin, we recommend using [posthtml-plugin-starter][plugin] to get started.\n\n- [posthtml-plugins](http://maltsev.github.io/posthtml-plugins)\n- [awesome-posthtml](https://github.com/posthtml/awesome-posthtml)\n\n[plugin]: https://github.com/posthtml/posthtml-plugin-starter\n\n## Maintainers\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n   \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg width=\"150 height=\"150\"\n      src=\"https://avatars0.githubusercontent.com/u/2789192?s=460\u0026v=4\"\u003e\n      \u003cbr /\u003e\n      \u003ca href=\"https://github.com/scrum\"\u003eIvan Demidov\u003c/a\u003e\n    \u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\n      \u003cimg width=\"150 height=\"150\"\n      src=\"https://avatars.githubusercontent.com/u/1510217?v=3\u0026s=150\"\u003e\n      \u003cbr /\u003e\n      \u003ca href=\"https://github.com/voischev\"\u003eIvan Voischev\u003c/a\u003e\n    \u003c/td\u003e\n   \u003c/tr\u003e\n  \u003ctbody\u003e\n\u003c/table\u003e\n\n## Contributors\n\n\u003ca href=\"https://github.com/posthtml/posthtml/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/posthtml/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/posthtml#backer)]\n\n\u003ca href=\"https://opencollective.com/posthtml#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/posthtml/backers.svg?width=885\u0026button=false\"\u003e\u003c/a\u003e\n\n\n[npm]: https://img.shields.io/npm/v/posthtml.svg\n[npm-url]: https://npmjs.com/package/posthtml\n\n[build]: https://github.com/posthtml/posthtml/workflows/Actions%20Status/badge.svg?style=flat-square\n[build-url]: https://github.com/posthtml/posthtml/actions?query=workflow%3A%22CI+tests%22\n\n[cover]: https://coveralls.io/repos/posthtml/posthtml/badge.svg?branch=master\n[cover-url]: https://coveralls.io/r/posthtml/posthtml?branch=master\n\n[code-style]: https://img.shields.io/badge/code%20style-standard-yellow.svg\n[code-style-url]: http://standardjs.com/\n\n[chat]: https://badges.gitter.im/posthtml/PostHTML.svg\n[chat-url]: https://gitter.im/posthtml/posthtml?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge\"\n[docs-url]: https://github.com/posthtml/posthtml/tree/master/docs\n","funding_links":["https://patreon.com/posthtml","https://opencollective.com/posthtml"],"categories":["JavaScript","\u003e 1k ★","html"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthtml%2Fposthtml","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fposthtml%2Fposthtml","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fposthtml%2Fposthtml/lists"}