From b7224c3d3e32691aa210af97ea38cc417ce9d053 Mon Sep 17 00:00:00 2001 From: Steve Calvert Date: Thu, 4 Apr 2019 17:51:07 -0700 Subject: [PATCH] Adding docs-page blueprint. (#343) * Adding docs-page blueprint. Includes router invocation. * Adding updating docs.hbs with new nav item * Adding documentation for docs-page blueprint * Removing placeholder to adds pods support to adding a nav item * Refining docs to be reflective of output * Bugfixes for stupid mistakes --- .../__templatepath__/__templatename__.md | 3 + blueprints/docs-page/index.js | 129 ++++++++++++++++++ package.json | 3 + .../app/pods/docs/quickstart/template.md | 29 +++- 4 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 blueprints/docs-page/files/__templatepath__/__templatename__.md create mode 100644 blueprints/docs-page/index.js diff --git a/blueprints/docs-page/files/__templatepath__/__templatename__.md b/blueprints/docs-page/files/__templatepath__/__templatename__.md new file mode 100644 index 000000000..694acb2cd --- /dev/null +++ b/blueprints/docs-page/files/__templatepath__/__templatename__.md @@ -0,0 +1,3 @@ +# <%= templateName %> + +<%= templateName %> content diff --git a/blueprints/docs-page/index.js b/blueprints/docs-page/index.js new file mode 100644 index 000000000..6dc71970f --- /dev/null +++ b/blueprints/docs-page/index.js @@ -0,0 +1,129 @@ +/* eslint-env node */ +const path = require('path'); +const fs = require('fs'); +const chalk = require('chalk'); +const EmberRouterGenerator = require('ember-router-generator'); +const stringUtil = require('ember-cli-string-utils'); + +const DUMMY_APP_PATH = path.join('tests', 'dummy', 'app'); + +function dedasherize(str) { + let dedasherized = str.replace(/-/g, ' '); + + return stringUtil.capitalize(dedasherized); +} + +module.exports = { + name: 'docs-page', + description: 'Generates an ember-cli-addon-docs doc page', + + fileMapTokens: function() { + return { + __templatepath__: function(options) { + if (options.pod) { + return path.join( + DUMMY_APP_PATH, + 'pods', + 'docs', + options.dasherizedModuleName + ); + } else { + return path.join(DUMMY_APP_PATH, 'templates', 'docs'); + } + }, + __templatename__: function(options) { + if (options.pod) { + return 'template'; + } + return options.dasherizedModuleName; + } + }; + }, + + locals: function(options) { + return { + templateName: dedasherize(options.entity.name) + }; + }, + + afterInstall: function(options) { + // eslint-disable-next-line no-debugger + debugger; + updateRouter.call(this, 'add', options); + updateDocsTemplate.call(this, options); + }, + + afterUninstall: function(options) { + updateRouter.call(this, 'remove', options); + } +}; + +function updateRouter(action, options) { + let entity = options.entity; + let actionColorMap = { + add: 'green', + remove: 'red' + }; + let color = actionColorMap[action] || 'gray'; + + if (entity.name === 'index') { + return; + } + + writeRoute(action, entity.name, options); + + this.ui.writeLine('updating router'); + this._writeStatusToUI(chalk[color], action + ' route', entity.name); +} + +function findRouter(options) { + let routerPathParts = [].concat([ + options.project.root, + DUMMY_APP_PATH, + 'router.js' + ]); + + return routerPathParts; +} + +function writeRoute(action, name, options) { + let routerPath = path.join.apply(null, findRouter(options)); + let source = fs.readFileSync(routerPath, 'utf-8'); + + let routes = new EmberRouterGenerator(source); + let newRoutes = routes[action](name, options); + + fs.writeFileSync(routerPath, newRoutes.code()); +} + +function updateDocsTemplate(options) { + let routeName = options.entity.name; + let docsTemplatePath = options.pods + ? path.join(DUMMY_APP_PATH, 'pods', 'docs', 'template.hbs') + : path.join(DUMMY_APP_PATH, 'templates', 'docs.hbs'); + + if (fs.existsSync(docsTemplatePath)) { + let templateLines = fs + .readFileSync(docsTemplatePath, 'utf-8') + .toString() + .split('\n'); + + let closingViewerNavTag = templateLines.find(line => + line.includes('{{/viewer.nav}}') + ); + + templateLines.splice( + templateLines.indexOf(closingViewerNavTag), + 0, + `${''.padStart( + closingViewerNavTag.search(/\S/) * 2, + ' ' + )}{{nav.item "${dedasherize(routeName)}" "docs.${routeName}"}}` + ); + + fs.writeFileSync(docsTemplatePath, templateLines.join('\n')); + + this.ui.writeLine('updating docs.hbs'); + this._writeStatusToUI(chalk.green, 'add nav item', 'docs.hbs'); + } +} diff --git a/package.json b/package.json index 3929fa51a..2573d2206 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "broccoli-plugin": "^1.3.1", "broccoli-source": "^1.1.0", "broccoli-stew": "^2.0.0", + "chalk": "^2.4.2", "ember-auto-import": "^1.2.19", "ember-cli-autoprefixer": "^0.8.1", "ember-cli-babel": "^6.16.0", @@ -44,6 +45,7 @@ "ember-cli-htmlbars-inline-precompile": "^1.0.3", "ember-cli-sass": "10.0.0", "ember-cli-string-helpers": "^1.9.0", + "ember-cli-string-utils": "^1.1.0", "ember-cli-tailwind": "^0.6.2", "ember-code-snippet": "^2.4.0", "ember-component-css": "^0.6.7", @@ -55,6 +57,7 @@ "ember-keyboard": "^4.0.0", "ember-modal-dialog": "3.0.0-beta.3", "ember-responsive": "^3.0.0-beta.1", + "ember-router-generator": "^1.2.3", "ember-router-scroll": "^1.0.0", "ember-svg-jar": "^1.2.2", "ember-tether": "^1.0.0-beta.2", diff --git a/tests/dummy/app/pods/docs/quickstart/template.md b/tests/dummy/app/pods/docs/quickstart/template.md index f976c1c50..a91a751eb 100644 --- a/tests/dummy/app/pods/docs/quickstart/template.md +++ b/tests/dummy/app/pods/docs/quickstart/template.md @@ -65,18 +65,39 @@ all docs pages in your site. documentation for your addon and live in the folder `tests/dummy/app/templates/docs`. Since Addon Docs supports Markdown out of the box we will create two `.md` files (one for your docs `index` and one -for the `usage` page). +for the `usage` page). Addon Docs includes a `docs-page` **blueprint** to make +adding docs routes easier. The blueprint will generate: + + - the **markdown file** in the `tests/dummy/app/templates/docs` directory + - the **nav item entry** in `tests/dummy/app/templates/docs.md` _if it exists_ + - the **`route` entry** in `tests/dummy/app/router.js` _for non-`index` routes_ + + Generate an `index` route using the following: + + ```bash + ember generate docs-page index + ``` + + This will generate the following markdown file. {{#docs-snippet name='quickstart-markdown-index.md' title='tests/dummy/app/templates/docs/index.md' language='markdown'}} - # Introduction + # Index - This is my new addon, and it rocks! + Index content {{/docs-snippet}} + Generate a `usage` route using the same blueprint as above. + + ```bash + ember generate docs-page usage + ``` + + This will generate and modify the files for your `usage` docs page. + {{#docs-snippet name='quickstart-markdown-subpage.md' title='tests/dummy/app/templates/docs/usage.md' language='markdown'}} # Usage - So easy to use, sweet! + Usage content {{/docs-snippet}} 6. **Create your marketing homepage**. Addon Docs comes with a set of