Skip to content

Conversation

@ang-zeyu
Copy link
Contributor

@ang-zeyu ang-zeyu commented Dec 15, 2019

What is the purpose of this pull request? (put "X" next to an item, remove the rest)

• [x] Documentation update
• [x] Enhancement to an existing feature

Resolves #913

What is the rationale for this request?
To allow plugins to define their own source file types and corresponding
source files that will be watched and updated by the live preview appropriately.

What changes did you make? (Give an overview)

  • Plugins can a new attribute in its exports: getSources
    • getSources: Allows plugins to return an array of source file paths to watch
  • Similar to Page.prototype.preRender, Page.prototype.getSources runs getSources all plugins just before
    preRender.
  • Updated relavant test files

Provide some example code that this change will affect:

(Plant uml plugin file)
module.exports = {
  ...,
  getSources: (content) => {
    // Add all src attributes in <puml> tags to watch list
    const $ = cheerio.load(content, { xmlMode: true });

    return $('puml').map((i, tag) => tag.attribs.src).get();
  },

Is there anything you'd like reviewers to focus on?
Whether a callback style solution would be better ( a 5th parameter to preRender / postRender that contains callbacks plugins can use ), since in the long run one may find plugins requiring more and more functionality.

Testing instructions:
I added a <puml> tag, and an <include> tag ( including testPlantUML.md )
to the test site. Changing any of the source files ( e.g. activity.puml ) should
cause the affected pages to reload when serving the page.

Proposed commit message: (wrap lines at 72 characters)
Allow live reloading for plugin defined sources

This allows plugins to define a custom list of source files and file
types for the page to be watched, allowing live reload to rebuild
the affected page.

src/Page.js Outdated
if (plugin.getSources) {
const sources = _.castArray(
plugin.getSources(content, this.pluginsContext[pluginName] || {},
this.frontMatter, this.getPluginConfig()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Why _.castArray? getSources should return an array.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So that a single source file could be returned as well,
should I enforce returning an array instead?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, since getSources is plural.

@ang-zeyu ang-zeyu force-pushed the watch-puml branch 2 times, most recently from 5dd6389 to 720648b Compare December 15, 2019 14:47
@ang-zeyu
Copy link
Contributor Author

Updated getSources to require returning array instead as per method naming

@yamgent yamgent self-requested a review December 16, 2019 03:50
@ang-zeyu ang-zeyu changed the title [WIP] Allow live reloading for plugin defined sources Allow live reloading for plugin defined sources Dec 16, 2019
Copy link
Member

@yamgent yamgent left a comment

Choose a reason for hiding this comment

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

Seems good implementation-wise, comments are mostly about wordings:

const $ = cheerio.load(content, { xmlMode: true });

return $('puml').map((i, tag) => tag.attribs.src).get();
},
Copy link
Member

Choose a reason for hiding this comment

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

The indentation of the method body is off. Only the comment line was in the correct indentation

During the `preRender` and `postRender` stages however, plugins may do custom processing using some other
source file types, as parsed from the raw Markdown, typically requiring rebuilding the site.

Hence, to add custom source files to watch, MarkBind allows defining an additional method in the plugin.
Copy link
Member

Choose a reason for hiding this comment

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

Hence, to add custom source files to watch, MarkBind allows defining an additional method in the plugin. implement the ``getSources`` method:

Prefer being more direct in documentations so that it is easier for the reader to process.


Hence, to add custom source files to watch, MarkBind allows defining an additional method in the plugin.
- `getSources(content, pluginContext, frontMatter, config)`: Called before the `preRender` function to retrieve an array of source file paths to watch.
- `content`: The raw Markdown of any Markdown file (`.md`, `.mbd`, etc.).
Copy link
Member

Choose a reason for hiding this comment

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

any -> the current? The use of "any" makes it seems like this call is not tied to any pages.

source file types, as parsed from the raw Markdown, typically requiring rebuilding the site.

Hence, to add custom source files to watch, MarkBind allows defining an additional method in the plugin.
- `getSources(content, pluginContext, frontMatter, config)`: Called before the `preRender` function to retrieve an array of source file paths to watch.
Copy link
Member

Choose a reason for hiding this comment

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

Returns an array of source file paths to watch. Called before a Markdown file'spreRender function is called.

src/Page.js Outdated
};

/**
* Collect page sources provided by plugins
Copy link
Member

Choose a reason for hiding this comment

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

Seems a bit wrong to say "page sources", since puml files are not really pages? Maybe "file sources"?

@ang-zeyu
Copy link
Contributor Author

Hi, thanks for looking through it! I've updated the relavant lines.

On another note, I noticed that usingPlugins.md does not have documentation for the fourth parameter, config, even though it is used in the preRender and postRender functions. I've correspondingly also omitted it from getSources for now.

Was this an intentional decision to hide some of the implementation details? If not, I could update it as well.

@yamgent
Copy link
Member

yamgent commented Dec 18, 2019

Was this an intentional decision to hide some of the implementation details? If not, I could update it as well.

It was probably an oversight. Feel free to add it in.

@ang-zeyu
Copy link
Contributor Author

Updated, will squash if its fine!

@acjh
Copy link
Contributor

acjh commented Dec 18, 2019

I noticed that usingPlugins.md does not have documentation for the fourth parameter, config, even though it is used in the preRender and postRender functions. I've correspondingly also omitted it from getSources for now.

Was this an intentional decision to hide some of the implementation details? If not, I could update it as well.

It was probably an oversight. Feel free to add it in.

Actually, it was intentionally undocumented by @jamos-tay as of #714 (comment):

I needed access to Page.headingIndexingLevel, so I added a 4th parameter, page which is the Page object itself... Other plugins might need access to page config so this could be helpful

I'm thinking we can use this for internal plugins, but don't document it in user docs, since we don't want to expose authors to the implementation

@ang-zeyu
Copy link
Contributor Author

Actually, it was intentionally undocumented by @jamos-tay as of [#714 (comment)]

Thanks for the heads up!

Since @jamos-tay ended up going with the approach @marvinchin suggested, there isn't too much to document though. Regarding the original concern for the change ( passing the entire Page being dangerous ), I could include a warning in the docs about includedFiles since it is used in Site.proto.updateSiteData(). Still, its a subsection to add into the docs which means more details for the user to read. Other properties aside though, rootPath, sourcePath and resultPath seem to be quite useful for plugins.

What's the take on this? 😮

@acjh
Copy link
Contributor

acjh commented Dec 19, 2019

Since @jamos-tay ended up going with the approach @marvinchin suggested, there isn't too much to document though. ... Other properties aside though, rootPath, sourcePath and resultPath seem to be quite useful for plugins.

The concern isn't that it is tedious to document. Rather, ideally, plugins should purely process content rather than use variables from and depend on the (filesystem-aware) implementation of Markbind CLI.

@ang-zeyu
Copy link
Contributor Author

Noted on the intended usage of plugins. Thanks!

Reverted the 'documentation updates' and squashed

@yamgent yamgent merged commit 211cd6e into MarkBind:master Dec 23, 2019
@yamgent yamgent added this to the v2.7.1 milestone Dec 23, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support live-preview for .puml files

3 participants