В вашем коде слишком много ошибок, поэтому я предпочитаю привести полный пример с пояснениями.
Вот что нам нужно:
- Пользовательский тег для создания структуры HTML этого нескольких кодовых блоков.
- Файл CSS для стилизации блока кода и окраски кода.
- Скрипт JS для анимации блока кода (вкладки)
Пользовательский тег: m_codeblock
(на стороне сервера JS)
Нам нужно разрешить пользователю определять:
- имя или ссылка
- несколько кодовых блоков на этой вкладке, поэтому мы определили тег для разделения и перечисления каждой вкладки
Вот синтаксис:
{% m_codeblock [name] [link] %}
<!-- tab [lang] -->
source_code
<!-- endtab -->
{% endm_codeblock %}
и пример:
{% m_codeblock stack overflow https://example.fr %}
<!-- tab html -->
<html>
<body>
<h1>Hey dan</h1>
</body>
</html>
<!-- endtab -->
<!-- tab css -->
h1 {
color:red;
}
<!-- endtab -->
{% endm_codeblock %}
Установите эти зависимости в папку вашего блога (не в папку темы):
- беги
npm install jsdom --save
- беги
npm install jquery --save
а вот исходный код этого пользовательского тега, помещенного в themes/theme_name/scripts/m_codeblock.js
:
'use strict';
var util = require('hexo-util');
var highlight = util.highlight;
var stripIndent = require('strip-indent');
var rCaptionUrl = /(\S[\S\s]*)\s+(https?:\/\/)(\S+)/i;
var rCaption = /(\S[\S\s]*)/;
var rTab = /<!--\s*tab (\w*)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
// create a window with a document to use jQuery library
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
/**
* Multi code block
* @param args
* @param content
* @returns {string}
*/
function multiCodeBlock(args, content) {
var arg = args.join(' ');
// get blog config
var config = hexo.config.highlight || {};
if (!config.enable) {
return '<pre><code>' + content + '</code></pre>';
}
var html;
var matches = [];
var match;
var caption = '';
var codes = '';
// extract languages and source codes
while (match = rTab.exec(content)) {
matches.push(match[1]);
matches.push(match[2]);
}
// create tabs and tabs content
for (var i = 0; i < matches.length; i += 2) {
var lang = matches[i];
var code = matches[i + 1];
var $code;
// trim code
code = stripIndent(code).trim();
// add tab
// active the first tab
if (i == 0) {
caption += '<li class="tab active">' + lang + '</li>';
}
else {
caption += '<li class="tab">' + lang + '</li>';
}
// highlight code
code = highlight(code, {
lang: lang,
gutter: config.line_number,
tab: config.tab_replace,
autoDetect: config.auto_detect
});
// used to parse HTML code and ease DOM manipulation
// display the first code block
$code = $('<div>').append(code).find('>:first-child');
if (i == 0) {
$code.css('display', 'block');
}
else {
$code.css('display', 'none');
}
codes += $code.prop('outerHTML');
}
// build caption
caption = '<ul class="tabs">' + caption + '</ul>';
// add caption title
if (rCaptionUrl.test(arg)) {
match = arg.match(rCaptionUrl);
caption = '<a href="' + match[2] + match[3] + '">' + match[1] + '</a>' + caption;
}
else if (rCaption.test(arg)) {
match = arg.match(rCaption);
caption = '<span>' + match[1] + '</span>' + caption;
}
codes = '<div class="tabs-content">' + codes + '</div>';
// wrap caption
caption = '<figcaption>' + caption + '</figcaption>';
html = '<figure class="highlight multi">' + caption + codes + '</figure>';
return html;
}
/**
* Multi code block tag
*
* Syntax:
* {% m_codeblock %}
* <!-- tab [lang] -->
* content
* <!-- endtab -->
* {% endm_codeblock %}
* E.g:
* {% m_codeblock %}
* <!-- tab js -->
* var test = 'test';
* <!-- endtab -->
* <!-- tab css -->
* .btn {
* color: red;
* }
* <!-- endtab -->
* {% endm_codeblock %}
*/
hexo.extend.tag.register('m_codeblock', multiCodeBlock, {ends: true});
});
Прочтите комментарий, чтобы понять код.
Все, что вам нужно сделать, это поместить ваши файлы JavaScript в папку scripts
, и Hexo загрузит их во время инициализации.
Стилизовать блок кода
По умолчанию отображается только первая вкладка, а остальные скрыты, и мы сделали это в исходном коде пользовательского тега здесь:
$code = $('<div>').append(code).find('>:first-child');
if (i == 0) {
$code.css('display', 'block');
}
else {
$code.css('display', 'none');
}
Так что вам просто нужно больше CSS для улучшения пользовательского интерфейса и окраски кода. Поместите этот файл в theme/theme_name/assets/css/style.css
и свяжите его с макетом.
Анимируйте блок кода (сторона клиента JS)
Нам нужен javascript для анимации вкладки. Когда мы нажимаем на вкладку, все содержимое вкладки должно быть скрыто и отображаться только правая вкладка. Поместите этот скрипт в theme/theme_name/assets/js/script.js
и свяжите его с макетом.
$(document).ready(function() {
$('.highlight.multi').find('.tab').click(function() {
var $codeblock = $(this).parent().parent().parent();
var $tab = $(this);
// remove `active` css class on all tabs
$tab.siblings().removeClass('active');
// add `active` css class on the clicked tab
$tab.addClass('active');
// hide all tab contents
$codeblock.find('.highlight').hide();
// show only the right one
$codeblock.find('.highlight.' + $tab.text()).show();
});
});
Ваша проблема заключалась в возможности создать этот собственный тег, и я собираюсь интегрировать его в следующий выпуск темы hexo (Tranquilpeak), который я разработал.
Вот результат: а>
Проверьте его в реальном времени на JSFiddle
person
Louis Barranqueiro
schedule
02.03.2016
theme/theme_name/layout
- person Louis Barranqueiro   schedule 05.02.2016onclick="tab('tab2')
, поэтому мне нужно написать эту функциюtab()
, но я не уверен, где разместить для нее код. - person Dan   schedule 05.02.2016