{"id":13991654,"url":"https://github.com/metalsmith/in-place","last_synced_at":"2025-04-13T10:52:22.156Z","repository":{"id":23409926,"uuid":"26772303","full_name":"metalsmith/in-place","owner":"metalsmith","description":"A metalsmith plugin for in-place templating","archived":false,"fork":false,"pushed_at":"2023-11-02T23:29:14.000Z","size":2808,"stargazers_count":57,"open_issues_count":0,"forks_count":27,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-14T07:34:54.570Z","etag":null,"topics":["metalsmith","metalsmith-plugin","node","templating"],"latest_commit_sha":null,"homepage":"","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/metalsmith.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2014-11-17T19:05:42.000Z","updated_at":"2024-05-17T16:42:46.000Z","dependencies_parsed_at":"2023-02-18T01:00:44.758Z","dependency_job_id":"ff1dd70c-e811-4f5e-a80d-eec3412ee80f","html_url":"https://github.com/metalsmith/in-place","commit_stats":{"total_commits":173,"total_committers":17,"mean_commits":"10.176470588235293","dds":0.4566473988439307,"last_synced_commit":"10ec0144b3824ce33c84d256b0a3d73352b79add"},"previous_names":["metalsmith/metalsmith-in-place"],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metalsmith%2Fin-place","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metalsmith%2Fin-place/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metalsmith%2Fin-place/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metalsmith%2Fin-place/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metalsmith","download_url":"https://codeload.github.com/metalsmith/in-place/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245206380,"owners_count":20577577,"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":["metalsmith","metalsmith-plugin","node","templating"],"created_at":"2024-08-09T14:01:30.775Z","updated_at":"2025-03-27T02:10:19.065Z","avatar_url":"https://github.com/metalsmith.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","node"],"sub_categories":[],"readme":"# @metalsmith/in-place\n\nA metalsmith plugin for transforming source files' contents. Complements [@metalsmith/layouts](https://github.com/metalsmith/layouts)\n\n[![metalsmith: core plugin][metalsmith-badge]][metalsmith-url]\n[![npm: version][npm-badge]][npm-url]\n[![ci: build][ci-badge]][ci-url]\n[![code coverage][codecov-badge]][codecov-url]\n[![license: MIT][license-badge]][license-url]\n\n## Features\n\n- renders source files' `contents` field with any existing or a custom [Jstransformer templating engine](https://github.com/jstransformers/jstransformer)\n- alters file extensions from `transform.inputFormats` to `transform.outputFormat`\n- can be used multiple times with different configs per metalsmith pipeline\n\n## Installation\n\nNPM:\n\n```bash\nnpm install @metalsmith/in-place jstransformer-handlebars\n```\n\nYarn:\n\n```bash\nyarn add @metalsmith/in-place jstransformer-handlebars\n\n```\n\nThis plugin works with [jstransformers](https://github.com/jstransformers/jstransformer) but they should be installed separately. `jstransformer-handlebars` is just an example, you could use any transformer. To render markdown you could install [jstransformer-marked](https://github.com/jstransformers/jstransformer-marked). To render handlebars you would install [jstransformer-handlebars](https://github.com/jstransformers/jstransformer-handlebars). Other popular templating options include: [Nunjucks](https://github.com/jstransformers/jstransformer-nunjucks), [Twig](https://github.com/jstransformers/jstransformer-twig), [Pug](https://github.com/jstransformers/jstransformer-pug), or [EJS](https://github.com/jstransformers/jstransformer-ejs). See also [this map](https://github.com/jstransformers/inputformat-to-jstransformer/blob/master/dictionary.json) to see which extensions map to which jstransformer.\n\n## Usage\n\nPass `@metalsmith/in-place` to `metalsmith.use` :\n\n```js\nimport inPlace from '@metalsmith/in-place'\n\n// shorthand\nmetalsmith.use(inPlace({ transform: 'nunjucks' }))\n\n// same as shorthand\nmetalsmith.use(\n  inPlace({\n    transform: jsTransformerNunjucks, // resolved\n    extname: '.html',\n    pattern: '**/*.{njk,nunjucks}*',\n    engineOptions: {}\n  })\n)\n```\n\nIn the transformed file, you have access to `{ ...metalsmith.metadata(), ...fileMetadata }`, so that the following build\n\n```js\nmetalsmith.metadata({ title: 'Default title', nodeVersion: process.version }).use(inPlace({ transform: 'handlebars' }))\n```\n\nfor a file:\n\n```yml\n---\ntitle: Article title\n---\n\u003ch1\u003e{{ title }}\u003c/h1\u003eNode v{{ nodeVersion }}\n```\n\nwould render `\u003ch1\u003eArticle title\u003c/h1\u003eNode v16.20`\n\nMultiple transforms can be used to target different sets of files, or to reprocess the same files multiple times in the order they are `metalsmith.use`'d:\n\n```js\n// this build will apply the marked transform to index.md, the handlebars transform to index.hbs,\n// and handlebars first, marked second to both index.hbs.md, index.md.hbs, and html-minifier to all (only in production)\nmetalsmith\n  .env('NODE_ENV', process.env.NODE_ENV)\n  .use(inPlace({ transform: 'handlebars', extname: null }))\n  .use(inPlace({ transform: 'marked' }))\n\nif (metalsmith.env('NODE_ENV') !== 'development') {\n  metalsmith.use(inPlace({ transform: 'html-minifier' }))\n}\n```\n\n### Options\n\nIn most cases, you will only need to specify the `transform` and `engineOptions` option.\n\n- [transform](#transform) (`string|JsTransformer`): **required**. Which transformer to use. The full name of the transformer, e.g. `jstransformer-handlebars`, its shorthand `handlebars`, a relative JS module path starting with `.`, e.g. `./my-transformer.js`, whose default export is a jstransformer or an actual jstransformer: an object with `name`, `inputFormats`,`outputFormat`, and at least one of the render methods `render`, `renderAsync`, `compile` or `compileAsync` described in the [jstransformer API docs](https://github.com/jstransformers/jstransformer#api)\n- [extname](#extension-handling) (`string|false|null`): optional. How to transform a file's extensions: `''|false|null` to remove the last `transform.inputFormat` matching extension, `.\u003cext\u003e` to force an extension rename.\n- [engineOptions](#engineoptions) (`Object\u003cstring, any\u003e`): optional. Pass options to the jstransformer that's rendering the files. The default is `{}`.\n- pattern (`string|string[]`): optional. Override default glob pattern matching `**/*.\u003ctransform.inputFormats\u003e*`. Useful to limit the scope of the transform by path or glob to a subfolder, or to include files not matching `transform.inputFormats`.\n\n### Extension handling\n\nBy default in-place will apply smart default extension handling based on `transform.inputFormats` and `transform.outputFormat`.\nFor example, any of the source files below processed through `inPlace({ transform: 'handlebars' })` will yield `index.html`.\n\n| source             | output           |\n| ------------------ | ---------------- |\n| src/index.hbs      | build/index.html |\n| src/index.hbs.html | build/index.html |\n| src/index.html.hbs | build/index.html |\n\nThe example demonstrates that:\n\n- order of extensions doesn't matter, _order of plugin execution does!_: you can pick the final extension to match the most suitable editor syntax highlighting\n- a single in-place run only alters the rightmost extension matching `transform.inputFormats`\n- you may choose to include or omit the `transform.outputFormat` in the source file name (.html in this case).\n\n### `engineOptions`\n\nPass options to the jstransformer that's rendering your templates via `engineOptions`. The\n`metalsmith.json`:\n\n```json\n{\n  \"source\": \"src\",\n  \"destination\": \"build\",\n  \"plugins\": [\n    {\n      \"@metalsmith/in-place\": {\n        \"transform\": \"ejs\",\n        \"engineOptions\": {\n          \"cache\": false\n        }\n      }\n    }\n  ]\n}\n```\n\n..would pass `{ \"cache\": false }` to `jstransformer-ejs`.\n\nIf you use [Pug](https://pugjs.org/api/getting-started.html), make sure to pass `engineOptions: { filename: true }`. This will ensure the filename of each processed file is passed to the render method as expected by this engine.\n\n### Multiple transforms per file\n\nSuppose a file `tags.hbs` that lists all the article tags used on your website\n\n```hbs\n---\ntitle: Tags\ndescription: Browse articles by tag\n---\n\u003ch1\u003e{{ title }}\u003c/h1\u003e\n\u003cp\u003e{{ description }}\u003c/p\u003e\n\u003cul\u003e\n{{#each tags}}\n  \u003cli\u003e\u003ca href=\"/tags/{{ . }}\"\u003e{{ . }}\u003c/a\u003e\u003c/li\u003e\n{{/each}}\n\u003c/ul\u003e\n```\n\nTo reduce Handlebars noise, you could add `metalsmith.use(inPlace({ transform: 'marked' })` to your build and change the filename to `tags.hbs.md` to generate markdown syntax with Handlebars!\n\n```hbs\n---\ntitle: Tags\ndescription: Browse articles by tag\n---\n\n# {{ title }}\n\n{{ description }}\n\n{{#each tags}}\n- [{{.}}](/tags/{{ . }})\n{{/each}}\n\nMore markdown here..\n```\n\n**Caution**: when using multiple templating transforms per file, make sure there is no conflicting syntax.\nFor example markdown will transform blocks indented by 4 spaces to `\u003cpre\u003e` tags, and marked's `smartypants` can potentially garble the result.\n\n### Usage with @metalsmith/layouts\n\nIn most cases `@metalsmith/in-place` is intended to be used _before_ `@metalsmith/layouts`.\nYou can easily share `engineOptions` configs between both plugins:\n\n```js\nimport inPlace from '@metalsmith/in-place'\nimport layouts from '@metalsmith/layouts'\n\nconst engineOptions = {}\nmetalsmith // index.hbs.hbs\n  .use(inPlace({ transform: 'handlebars', extname: '', engineOptions })) // -\u003e index.hbs\n  .use(layouts({ engineOptions })) // -\u003e index.html\n```\n\n@metalsmith/layouts uses a similar mechanism targeting `transform.inputFormats` file extensions by default.\nThe example requires files ending in `.hbs.hbs` extension, but if you don't like this, you can just have a single `.hbs` extension, and change the in-place invocation to `inPlace({ engineOptions, transform, extname: '.hbs' })` for the same result.\n\n### Debug\n\nTo enable debug logs, set the `DEBUG` environment variable to `@metalsmith/in-place*`:\n\n```js\nmetalsmith.env('DEBUG', '@metalsmith/in-place*')\n```\n\nAlternatively you can set `DEBUG` to `@metalsmith/*` to debug all Metalsmith core plugins.\n\n## Credits\n\n- [Ismay Wolff](https://github.com/ismay) for improving upon metalsmith-templates \u0026 diligently maintaining its successor\n- [Ian Storm Taylor](https://github.com/ianstormtaylor) for creating [metalsmith-templates](https://github.com/segmentio/metalsmith-templates), on which this plugin was based\n- [Rob Loach](https://github.com/RobLoach) for creating [metalsmith-jstransformer](https://github.com/RobLoach/metalsmith-jstransformer), which inspired our switch to jstransformers\n\n## License\n\n[MIT](LICENSE)\n\n[npm-badge]: https://img.shields.io/npm/v/@metalsmith/in-place.svg\n[npm-url]: https://www.npmjs.com/package/@metalsmith/in-place\n[ci-badge]: https://github.com/metalsmith/in-place/actions/workflows/test.yml/badge.svg\n[ci-url]: https://github.com/metalsmith/in-place/actions/workflows/test.yml\n[metalsmith-badge]: https://img.shields.io/badge/metalsmith-core_plugin-green.svg?longCache=true\n[metalsmith-url]: https://metalsmith.io\n[codecov-badge]: https://img.shields.io/coveralls/github/metalsmith/in-place\n[codecov-url]: https://coveralls.io/github/metalsmith/in-place\n[license-badge]: https://img.shields.io/github/license/metalsmith/in-place\n[license-url]: LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetalsmith%2Fin-place","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetalsmith%2Fin-place","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetalsmith%2Fin-place/lists"}