Skip to content

Commit

Permalink
Guides/issue 689 improve docs for theme pack developers (#696)
Browse files Browse the repository at this point in the history
* theme pack docs update and added test cases to cover plugin authors building with Greenwood while developing a theme pack

* plugin author develop specs added for theme packs

* remove FAQ item about building and serving for theme pack development

* fix development resource example

* update example
  • Loading branch information
thescientist13 authored Aug 20, 2021
1 parent b68ab76 commit a375ce3
Show file tree
Hide file tree
Showing 13 changed files with 486 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Use Case
* Run Greenwood with a custom context plugin that provides custom templates (app / page) and resources (JS / CSS); aka a "theme pack".
* Build with Greenwood when using a custom context plugin (e.g. installed via npm) that provides custom templates (app / page) and resources (JS / CSS); aka a "theme pack".
*
* User Result
* Should generate a bare bones Greenwood build with expected templates being used from node_modules along with JS and CSS.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*
* Use Case
* Develop with Greenwood with a custom context plugin that provides custom templates (app / page) and resources (JS / CSS); aka a "theme pack".
* Develop with Greenwood when using a custom context plugin (e.g. installed via npm) that provides custom templates (app / page) and resources (JS / CSS); aka a "theme pack".
*
* User Result
* Should start development server with expected templates being used from node_modules along with JS and CSS.
*
* User Command
* greenwood build
* greenwood develop
*
* User Config
* Mock Theme Pack Plugin (from fixtures)
Expand Down
33 changes: 33 additions & 0 deletions packages/cli/test/cases/theme-pack/greenwood.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const myThemePack = require('./my-theme-pack');
const packageName = require('./package.json').name;
const path = require('path');
const { ResourceInterface } = require('@greenwood/cli/src/lib/resource-interface');

class MyThemePackDevelopmentResource extends ResourceInterface {
constructor(compilation, options) {
super(compilation, options);
this.extensions = ['*'];
}

async shouldResolve(url) {
// eslint-disable-next-line no-underscore-dangle
return Promise.resolve(process.env.__GWD_COMMAND__ === 'develop' && url.indexOf(`/node_modules/${packageName}/`) >= 0);
}

async resolve(url) {
return Promise.resolve(this.getBareUrlPath(url).replace(`/node_modules/${packageName}/dist/`, path.join(process.cwd(), '/src/')));
}
}

module.exports = {
plugins: [
...myThemePack({
__isDevelopment: true
}),
{
type: 'resource',
name: `${packageName}:resource`,
provider: (compilation, options) => new MyThemePackDevelopmentResource(compilation, options)
}
]
};
18 changes: 18 additions & 0 deletions packages/cli/test/cases/theme-pack/my-theme-pack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const packageJson = require('./package.json');
const path = require('path');

module.exports = (options = {}) => [{
type: 'context',
name: `${packageJson.name}:context`,
provider: (compilation) => {
const templateLocation = options.__isDevelopment // eslint-disable-line no-underscore-dangle
? path.join(compilation.context.userWorkspace, 'layouts')
: path.join(__dirname, 'dist/layouts');

return {
templates: [
templateLocation
]
};
}
}];
4 changes: 4 additions & 0 deletions packages/cli/test/cases/theme-pack/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "my-theme-pack",
"main": "my-theme-pack.js"
}
18 changes: 18 additions & 0 deletions packages/cli/test/cases/theme-pack/src/components/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const template = document.createElement('template');

template.innerHTML = `
<header>Welcome to my blog!</header>
`;

class HeaderComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}

async connectedCallback() {
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}

customElements.define('x-header', HeaderComponent);
16 changes: 16 additions & 0 deletions packages/cli/test/cases/theme-pack/src/layouts/blog-post.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<html>

<head>
<link rel="stylesheet" href="/node_modules/my-theme-pack/dist/styles/theme.css"></link>
<script type="module" src="/node_modules/my-theme-pack/dist/components/header.js"></script>
</head>

<body>
<x-header></x-header>

<h1>This is the blog post template called from the layouts directory.</h1>
<content-outlet></content-outlet>

</body>

</html>
7 changes: 7 additions & 0 deletions packages/cli/test/cases/theme-pack/src/pages/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
template: 'blog-post'
---

## Title of blog post

Lorum Ipsum, this is a test.
7 changes: 7 additions & 0 deletions packages/cli/test/cases/theme-pack/src/styles/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import './theme.css';

:root {
color: var(--color-text-primary);
font-family: var(--font-family);
background-color: var(--color-secondary);
}
5 changes: 5 additions & 0 deletions packages/cli/test/cases/theme-pack/src/styles/theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
:root {
--color-primary: #135;
--color-secondary: #74b238;
--font-family: 'Optima', sans-serif;
}
153 changes: 153 additions & 0 deletions packages/cli/test/cases/theme-pack/theme-pack.build.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/*
* Use Case
* A theme pack _author_ creating a theme pack and using Greenwood for development and testing
* following the guide published on the Greenwood website. (https://www.greenwoodjs.io/guides/theme-packs/)
*
* User Result
* Should correctly validate the develop and build / serve commands work correctly using tge expected templates
* being resolved correctly per the known work around needs as documented in the FAQ and tracked in a discussion.
* https://github.com/ProjectEvergreen/greenwood/discussions/682
*
* User Command
* greenwood develop
*
* User Config
* Mock Theme Pack Plugin (from fixtures)
*
* Plugin Author Workspace
* src/
* components/
* header.js
* layouts/
* blog-post.html
* pages/
* index.md
* styles/
* theme.css
*/
const expect = require('chai').expect;
const glob = require('glob-promise');
const { JSDOM } = require('jsdom');
const path = require('path');
const { getSetupFiles, getDependencyFiles, getOutputTeardownFiles } = require('../../../../../test/utils');
const Runner = require('gallinago').Runner;
const runSmokeTest = require('../../../../../test/smoke-test');

describe('Build Greenwood With: ', function() {
const LABEL = 'Developement environment for a heme Pack';
const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js');
const outputPath = __dirname;
let runner;

before(function() {
this.context = {
publicDir: path.join(outputPath, 'public')
};
runner = new Runner(true);
});

describe(LABEL, function() {

before(async function() {
const themePacktemplates = await getDependencyFiles(
`${__dirname}/src/layouts/*.html`,
`${outputPath}/node_modules/my-theme-pack/dist/layouts`
);
const themePackStyles = await getDependencyFiles(
`${__dirname}/src/styles/*.css`,
`${outputPath}/node_modules/my-theme-pack/dist/styles`
);
const themePackComponents = await getDependencyFiles(
`${__dirname}/src/components/*.js`,
`${outputPath}/node_modules/my-theme-pack/dist/components`
);

await runner.setup(outputPath, [
...getSetupFiles(outputPath),
...themePacktemplates,
...themePackStyles,
...themePackComponents
]);
await runner.runCommand(cliPath, 'build');
});

runSmokeTest(['public', 'index'], LABEL);

describe('Custom Default App and Page Templates', function() {
let dom;

before(async function() {
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
});

it('should have expected text from layout/blog-post.html', function() {
const pageTemplateHeading = dom.window.document.querySelectorAll('body h1')[0];

expect(pageTemplateHeading.textContent).to.be.equal('This is the blog post template called from the layouts directory.');
});

it('should have expected text from (test) user workspace pages/index.md', function() {
const heading = dom.window.document.querySelectorAll('body h2')[0];
const paragraph = dom.window.document.querySelectorAll('body p')[0];

expect(heading.textContent).to.be.equal('Title of blog post');
expect(paragraph.textContent).to.be.equal('Lorum Ipsum, this is a test.');
});
});

describe('Custom Theme Pack theme.css in app template', function() {
let dom;

before(async function() {
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
});

it('should output a single CSS file for custom theme pack styles/theme.css', async function() {
expect(await glob.promise(path.join(this.context.publicDir, '**/theme.*.css'))).to.have.lengthOf(1);
});

it('should have expected link tag in the head', function() {
const linkTag = Array.from(dom.window.document.querySelectorAll('head link'))
.filter((linkTag) => {
return linkTag.getAttribute('rel') === 'stylesheet'
&& linkTag.getAttribute('href').indexOf('/theme.') === 0;
});

expect(linkTag.length).to.equal(1);
});
});

describe('Custom Theme Pack heading.js in custom title page template', function() {
let dom;

before(async function() {
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, 'index.html'));
});

it('should output a single JS file for custom theme pack components/heading.js', async function() {
expect(await glob.promise(path.join(this.context.publicDir, '**/header.*.js'))).to.have.lengthOf(1);
});

it('should have expected link tag in the head', function() {
const scriptTag = Array.from(dom.window.document.querySelectorAll('head script'))
.filter((linkTag) => {
return linkTag.getAttribute('src').indexOf('/header.') === 0;
});

expect(scriptTag.length).to.equal(1);
});

it('should have expected heading component content', function() {
const header = dom.window.document.querySelector('body x-header header');

expect(header.textContent).to.equal('Welcome to my blog!');
});
});
});

after(function() {
runner.teardown(getOutputTeardownFiles(outputPath));
});

});

Loading

0 comments on commit a375ce3

Please sign in to comment.