diff --git a/_config.yml b/_config.yml deleted file mode 100644 index cb2182d4b..000000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -# 请到 source/_config.yml 编辑主题配置文件 \ No newline at end of file diff --git a/include/README.md b/include/README.md new file mode 100644 index 000000000..870166c73 --- /dev/null +++ b/include/README.md @@ -0,0 +1 @@ +Refer from: \ No newline at end of file diff --git a/include/config.js b/include/config.js new file mode 100644 index 000000000..a93ef9715 --- /dev/null +++ b/include/config.js @@ -0,0 +1,102 @@ +/* eslint no-process-exit: "off" */ +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +const crypto = require('crypto'); +const logger = require('hexo-log')(); +const yaml = require('hexo-component-inferno/lib/util/yaml'); +// const { Migrator } = require('hexo-component-inferno/lib/core/migrate'); +// const { SchemaLoader } = require('hexo-component-inferno/lib/core/schema'); +const { yellow } = require('./util/console'); + +function loadThemeConfig(hexo, cfgPaths) { + const configs = cfgPaths.map(cfgPath => fs.readFileSync(cfgPath)) + .map(cfgPath => yaml.parse(cfgPath)); + return Object.assign({}, ...configs, hexo.config.theme_config); +} + +function generateThemeConfigFile(schema, cfgPath) { + const defaultValue = schema.getDefaultValue(); + fs.writeFileSync(cfgPath, defaultValue.toYaml()); +} + +function hashConfigFile(cfgPath) { + const content = fs.readFileSync(cfgPath); + return crypto.createHash('md5').update(content).digest('hex'); +} + +function checkConfig(hexo) { + if (!process.argv.includes('--nexmoe-dont-check-config')) { + logger.info('[Nexmoe] Checking theme configurations'); + + const themeSiteCfg = path.join(hexo.base_dir, '_config.nexmoe.yml'); + const themeDirCfg = path.join(hexo.theme_dir, '_config.yml'); + const themeCfgPaths = [themeDirCfg, themeSiteCfg].filter(cfgPath => fs.existsSync(cfgPath)); + const themeSiteCfgExample = themeSiteCfg + '.example'; + + // const schemaDir = path.join(hexo.theme_dir, 'include/schema/'); + // const loader = SchemaLoader.load(require(path.join(schemaDir, 'config.json')), schemaDir); + // const schema = loader.getSchema('/config.json'); + + if (!process.argv.includes('--nexmoe-dont-generate-config')) { + if (!themeCfgPaths.length) { + logger.warn('None of the following configuration files is found:'); + logger.warn(`- ${yellow(themeSiteCfg)}`); + logger.warn(`- ${yellow(themeDirCfg)}`); + logger.info('Generating theme configuration file...'); + // generateThemeConfigFile(schema, themeSiteCfg); + fs.writeFileSync(themeSiteCfg, fs.readFileSync(path.join(hexo.theme_dir, 'source/_config.yml'))) + themeCfgPaths.push(themeSiteCfg); + logger.info(`${yellow(themeSiteCfg)} created successfully.`); + logger.info('To skip configuration generation, use "--nexmoe-dont-generate-config".'); + } + } + + // let cfg = loadThemeConfig(hexo, themeCfgPaths); + + // if (!process.argv.includes('--nexmoe-dont-upgrade-config')) { + // const migrator = new Migrator(require(path.join(hexo.theme_dir, 'include/migration/head'))); + // if (cfg.version && migrator.isOudated(cfg.version)) { + // logger.warn(`Your theme configuration is outdated (${cfg.version} < ${migrator.getLatestVersion()}).`); + // logger.info('To skip the configuration upgrade, use "--nexmoe-dont-upgrade-config".'); + + // logger.info('Backing up theme configuration files...'); + // for (const cfgPath of themeCfgPaths) { + // const backupPath = cfgPath + '.' + hashConfigFile(cfgPath); + // const relCfgPath = path.relative(hexo.base_dir, cfgPath); + // const relBackupPath = path.relative(hexo.base_dir, backupPath); + // fs.renameSync(cfgPath, backupPath); + // logger.info(`${yellow(relCfgPath)} => ${yellow(relBackupPath)}`); + // } + + // logger.info('Upgrading theme configurations...'); + // cfg = migrator.migrate(cfg); + // fs.writeFileSync(themeSiteCfg, yaml.stringify(cfg)); + // logger.info(`Theme configurations are written to ${yellow(themeSiteCfg)}.`); + + // generateThemeConfigFile(schema, themeSiteCfgExample); + // logger.info(`Example configurations is at ${yellow(themeSiteCfgExample)}.`); + // } + // } + + // const validation = schema.validate(cfg); + // if (validation !== true) { + // logger.warn('Theme configurations failed one or more checks.'); + // logger.warn('nexmoe may still run, but you will encounter unexcepted results.'); + // logger.warn('Here is some information for you to correct the configuration file.'); + // logger.warn(util.inspect(validation)); + // } + + } +} + +module.exports = hexo => { + try { + checkConfig(hexo); + } catch (e) { + logger.error(e); + logger.error('Theme configuration checking failed.'); + logger.info('You may use \'--nexmoe-dont-check-config\' to skip configuration checking.'); + process.exit(-1); + } +}; diff --git a/include/dependency.js b/include/dependency.js new file mode 100644 index 000000000..38bd23453 --- /dev/null +++ b/include/dependency.js @@ -0,0 +1,34 @@ +/* eslint no-process-exit: "off" */ +const semver = require('semver'); +const logger = require('hexo-log')(); +const packageInfo = require('../package.json'); +const { yellow, red, green } = require('./util/console'); + +module.exports = hexo => { + function checkDependency(name, reqVer) { + try { + require.resolve(name); + const version = require(name + '/package.json').version; + if (!semver.satisfies(version, reqVer)) { + logger.error(`Package ${yellow(name)}'s version (${yellow(version)}) does not satisfy the required version (${red(reqVer)}).`); + return false; + } + return true; + } catch (e) { + logger.error(`Package ${yellow(name)} is not installed.`); + } + return false; + } + + logger.info('[Nexmoe] Checking package dependencies'); + const dependencies = Object.assign({}, packageInfo.dependencies); + const missingDeps = Object.keys(dependencies) + .filter(name => !checkDependency(name, dependencies[name])); + if (missingDeps && missingDeps.length) { + logger.error('Please install the missing dependencies your Hexo site root directory:'); + logger.error(green('npm install --save ' + missingDeps.map(name => `${name}@${dependencies[name]}`).join(' '))); + logger.error('or:'); + logger.error(green('yarn add ' + missingDeps.map(name => `${name}@${dependencies[name]}`).join(' '))); + process.exit(-1); + } +}; diff --git a/include/register.js b/include/register.js new file mode 100644 index 000000000..06b2e4c91 --- /dev/null +++ b/include/register.js @@ -0,0 +1,17 @@ +const logger = require('hexo-log')(); + +module.exports = hexo => { + logger.info('=== Registering Hexo extensions ==='); + require('hexo-component-inferno/lib/hexo/filter/locals')(hexo); + require('hexo-component-inferno/lib/hexo/generator/assets')(hexo); + require('hexo-component-inferno/lib/hexo/generator/insight')(hexo); + require('hexo-component-inferno/lib/hexo/generator/categories')(hexo); + require('hexo-component-inferno/lib/hexo/generator/category')(hexo); + require('hexo-component-inferno/lib/hexo/generator/manifest')(hexo); + require('hexo-component-inferno/lib/hexo/generator/tags')(hexo); + require('hexo-component-inferno/lib/hexo/helper/cdn')(hexo); + require('hexo-component-inferno/lib/hexo/helper/page')(hexo); + require('hexo-component-inferno/lib/hexo/tag/message')(hexo); + require('hexo-component-inferno/lib/hexo/tag/tabs')(hexo); + require('hexo-component-inferno/lib/core/view').init(hexo); +}; diff --git a/include/util/console.js b/include/util/console.js new file mode 100644 index 000000000..22e8dc48a --- /dev/null +++ b/include/util/console.js @@ -0,0 +1,15 @@ +let chalk; +try { + chalk = require('chalk'); // eslint-disable-line node/no-extraneous-require +} catch (e) { } + +module.exports = new Proxy({}, { + get(obj, prop) { + if (chalk) { + return chalk[prop]; + } + return function() { + return arguments.length === 1 ? arguments[0] : arguments; + }; + } +}); diff --git a/layout/_layout/nexmoe/body.jsx b/layout/_layout/nexmoe/body.jsx new file mode 100644 index 000000000..7ee6be4fa --- /dev/null +++ b/layout/_layout/nexmoe/body.jsx @@ -0,0 +1,33 @@ +const { Component } = require("inferno"); + +module.exports = class extends Component { + render() { + const { partial } = this.props; + const Content = require(`./content`); + const Footer = require(`./footer`); + + return ( + <> +
+
+ +
+
+ + + + ); + } +}; diff --git a/layout/_layout/nexmoe/content.jsx b/layout/_layout/nexmoe/content.jsx new file mode 100644 index 000000000..c29292d23 --- /dev/null +++ b/layout/_layout/nexmoe/content.jsx @@ -0,0 +1,14 @@ +const { Component } = require("inferno"); + +module.exports = class extends Component { + render() { + const { body } = this.props; + + return ( +
+ ); + } +}; diff --git a/layout/_layout/nexmoe/footer.jsx b/layout/_layout/nexmoe/footer.jsx new file mode 100644 index 000000000..d98c90d28 --- /dev/null +++ b/layout/_layout/nexmoe/footer.jsx @@ -0,0 +1,11 @@ +const { Component } = require("inferno"); + +module.exports = class extends Component { + render() { + const { body } = this.props; + + return ( + <> + ); + } +}; diff --git a/layout/_layout/single/header.ejs b/layout/_layout/nexmoe/header.ejs similarity index 87% rename from layout/_layout/single/header.ejs rename to layout/_layout/nexmoe/header.ejs index 1c2291593..d2d3c37fc 100644 --- a/layout/_layout/single/header.ejs +++ b/layout/_layout/nexmoe/header.ejs @@ -19,12 +19,12 @@ <% } %> - + + <% theme.widgets.forEach(function(widget){ %> + <% if(widget.enable){ %> + <%- partial('_widget/' + widget.name, {options: widget.options}) %> + <% }}) %> +