如何为Hexo实现选项卡式代码块标签 [英] How to implement a tabbed codeblock tag for Hexo

查看:164
本文介绍了如何为Hexo实现选项卡式代码块标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在hexo中创建选项卡式代码块(作为标签插件),但是我不知道将js函数放在哪里.我以为可以使用 js帮助器加载该函数,但是我不知道在哪里包括帮手.我尝试但未能将其添加到标签插件中.这是标签插件代码(保存为 testtag.js ):

I am trying to create tabbed code-blocks (as a tag plugin) in hexo but I cannot figure out where to put my js function. I thought I could load the function using the js helper but I don't know where to include the helper. I tried, and failed, to add it into the tag plugin. This is the tag plugin code (saved as testtag.js):

hexo.extend.tag.register('testtag', function(args, content){
  var className =  args.join(' ');

  var result = '';
  result += "<\%- js('\\themes\\bootstrap-blog\\scripts\\tab.js') \%>"
  result += '<div class="tabs">';
  result += '<ul>';
  result += '<li class="li_tab1" onclick="tab(&apos;tab1&apos;)"><a>Tab 1</a></li>';
  result += '<li class="li_tab2" onclick="tab(&apos;tab2&apos;)"><a>Tab 2</a></li>';
  result += '</ul>';
  result += '<div class="contentarea">';
  result += '<div id="tab1">';
  result += '<p>' + content + '</p>';
  result += '</div>';
  result += '<div id="tab2" style="display: none;">'
  result += '<p>This is the text for tab 2.</p>'
  result += '</div>'
  result += '</div>'
  result += '</div>'

  return result;

}, {ends: true});

有效.但是,标记的onclick事件只会引发无法找到tab函数的错误.请注意,上面result的第一行是我使用助手的失败尝试.

which does work. However, the onclick event of the tags just raises the error that it can't find the tab function. Note that the first line of result above was my failed attempt to use the helper.

这是我的tab函数 tab.js :

function tab(tab) {
document.getElementById('tab1').style.display = 'none';
document.getElementById('tab2').style.display = 'none';
document.getElementById('li_tab1').setAttribute("class", "");
document.getElementById('li_tab2').setAttribute("class", "");
document.getElementById(tab).style.display = 'block';
document.getElementById('li_'+tab).setAttribute("class", "active");
}

保存在* \ themes \ bootstrap-blog \ scripts *文件夹中的 tab.js testtag.js .

Both tab.js and testtag.js as saved in the *\themes\bootstrap-blog\scripts* folder.

我看到了这个答案,虽然我可能会有所帮助,但我无法弄清楚视图是什么.在Hexo文档中找不到关于视图的任何信息.

I saw this answer which I though might help but I can't figure out what a view is. I couldn't find anything about views in the Hexo docs.

推荐答案

您的代码中有太多错误,因此我希望为您提供完整的示例并进行解释.

There are too many mistake in your code so I prefer to give you a full example with explanations.

这是我们需要的:

  1. 用于构建此多个代码块的HTML结构的自定义标记
  2. 用于样式化代码块和代码颜色的CSS文件
  3. 用于为代码块(标签)制作动画的JS脚本

自定义标签:m_codeblock(JS服务器端)

我们需要允许用户定义:

Custom tag : m_codeblock (JS server side)

We need to allow user to define :

  • 名称或链接
  • 此标签中有多个代码块,因此我们定义了一个标签来分隔并列出每个标签

语法如下:

{% 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
  • run npm install jsdom --save
  • run npm install jquery --save

,这是放在themes/theme_name/scripts/m_codeblock.js中的此自定义标签的源代码:

and here is the source code of this custom tag put in 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将在初始化期间加载它们.

All you need to do is put your JavaScript files in the scripts folder and Hexo will load them during initialization.

样式化代码块

默认情况下,仅显示第一个标签,而其他标签则隐藏,我们在此处的自定义标签源代码中进行了此操作:

Stylize the code block

By default, only the first tab is displayed and others hidden and we did that in the custom tag source code here :

$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中,并将其链接到布局.

So you just need more css to improve user interface and code coloration. Put this file in theme/theme_name/assets/css/style.css and link it to a layout.

我们需要一些JavaScript来为标签制作动画. 当我们单击选项卡时,所有选项卡的内容都必须隐藏,并且仅显示右侧的选项卡.将此脚本放入theme/theme_name/assets/js/script.js并将其链接到布局.

We need some javascript to animate the tab. When we click on a tab, all tab contents must be hidden and only the right tab displayed. Put this script in theme/theme_name/assets/js/script.js and link it to a layout.

$(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 ).

Your issue was the opportunity to build this custom tag and I'm gonna integrate it in the next release of a hexo theme (Tranquilpeak) that I developed.

结果是:

JSFiddle

Check it live on JSFiddle

这篇关于如何为Hexo实现选项卡式代码块标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆