vuejs / vuepress

📝 Minimalistic Vue-powered static site generator
https://vuepress.vuejs.org
MIT License
22.58k stars 4.76k forks source link

feat wanted: Allow to modify themeConfig in theme #1938

Closed Mister-Hope closed 5 years ago

Mister-Hope commented 5 years ago

Can a theme modify themeConfig ?

More certain question is how can a theme pass a modified themeConfig to the parent theme which it is extending?

Reason

If a theme extends from another theme, it may want to pass some configuarion which the parent theme asks, but now I don't think there is a way to do that.

If I can pass some options to the parent theme to let a feature work well, I dont think overwriting this feature part in the extending theme and modify it to let it has a another default value is necessary.

Detail

I am extending theme-default now, but I want to add some config to the parent theme(theme-default) by injecting some property to the themeConfig. So that my theme users won't need to config them.

I read through the document, and find out vuepress only allow me to extend the $page option.

And when I tried to modify it in my enhanceApp.js:

$site.themeConfig = Object.assign(defaultConfig, $site.themeConfig);

Vuepress told me it's readonly.

So how can I do?

More

A strict situation here is:

In this situation, Theme A needs to pass a modify themeConfig to themeB, to deny user's config on certain fields of themeConfig,

Now, Theme A can only do that by overwriting all the feature 2 files in Theme B and modify them, and that is bad for the purpose of extend.

I really hope this part can be approved

Mister-Hope commented 5 years ago

Hacked it by:

const assign = (originObject, assignObject) => {
  Object.keys(originObject).forEach(property => {
    if (assignObject[property] === undefined)
      assignObject[property] = originObject[property];
    else if (typeof assignObject[property] === 'object' && !Array.isArray(assignObject))
      assign(originObject[property], assignObject[property]);
  });
};

module.exports = assign;

And


const assign = require('./lib/assign');

export default ({
  Vue, 
  options,
  router,
  siteData
}) => {
  const themeConfig = siteData.themeConfig;

  const themeConfigDefault = {
    ...
  };

  assign(themeConfigDefault, themeConfig);
};