Refactor sub-menu (#492)

This commit is contained in:
Mimi 2022-03-18 16:42:42 +08:00 committed by GitHub
parent 72c28e5e87
commit e16688573b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 109 additions and 120 deletions

View File

@ -1,13 +1,10 @@
{% macro render(name, itemName, value) %}
{% macro render(node) %}
{%- set itemURL = value.split('||')[0] | trim %}
{%- if not itemURL.startsWith('http') %}
{%- set itemURL = itemURL | replace('//', '/') %}
{%- endif %}
<li class="menu-item menu-item-{{ itemName | replace(' ', '-') }}">
{%- set itemURL = node.path %}
<li class="menu-item menu-item-{{ node.name | lower | replace(' ', '-') }}">
{%- set menuIcon = '<i class="' + value.split('||')[1] | trim + ' fa-fw"></i>' if theme.menu_settings.icons and value.split('||')[1] else '' %}
{%- set menuText = __('menu.' + name) | replace('menu.', '') %}
{%- set menuIcon = '<i class="' + node.icon + ' fa-fw"></i>' if theme.menu_settings.icons and node.icon else '' %}
{%- set menuText = __('menu.' + node.name) | replace('menu.', '') %}
{%- set menuBadge = '' %}
{%- if theme.menu_settings.badges %}
@ -18,7 +15,7 @@
}
%}
{%- for menu, count in badges %}
{%- if name == menu %}
{%- if node.name == menu %}
{%- set menuBadge = '<span class="badge">' + count + '</span>' %}
{%- endif %}
{%- endfor %}

View File

@ -3,23 +3,8 @@
{%- if theme.menu or theme.algolia_search.enable or theme.local_search.enable %}
<nav class="site-nav">
<ul class="main-menu menu">
{%- for name, path in theme.menu %}
{%- set respath = path %}
{%- if path == '[object Object]' %}
{# Main Menu (default menu item for Submenu) #}
{%- for subname, subpath in path %}
{%- set itemName = subname | lower %}
{%- set respath = subpath %}
{%- if itemName == 'default' %}
{%- set itemName = name | lower %}
{{ menu_item.render(name, itemName, respath) }}
{%- endif %}
{%- endfor %}
{% else %}
{# Main Menu (standard menu items) #}
{%- set itemName = name | lower %}
{{- menu_item.render(name, itemName, respath) | trim }}
{%- endif %}
{%- for node in theme.main_menu %}
{{- menu_item.render(node) | trim }}
{%- endfor %}
{%- if theme.algolia_search.enable or theme.local_search.enable %}

View File

@ -1,92 +1,12 @@
{% import '_partials/header/menu-item.njk' as menu_item with context %}
{%- if theme.menu and is_page() %}
{# Submenu & Submenu-2 #}
{%- for name, value in theme.menu %}
{%- set respath = value %}
{%- if value == '[object Object]' %}
{# If current URL is value of parent submenu 'default' path #}
{%- set currentParentUrl = page.path.split('/')[0] | trim %}
{%- if currentParentUrl == value.default.split('||')[0] | trim | replace('/', '') %}
{# Submenu items #}
<ul class="sub-menu menu">
{%- for subname, subvalue in value %}
{# For main submenu items #}
{%- if subvalue != '[object Object]' %}
{%- set itemName = subname | lower %}
{%- if itemName == 'default' %}
{%- set parentValue = subvalue.split('||')[0] | trim %}
{% else %}
{%- set respath = subvalue if subvalue.startsWith('http') else (parentValue + subvalue) %}
{{ menu_item.render(subname, itemName, respath) }}
{%- endif %}
{% else %}
{# For 'default' submenu item in main submenu #}
{%- set itemName = subname | lower %}
{%- for subname2, subvalue2 in subvalue %}
{%- if subname2 == 'default' %}
{%- set respath = parentValue + subvalue2 %}
{{ menu_item.render(subname, itemName, respath) }}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endfor %}
</ul>
{# End Submenu items #}
{# Submenu-2 #}
{%- for name, value in theme.menu %}
{%- set respath = value %}
{%- if value == '[object Object]' %}
{%- for subname, subvalue in value %}
{%- set itemName = subname | lower %}
{%- if itemName == 'default' %}
{%- set parentValue = subvalue.split('||')[0] | trim %}
{%- endif %}
{%- if subvalue == '[object Object]' %}
{# If current URL is value of parent submenu 'default' path #}
{%- set paths = page.path.split('/') %}
{%- if paths.length > 2 %}
{%- if paths[1] == subvalue.default.split('||')[0] | trim | replace('/', '') %}
{# Submenu-2 items #}
<ul class="sub-menu menu">
{%- for subname2, subvalue2 in subvalue %}
{%- set respath2 = subvalue %}
{%- set itemName = subname2 | lower %}
{%- if itemName == 'default' %}
{%- set parentSubValue = subvalue2.split('||')[0] | trim %}
{% else %}
{%- if subvalue2.startsWith('http') %}
{%- set respath2 = subvalue2 %}
{% else %}
{%- set respath2 = parentValue + parentSubValue + subvalue2 %}
{%- endif %}
{{ menu_item.render(subname2, itemName, respath2) }}
{%- endif %}
{%- endfor %}
</ul>
{# End Submenu-2 items #}
{%- endif %}
{%- endif %}
{# End URL & path comparing #}
{%- endif %}
{%- endfor %}
{%- endif %}
{%- endfor %}
{# End Submenu-2 #}
{%- endif %}
{# End URL & path comparing #}
{%- endif %}
{%- set menus = next_menu(page.path) %}
{%- for menu in menus %}
<ul class="sub-menu menu">
{%- for node in menu %}
{{ menu_item.render(node) }}
{%- endfor %}
</ul>
{%- endfor %}
{# End Submenu & Submenu-2 #}
{%- endif %}

View File

@ -1,18 +1,27 @@
{%- set paths = page.path.split('/') %}
{%- set count = paths.length %}
{%- if count > 2 %}
{%- set link = '' %}
{%- set link = '/' %}
<ul class="breadcrumb">
{%- for path in paths %}
{%- if path != 'index.html' %}
{%- if loop.index == count and path.endsWith('.html') %}
{%- set link = link + path %}
{%- else %}
{%- set link = link + path + '/' %}
{%- endif %}
{%- if theme.menu_map.has(link) %}
{%- set name = __('menu.' + theme.menu_map.get(link).name) | replace('menu.', '') %}
{%- else %}
{%- set name = path %}
{%- endif %}
{%- if loop.index == count - 1 and paths[loop.index] == 'index.html' %}
<li>{{ path | upper }}</li>
{% else %}
{%- set link = '/' + path if link == '' else link + '/' + path %}
<li>{{ name | upper }}</li>
{%- else %}
{%- if path.endsWith('.html') %}
<li>{{ path | replace(r/\.html$/, '') | upper }}</li>
{% else %}
<li><a href="{{ url_for(link) }}/">{{ path | upper }}</a></li>
<li>{{ name | replace(r/\.html$/, '') | upper }}</li>
{%- else %}
<li><a href="{{ url_for(link) }}">{{ name | upper }}</a></li>
{%- endif %}
{%- endif %}
{%- endif %}

View File

@ -11,6 +11,8 @@ hexo.extend.filter.register('before_generate', () => {
require('./lib/injects')(hexo);
// Highlight
require('./lib/highlight')(hexo);
// Menu and sub menu
require('./lib/navigation')(hexo);
}, 0);
hexo.on('ready', () => {

View File

@ -0,0 +1,57 @@
'use strict';
const { join } = require('path').posix;
class TreeNode {
constructor(parent, path, name, icon) {
if (parent && !path.startsWith('http')) {
path = join(parent.path, path);
}
this.parent = parent;
this.children = [];
this.path = path;
this.name = name;
this.icon = icon;
}
append(child) {
this.children.push(child);
}
}
module.exports = hexo => {
const menu_map = new Map();
const main_menu = [];
hexo.theme.config.menu_map = menu_map;
hexo.theme.config.main_menu = main_menu;
function parse(menu, parent) {
if (!menu) return;
Object.entries(menu).forEach(([name, value]) => {
if (name.toLowerCase() === 'default') return;
let node;
if (typeof value === 'string') {
const [path, icon] = value.split('||').map(v => v.trim());
node = new TreeNode(parent, path, name, icon);
} else if (typeof value === 'object') {
if (typeof value.default !== 'string') {
hexo.log.warn('Missing default entry for menu item:', name);
return;
}
const [path, icon] = value.default.split('||').map(v => v.trim());
node = new TreeNode(parent, path, name, icon);
parse(value, node);
}
if (node) {
menu_map.set(node.path, node);
if (parent) {
parent.append(node);
} else {
main_menu.push(node);
}
}
});
}
parse(hexo.theme.config.menu);
};

View File

@ -0,0 +1,19 @@
/* global hexo */
'use strict';
hexo.extend.helper.register('next_menu', function(path) {
path = ('/' + path).replace(/index\.html$/, '');
const { menu_map } = this.theme;
if (!menu_map.has(path)) return;
let node = menu_map.get(path);
const menus = [];
if (node.children.length) {
menus.unshift(node.children);
}
while (node.parent) {
menus.unshift(node.parent.children);
node = node.parent;
}
return menus;
});