mirror of
https://github.com/next-theme/hexo-theme-next.git
synced 2026-01-20 19:02:33 +00:00
Refactor sub-menu (#492)
This commit is contained in:
parent
72c28e5e87
commit
e16688573b
@ -1,13 +1,10 @@
|
|||||||
{% macro render(name, itemName, value) %}
|
{% macro render(node) %}
|
||||||
|
|
||||||
{%- set itemURL = value.split('||')[0] | trim %}
|
{%- set itemURL = node.path %}
|
||||||
{%- if not itemURL.startsWith('http') %}
|
<li class="menu-item menu-item-{{ node.name | lower | replace(' ', '-') }}">
|
||||||
{%- set itemURL = itemURL | replace('//', '/') %}
|
|
||||||
{%- endif %}
|
|
||||||
<li class="menu-item menu-item-{{ itemName | replace(' ', '-') }}">
|
|
||||||
|
|
||||||
{%- set menuIcon = '<i class="' + value.split('||')[1] | trim + ' fa-fw"></i>' if theme.menu_settings.icons and value.split('||')[1] else '' %}
|
{%- set menuIcon = '<i class="' + node.icon + ' fa-fw"></i>' if theme.menu_settings.icons and node.icon else '' %}
|
||||||
{%- set menuText = __('menu.' + name) | replace('menu.', '') %}
|
{%- set menuText = __('menu.' + node.name) | replace('menu.', '') %}
|
||||||
|
|
||||||
{%- set menuBadge = '' %}
|
{%- set menuBadge = '' %}
|
||||||
{%- if theme.menu_settings.badges %}
|
{%- if theme.menu_settings.badges %}
|
||||||
@ -18,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
%}
|
%}
|
||||||
{%- for menu, count in badges %}
|
{%- for menu, count in badges %}
|
||||||
{%- if name == menu %}
|
{%- if node.name == menu %}
|
||||||
{%- set menuBadge = '<span class="badge">' + count + '</span>' %}
|
{%- set menuBadge = '<span class="badge">' + count + '</span>' %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|||||||
@ -3,23 +3,8 @@
|
|||||||
{%- if theme.menu or theme.algolia_search.enable or theme.local_search.enable %}
|
{%- if theme.menu or theme.algolia_search.enable or theme.local_search.enable %}
|
||||||
<nav class="site-nav">
|
<nav class="site-nav">
|
||||||
<ul class="main-menu menu">
|
<ul class="main-menu menu">
|
||||||
{%- for name, path in theme.menu %}
|
{%- for node in theme.main_menu %}
|
||||||
{%- set respath = path %}
|
{{- menu_item.render(node) | trim }}
|
||||||
{%- 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 %}
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
{%- if theme.algolia_search.enable or theme.local_search.enable %}
|
{%- if theme.algolia_search.enable or theme.local_search.enable %}
|
||||||
|
|||||||
@ -1,92 +1,12 @@
|
|||||||
{% import '_partials/header/menu-item.njk' as menu_item with context %}
|
{% import '_partials/header/menu-item.njk' as menu_item with context %}
|
||||||
|
|
||||||
{%- if theme.menu and is_page() %}
|
{%- if theme.menu and is_page() %}
|
||||||
{# Submenu & Submenu-2 #}
|
{%- set menus = next_menu(page.path) %}
|
||||||
{%- for name, value in theme.menu %}
|
{%- for menu in menus %}
|
||||||
{%- 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">
|
<ul class="sub-menu menu">
|
||||||
{%- for subname, subvalue in value %}
|
{%- for node in menu %}
|
||||||
{# For main submenu items #}
|
{{ menu_item.render(node) }}
|
||||||
{%- 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 %}
|
{%- endfor %}
|
||||||
</ul>
|
</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 %}
|
{%- 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 %}
|
|
||||||
{%- endfor %}
|
|
||||||
{# End Submenu & Submenu-2 #}
|
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|||||||
@ -1,18 +1,27 @@
|
|||||||
{%- set paths = page.path.split('/') %}
|
{%- set paths = page.path.split('/') %}
|
||||||
{%- set count = paths.length %}
|
{%- set count = paths.length %}
|
||||||
{%- if count > 2 %}
|
{%- if count > 2 %}
|
||||||
{%- set link = '' %}
|
{%- set link = '/' %}
|
||||||
<ul class="breadcrumb">
|
<ul class="breadcrumb">
|
||||||
{%- for path in paths %}
|
{%- for path in paths %}
|
||||||
{%- if path != 'index.html' %}
|
{%- 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' %}
|
{%- if loop.index == count - 1 and paths[loop.index] == 'index.html' %}
|
||||||
<li>{{ path | upper }}</li>
|
<li>{{ name | upper }}</li>
|
||||||
{% else %}
|
{%- else %}
|
||||||
{%- set link = '/' + path if link == '' else link + '/' + path %}
|
|
||||||
{%- if path.endsWith('.html') %}
|
{%- if path.endsWith('.html') %}
|
||||||
<li>{{ path | replace(r/\.html$/, '') | upper }}</li>
|
<li>{{ name | replace(r/\.html$/, '') | upper }}</li>
|
||||||
{% else %}
|
{%- else %}
|
||||||
<li><a href="{{ url_for(link) }}/">{{ path | upper }}</a></li>
|
<li><a href="{{ url_for(link) }}">{{ name | upper }}</a></li>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|||||||
@ -11,6 +11,8 @@ hexo.extend.filter.register('before_generate', () => {
|
|||||||
require('./lib/injects')(hexo);
|
require('./lib/injects')(hexo);
|
||||||
// Highlight
|
// Highlight
|
||||||
require('./lib/highlight')(hexo);
|
require('./lib/highlight')(hexo);
|
||||||
|
// Menu and sub menu
|
||||||
|
require('./lib/navigation')(hexo);
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
hexo.on('ready', () => {
|
hexo.on('ready', () => {
|
||||||
|
|||||||
57
scripts/events/lib/navigation.js
Normal file
57
scripts/events/lib/navigation.js
Normal 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);
|
||||||
|
};
|
||||||
19
scripts/helpers/navigation.js
Normal file
19
scripts/helpers/navigation.js
Normal 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;
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user