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

Support always-on plugins #714

Merged
merged 3 commits into from
Mar 28, 2019
Merged

Conversation

jamos-tay
Copy link
Contributor

@jamos-tay jamos-tay commented Feb 20, 2019

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

• [X] Enhancement to an existing feature

Fixes #702

What is the rationale for this request?

Certain plugins are unlikely to be excluded from every project
Support for plugins that are always on by default for every project

What changes did you make? (Give an overview)

Added support for default plugins:

  • Reside in the src/plugins/default folder
  • Folder is scanned and all plugins are included
  • Overriding allowed: If there's a plugin with the same name in the project plugin folder, Markbind will use that one. A warning will be displayed if the default plugin is being overridden so they don't accidentally override
  • Can be turned off by supplying off to pluginsContext:
{
  ...
  plugins : {
     // Do not need to specify plugin name in plugins
  },
  pluginsContext : {
    "anchors" : {
      "off": true
    }
  }
}

Also:

  • Convert anchors to default plugins to test it

* Adds anchor links to headers
*/
module.exports = {
postRender: (content, pluginContext, frontMatter, page) => {
Copy link
Contributor Author

@jamos-tay jamos-tay Feb 20, 2019

Choose a reason for hiding this comment

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

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

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm just thinking it might be dangerous to pass the entire Page object down to plugins, since that would allow the plugin to modify or invoke the variables and methods of Page which could be dangerous. 😅

What do you think about passing down a copy of the pageConfig object instead? Or maybe having a helper method getDefaultPluginsContext which constructs the context for default plugins and appends it to the other pluginsContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I think I'll do the page config method, I think getDefaultPluginsContext might end up growing pretty large if we have a lot of default plugins =P

Copy link
Member

Choose a reason for hiding this comment

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

This part doesn't seem to be addressed?

Copy link
Contributor

@marvinchin marvinchin left a comment

Choose a reason for hiding this comment

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

Just a couple of questions 🙂

src/Site.js Outdated
.filter(plugin => !_.includes(defaultPlugins, plugin))
.forEach(plugin => this.loadPlugin(plugin, false));
defaultPlugins
.filter(plugin => !this.siteConfig.pluginsContext
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wondering - would using lodash's get method make this more readable? 🙂

Possibly something like this:

_.get(this.siteConfig, ["pluginsContext", plugin, "off"], false)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

TIL, thanks

* Adds anchor links to headers
*/
module.exports = {
postRender: (content, pluginContext, frontMatter, page) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm just thinking it might be dangerous to pass the entire Page object down to plugins, since that would allow the plugin to modify or invoke the variables and methods of Page which could be dangerous. 😅

What do you think about passing down a copy of the pageConfig object instead? Or maybe having a helper method getDefaultPluginsContext which constructs the context for default plugins and appends it to the other pluginsContext?

@jamos-tay
Copy link
Contributor Author

Rebased and updated

@yamgent yamgent self-requested a review February 25, 2019 01:51
@yamgent yamgent added this to the v1.19.2 milestone Feb 25, 2019
docs/userGuide/usingPlugins.md Outdated Show resolved Hide resolved
* Adds anchor links to headers
*/
module.exports = {
postRender: (content, pluginContext, frontMatter, page) => {
Copy link
Member

Choose a reason for hiding this comment

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

This part doesn't seem to be addressed?

@yamgent yamgent removed this from the v1.19.2 milestone Feb 25, 2019
src/Site.js Outdated
* Finds plugins in the site's default plugin folder
*/
function findDefaultPlugins() {
const globPath = path.join(__dirname, BUILT_IN_PLUGIN_DEFAULT_FOLDER_NAME);
Copy link
Contributor

Choose a reason for hiding this comment

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

This assumes all built-in plugins are default plugins (i.e. turned on by default), which is not true.
For example, Algolia search plugin loads unnecessary files in the site if not used, so it should be turned off by default.

Also, this is known at MarkBind dev time. Shall we use a constant as a whitelist?

Copy link
Contributor Author

@jamos-tay jamos-tay Mar 1, 2019

Choose a reason for hiding this comment

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

Currently there's a separate folder for plugins that are always on (BUILT_IN_PLUGIN_FOLDER_NAME vs BUILT_IN_PLUGIN_DEFAULT_FOLDER_NAME)

src/
  plugins/
    default/
      always-on.js
      ... other default plugins
    must-be-turned-on.js
    ... other normal plugins

Plugins that should be off can be placed outside the default folder, where they are treated like normal plugins

I think this might be better than using a whitelist as that has to be hardcoded...

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah. BUILT_IN_PLUGIN_DEFAULT_FOLDER_NAMEBUILT_IN_DEFAULT_PLUGIN_FOLDER_NAME?

Copy link
Member

Choose a reason for hiding this comment

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

Ah. BUILT_IN_PLUGIN_DEFAULT_FOLDER_NAMEBUILT_IN_DEFAULT_PLUGIN_FOLDER_NAME?

Sounds better 👍.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure no problem

@jamos-tay
Copy link
Contributor Author

Updated and rebased

@jamos-tay
Copy link
Contributor Author

Updated, rebased

docs/userGuide/usingPlugins.md Outdated Show resolved Hide resolved
src/Site.js Outdated Show resolved Hide resolved
@jamos-tay
Copy link
Contributor Author

Updated

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.

I think you forgot to remove the prefix when obtaining the names of the default plugins, because the example in the documentation no longer works, and I have to do this instead:

  "pluginsContext": {
    "markbind-plugin-anchors": {
      "off": true
    }
  }

@jamos-tay
Copy link
Contributor Author

Sorry for the delay, rebased and updated

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.

@nicholaschuayunzhi has some additional comments for this PR, let me post my minor nit first:

src/Site.js Outdated Show resolved Hide resolved
Copy link
Contributor

@nicholaschuayunzhi nicholaschuayunzhi left a comment

Choose a reason for hiding this comment

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

Sorry for my late comments. Perhaps the tests could be done in separate PR?

src/Page.js Show resolved Hide resolved
@jamos-tay
Copy link
Contributor Author

Sorry for lateness, updated

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.

Apologies for the late reply.

src/Page.js Outdated Show resolved Hide resolved
@jamos-tay
Copy link
Contributor Author

Updated

@yamgent yamgent added this to the v1.22.1 milestone Mar 27, 2019
@yamgent
Copy link
Member

yamgent commented Mar 28, 2019

Travis is currently borked, don't really know why, the builds are all getting stuck. I will return to this PR and merge it when I have the next free time.

Meanwhile the proposed commit message:

Support always-on plugins (#714)

When authors want to use plugins for his website, he or she must
modify site.json to enable them manually. There are no plugins that
are enabled by default.

In the future, there may be built-in MarkBind plugins that should be
enabled by default. For example, we want to move the anchor
functionality into a plugin. However, as there are no default plugins,
MarkBind will have them disabled by default, even though anchors are
a common feature in websites and it would be troublesome for authors
to enable this manually.

Let's add always-on plugins, plugins that are always enabled by default
unless the author specify in site.json to disable them. As a
"proof-of-concept", let's also refactor the anchor logic to an
always-on plugin to demonstrate how always-on plugins can be utilized.

@yamgent yamgent changed the title Support always on plugins Support always-on plugins Mar 28, 2019
@yamgent yamgent merged commit a2f88a2 into MarkBind:master Mar 28, 2019
@ang-zeyu ang-zeyu mentioned this pull request Mar 23, 2020
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.

None yet

5 participants