如何为Hexo

时间:2016-02-01 21:04:25

标签: javascript node.js hexo

我试图在hexo中创建标签式代码块(作为标签插件),但我无法弄清楚我的js函数放在哪里。我以为我可以使用the js helper加载函数,但我不知道在哪里包含帮助器。我尝试并将其添加到标记插件中失败了。这是标签插件代码(保存为 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的第一行是我尝试使用帮助程序失败。

这是我的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");
}

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

我看到this answer我可能会帮助但我无法弄清楚视图是什么。我在Hexo文档中找不到任何关于视图的内容。

2 个答案:

答案 0 :(得分:7)

您的代码中有太多错误,所以我更愿意给您一个完整的解释说明。

以下是我们的需求:

  1. 用于构建此多个代码块的HTML结构的自定义标记
  2. 用于样式化代码块和代码着色的CSS文件
  3. 用于设置代码块动画的JS脚本(标签)
  4. 自定义标记: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)中。

    结果如下: result

    JSFiddle

    上查看

答案 1 :(得分:0)

您还可以创建由父标记读取的内部标记。

{% code_with_tabs %}
  {% code js title="something" class_name="info" %}
    1. aosjaojsdoajsdoajsd
  {% endcode %}
  {% code js title="something" class_name="info" %}
    2. aosjaojsdoajsdoajsd
  {% endcode %}
{% endcode_with_tabs %}

使用解析器读取生成的内部HTML。