Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow themes to copy assets to the output directory #387

Merged
merged 1 commit into from Apr 5, 2018
Merged

allow themes to copy assets to the output directory #387

merged 1 commit into from Apr 5, 2018

Conversation

kmohrf
Copy link
Contributor

@kmohrf kmohrf commented Mar 29, 2018

Hey,

this PR adds support for themes to add their own assets to the output directory of the html file. The primary reason for adding this feature is that I need a theme that bundles its assets in order to provide api documentation on local networks that don’t have access to the internet.

Themes may define a copyAssets method as part of their config. If they do the function will receive the target directory of the output file as their only argument and should return a Promise to indicate completion. I thought about adding some logic to handle things like strings as arguments for the copyAssets config option, but that is likely to fall short in terms of what people might want to do with this. The theme should know best how to handle its assets.

I wasn’t quite sure where to add the documentation for this. If there is a theme guide somewhere I'll be happy to submit a pull request.

Thank you for your time and your work you put into this project!

@kevinrenskers kevinrenskers changed the base branch from master to develop March 29, 2018 19:13
bin/raml2html Outdated
@@ -58,17 +57,7 @@ if (argv.template) {

// Start the rendering process
raml2html
.render(input, config, argv)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your PR! Looks like a very nice change, and a nice way to handle themes that require the output path to be set (rather then outputting to the console).

One comment I have: would it be possible to keep the .render(input, config, argv) line here, followed by the new handleOutput logic? I feel that the render call should not be within handleOutput. I'd also rename handleOutput to simply write. So we have render followed by write.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that I look at it some more, I am wondering: how does a theme set this config.copyAssets flag? Combined with my other question about that export, I think there might be another way to go to implement this behaviour: do something similar as processRamlObj and postProcessHtml, where themes can override those functions but we supply a default one. Then a theme can just do whatever it wants, throw an error when needed, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i’ve started with the handleOutput call because i wanted it to throw early if the theme wants to store assets but the user didn’t choose to provide the --output option. otherwise the html would have been rendered for nothing. however i could move this check to the bin script.

concerning your second comment: I’m a bit confused. In index.js#L128 the theme config is loaded. In the theme I’m working on I’ve defined the main property in the package.json file to my theme config and I’m exporting an object there that defines processRamlObj and (with this PR) copyAssets. Isn’t that how it’s supposed to be working?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you are correct. I always see the theme as an object that has a bunch of methods on it, but you're right that it can of course just contain properties. However, this implementation is still maybe not flexible enough. What if some other theme wants to write to an S3 bucket for example? Now raml2html "owns" the new handleOutput, we have to maintain it, and if other themes have other wishes, we have to keep adding new options to it. By letting theme supply the entire write function itself instead of only supplying 2 config parameters, the theme has 100% flexibility and raml2html doesn't need to own that complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah… now I get it. I’ll update the PR :). is write the name you’d prefer for this config option?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's go with writeOutput

index.js Outdated
@@ -153,6 +181,7 @@ function getConfigForTheme(theme, programArguments) {
module.exports = {
getConfigForTemplate,
getConfigForTheme,
handleOutput,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this getting exported? It doesn't seem like this needs to be public API, as the behaviour is controlled by a config flag? It's not like a theme needs to override this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i didn’t think of raml2html as an api but more of an application. so i never thought that it would become part of an api :). uhm. the reason i moved it to the index.js file is that i didn’t want to bloat up the bin script, as I usually try to isolate cli code from the code that actually does things.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right but now we have themes that have to set options (somehow) that control the output functionality, contained within the main script (instead of the cli script). I think my suggestion to have themes supply their own writeOutput function, ala the way postProcessHtml works basically, is probably the best way to go. It leaves all logic in one script, all called in the same way, and doesn't need extra config options since the themes just supply their own write function.

Themes may override the default output implementation by definining the
`writeOutput` function as part of their config. `writeOutput` receives the
rendered html, the config and the cli options as arguments and may
implement some form of asset generation or custom write targets.
@kmohrf
Copy link
Contributor Author

kmohrf commented Apr 4, 2018

sorry for the delay. here are the requested changes :)

@kevinrenskers kevinrenskers merged commit 10b1608 into raml2html:develop Apr 5, 2018
@kevinrenskers
Copy link
Member

It's merged to develop but not released quite yet. I'd love for someone to confirm that all existing use cases work as expected :)

@kevinrenskers
Copy link
Member

@kmohrf I've created a ticket to write documentation for theme authors (https://github.com/raml2html/raml2html/issues/388). As you've noticed yourself, it's something that's currently lacking. If you feel like taking a stab at it, feel free to make a start! :)

@kmohrf
Copy link
Contributor Author

kmohrf commented Apr 6, 2018

@kevinrenskers I’m about to publish a theme myself next week. If I find some time for documentation afterwards I’ll gladly contribute to the docs :)

@kmohrf
Copy link
Contributor Author

kmohrf commented Apr 10, 2018

just fyi @kevinrenskers

I just published raml2html-werk-theme that uses this feature. There is still a glitch (unrelated to this PR) that might be a sidenote for #388, because right now the theme only works, if I use a filesystem reference for the --theme option. Using it with --theme raml2html-werk-theme seems to ignore my custom theme config. I’ve hadn’t had the time to investigate this.

@kevinrenskers
Copy link
Member

For --theme raml2html-werk-theme to work, it needs to be installed as a node package somewhere in your path (like, globally). Might that be the issue?

@kevinrenskers
Copy link
Member

I've published 7.1.0 btw.

@y0n3t4n1
Copy link

Note that this change re-introduced #259 when the output is stdout:
this part should really have been

process.stdout.write(result, resolve);

rather than

process.stdout.write(result);
resolve();

@kevinrenskers
Copy link
Member

You are completely correct, thanks for pointing it out. Fixed and published.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants