diff --git a/www/assets/greenwood-starter-presentation.png b/www/assets/greenwood-starter-presentation.png new file mode 100644 index 000000000..4a3f11040 Binary files /dev/null and b/www/assets/greenwood-starter-presentation.png differ diff --git a/www/pages/guides/theme-packs.md b/www/pages/guides/theme-packs.md index ded5dd762..cd10838f2 100644 --- a/www/pages/guides/theme-packs.md +++ b/www/pages/guides/theme-packs.md @@ -7,31 +7,32 @@ index: 2 ## Creating a Theme Pack -Introduced as a concept in the [Context Plugin docs](/plugins/context/), a theme pack is what Greenwood uses to refer to a plugin that aims to provide a set of reasuale templates, pages and more to a user (think of [**CSS Zen Garden**](http://www.csszengarden.com/)). A good example (and the one used in this guide!) is greenwood-starter-presentation, which provides the starting point for creating a slide deck entirely from markdown, using Greenwood! +Introduced as a concept in the [Context Plugin docs](/plugins/context/), a theme pack is what Greenwood uses to refer to a plugin that aims to provide a set of reasuale templates, pages and more to a user (think of [**CSS Zen Garden**](http://www.csszengarden.com/)). A good example (and the one this guide is based on) is [**greenwood-starter-presentation**](https://github.com/thescientist13/greenwood-starter-presentation), which provides the starting point for creating a [slide deck entirely from markdown](https://github.com/thescientist13/knowing-your-tco), using Greenwood! -> _Support for pages [coming soon](https://github.com/ProjectEvergreen/greenwood/issues/681)_! + ### Prerequistes -This guide will walk through the process of setting up Greenwood to support the developing and publishing of your package (theme pack) to npm. +This guide will walk through the process of setting up Greenwood to support the developing and publishing of your package (theme pack) to **npm**. To try and focus on just the theme pack aspects, this guide assumes a couple things: -- You are already familiar with [setting up](/getting-started/) a Greenwood project. -- You are familiar with [publishing packages to npm](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages). -- Assumes a Unix "like" environment (in regards to commands and file path examples used), though the same can definifitely be done on Windows. +1. You are already familiar with [setting up](/getting-started/) a Greenwood project. +1. You are familiar with [publishing packages to npm](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages). +1. Assumes a Unix "like" environment (in regards to commands and file path examples used), though the same can definifitely be done on Windows. We encourage using Greenwood to develop your theme pack mainly so that you can ensure a seamless experience when publishing to npm knowing that things should just work. ™️ ### Project Setup For the sake of development, you can create as much as you need to recreate a user workspace and to simulate what your theme pack would look like. Think of it like creating a [Storybook](https://storybook.js.org/) for your theme pack. -For this guide, we will be publishing _templates/_ and _styles/_ to npm, and so _pages/_ will just be used as a way to pull in the template for local development and testing purposes. + +For this guide, we will be publishing _layouts/_ (templates) and _styles/_ to **npm**. The _pages/_ diretory is just being used to pull in the template for local development and testing purposes for you as the plugin author. ```shell src/ pages/ index.md styles/ theme.css - templates/ + layouts/ blog-post.html package.json my-theme-pack.js @@ -61,19 +62,23 @@ module.exports = () => [{ provider: () => { return { templates: [ - path.join(__dirname, 'dist/templates') + // __dirname will be _node_modules/your-package/_ + // when your plugin is run in a users project + path.join(__dirname, 'dist/layouts') ] }; } }]; ``` -_blog-post.html_ +_src/layouts/blog-post.html_ ```html + +
- + @@ -86,14 +91,14 @@ _blog-post.html_ ``` -_theme.css_ +_src/styles/theme.css_ ```css * { color: red } ``` -_index.md_ +_src/pages/index.md_ ```md --- template: 'blog-post' @@ -104,36 +109,25 @@ template: 'blog-post' Lorum Ipsum, this is a test. ``` -You should then be able to run `yarn develop` and load `/` in your browser and the color of the text should be red. - -You're all ready for development! 🙌 - ### Development -The main consideration needed for development is that your files won't be in _node_modules_, which is what the case would be for users when you publish. So for that reason, we need to add a little boilerplate to _my-theme-pack.js_. There might be others way to solve it, but it just checks if the packages is installed and: -1. If it _is_ installed, then use `__dirname` (which would resolve to somewhere inside _node_modules_) as the base path -1. If it _is not_ installed (like for local development) then you can use use whatever location you have defined in your repository. Most common would just be to use `process.cwd` +The main consideration needed for development is that your files won't be in _node_modules_, which is what the case would be for users when you publish. So for that reason, we need to add a little boilerplate to _my-theme-pack.js_. There might be others way to solve it, but for right now, accepting a "developer only" flag can easily make the plugin pivot into local or "published" modes. + +1. If the flag _is_ passed, then use `__dirname` (which would resolve to somewhere inside _node_modules_) as the base path +1. If the flag _is not_ installed (like we want for local development) then you can use use whatever location you have defined in your repository. Most common would just be to use `process.cwd` So using our current example, our final _my-theme-pack.js_ would look like this: ```js -const os = require('os'); const path = require('path'); -const packageJson = require('./package.json'); -const { spawnSync } = require('child_process'); module.exports = () => [{ type: 'context', name: 'my-theme-pack:context', - provider: () => { - const { name } = packageJson; - const baseDistDir = `node_modules/${name}/dist`; - const command = os.platform() === 'win32' ? 'npm.cmd' : 'npm'; - const ls = spawnSync(command, ['ls', name]); - const isInstalled = ls.stdout.toString().indexOf('(empty)') < 0; - - const templateLocation = isInstalled - ? path.join(__dirname, `${baseDistDir}/templates`) - : path.join(process.cwd(), 'src/templates'); + provider: (options = {}) => { + // you can use other directory names besides templates/ this way! + const templateLocation = options.__isDevelopment + ? path.join(process.cwd(), 'src/layouts') + : path.join(__dirname, 'dist/layouts'); return { templates: [ @@ -144,7 +138,9 @@ module.exports = () => [{ }]; ``` -And our final _greenwood.config.js_ would look like this, which add a "one-off" [resource plugin](/plugins/resource/) to tell Greenwood to route requests to your theme pack files from their _node_modules_ path to the source directory of your repository for development. +And our final _greenwood.config.js_ would look like this, which add a "one-off" [resource plugin](/plugins/resource/) to tell Greenwood to route requests to your theme pack files away from _node_modules+ and to the location of your projects files for development. + +Additionally, we make sure to pass the flag from above for `__isDevelopment` to our plugin. ```js // shared from another test const myThemePackPlugin = require('./my-theme-pack'); @@ -169,7 +165,9 @@ class MyThemePackDevelopmentResource extends ResourceInterface { module.exports = { plugins: [ - ...myThemePackPlugin(), + ...myThemePackPlugin({ + __isDevelopment: true + }), { type: 'resource', name: 'my-theme-pack:resource', @@ -179,13 +177,15 @@ module.exports = { }; ``` -> _We realize this current workflow is a bit clunky at the moment, so please follow [this discussion](https://github.com/ProjectEvergreen/greenwood/discussions/682) for ways we can try and make this more elegant!_ 🙏🏻 +You should then be able to run `yarn develop` and load `/` in your browser and the color of the text should be red. + +You're all ready for development now! 🙌 ### Publishing -When it comes to publishing, it should be fairly straightforward, you'll just want to do the following +When it comes to publishing, it should be fairly straightforward, and you'll just want to do the following: 1. Add _dist/_ to _.gitignore_ (or whatever `files` location you want to use for publishing) -1. Add a `prepublish` script to your _package.json_ to create the _dist/_ directory with all the needed _templates/_ and _styles/_ +1. Add a `prepublish` script to your _package.json_ to create the _dist/_ directory with all the needed _layouts_ (templates) /_ and _styles/_ ```json { "name": "my-theme-pack", @@ -196,13 +196,16 @@ When it comes to publishing, it should be fairly straightforward, you'll just wa "dist/" ], "scripts": { - "prepublish": "rm -rf dist/ && mkdir dist/ && cd src/ && cp -rv templates ../dist && cp -rv pages ../dist" + "prepublish": "rm -rf dist/ && mkdir dist/ && rsync -rv --exclude 'pages/' src/ dist" } } ``` +1. Now, when you run `npm publish` a fresh _dist/_ folder will be made and [included in your package](https://unpkg.com/browse/greenwood-starter-presentation/) + +### Installation and Usage for Users +With the above in place and the package published, you're now ready to share your theme pack with other Greenwood users! -### Installation and Usage -With the above in place the package published, user's would just need to do the following +For users, they would just need to do the following: 1. Install the plugin from npm ```shell @@ -210,7 +213,6 @@ With the above in place the package published, user's would just need to do the ``` 1. Add the plugin to their _greenwood.config.js_ ```js - // shared with another test develop.plugins.context const myThemePackPlugin = require('my-theme-pack'); module.exports = { @@ -219,15 +221,87 @@ With the above in place the package published, user's would just need to do the ] }; ``` -1. Then in any of their markdown files, users would just reference the published template's filename +1. Then in any of their markdown files, users would just need to reference the published template's filename ```md --- template: 'blog-post' --- - My Blog Post using Theme Packs! + My Blog Post using Theme Packs! 💯 ``` Success! 🥳 -> _Don't forget, user's can also [include additional CSS / JS files in their frontmatter](/docs/front-matter/#imports), to further extend, customize, and override your templates!_ \ No newline at end of file +> _Don't forget, user's can also [include additional CSS / JS files in their frontmatter](/docs/front-matter/#imports), to further extend, customize, and override your templates!_ + + +### FAQ + +#### _I'm getting an (Rollup) error when trying to build or test my theme pack for production_ +If you try and run `yarn build` or `yarn serve` in a repo where you are creating the theme pack, as per the guide here, you may see this error if you reference assets like `