没有找到把手和节点动态部分

时间:2016-04-05 22:48:43

标签: javascript node.js handlebars.js bigcommerce

我试图动态渲染部分(意思是,在程序运行之前,部分名称是未知的)。我发现使用Handlebars docs中的简单lookup子表达式可以实现这一点。

动态部分

  

可以动态选择要执行的部分   使用子表达式语法。

     

{{> (whichPartial) }}

     

将评估whichPartial,然后呈现其名称返回的部分   这个功能。

     

Subexpressions不解析变量,因此whichPartial   必须是一个功能。如果一个简单变量具有部分名称,那么它就是   可以通过查找帮助程序解决它。

     

{{> (lookup . 'myVariable') }}

这是我的设置:

我的页面包含以下调用:

{{> components/common/panel content="components/common/category-images"}}

然后,在components/common/panel.html,我有:

<div class="panel">
  {{> (lookup . 'content')}}
</div>

当这个运行时,我收到一个错误:

Debug: internal, implementation, error
    Error: Uncaught error: The partial components/common/category-images could not be found

如果我直接用以下方式调用部分:

{{> components/common/category-images}}

它工作正常,所以我知道该文件存在。更奇怪的是,如果我包含原始行,然后直接调用部分注释掉,它就可以工作:

{{> components/common/panel content="components/common/category-images"}}
{{!-- {{> components/common/category-images}} --}}

但是,只要删除该注释行,我就会再次收到错误,即找不到该部分。我很困惑。有人可以帮忙吗?

更新

我找到了以下似乎相关的文件:stencil-cli/lib/templateAssembler.js。以下是内容:

var _ = require('lodash'),
    Async = require('async'),
    Fs = require('fs'),
    Path = require('path'),
    internals = {
        options: {
            templatesFolder: Path.join(process.cwd(), 'templates'),
            extension: '.html',
            partialRegex: /\{\{>\s*([_|\-|a-zA-Z0-9\/]+)[^{]*?}}/g,
            dynamicComponentRegex: /\{\{\s*?dynamicComponent\s*(?:'|")([_|\-|a-zA-Z0-9\/]+)(?:'|").*?}}/g
        }
    };

module.exports.assemble = assemble;
module.exports.getTemplateContentSync = getTemplateContentSync;

/**
 * Parses the passed in templates and resolves all of their partials.
 *
 * @param templates
 * @param callback
 */
function assemble(templates, callback) {
    getTemplatePaths(templates, function(err, templatePaths) {
        if (err) {
            return callback(err);
        }

        getContent(templatePaths, callback);
    });
}

function getTemplateContentSync(templateFile) {
    var path = Path.join(internals.options.templatesFolder, templateFile + internals.options.extension);
    return Fs.readFileSync(path).toString();
}

/**
 * Parses the passed in templates and returns all of the partials for each one
 *
 * @param templates
 * @param callback
 */
function getTemplatePaths(templates, callback) {
    var templatePaths = [],
        missingTemplates = [];

    if (templates === undefined) {
        return callback(null);
    }

    if (! _.isArray(templates)) {
        templates = [templates];
    }

    Async.each(templates, resolvePartials, function (err) {
        if (err) {
            return callback(err);
        }

        if (missingTemplates.length > 0) {
            return callback(new Error(
                'The following template(s) are/is missing: \n' + missingTemplates.join('\n')
            ));
        }

        callback(null, templatePaths);
    });

    function resolvePartials(templateFile, callback) {
        var file = Path.join(internals.options.templatesFolder, templateFile + internals.options.extension);
        console.log(file);
        Fs.readFile(file, {encoding: 'utf-8'}, function(err, content) {
            var componentPaths = [],
                matches = [],
                match,
                partialPath;

            if (err) {
                missingTemplates.push(templateFile);

                return callback();
            }

            templatePaths.push(templateFile);
            match = internals.options.partialRegex.exec(content);
            while (match !== null) {
                partialPath = match[1];
                if (templatePaths.indexOf(partialPath) === -1) {
                    matches.push(partialPath);
                }
                match = internals.options.partialRegex.exec(content);
            }

            match = internals.options.dynamicComponentRegex.exec(content);

            while (match !== null) {
                if (componentPaths.indexOf(match[1]) === -1) {
                    componentPaths.push(match[1]);
                }
                match = internals.options.dynamicComponentRegex.exec(content);
            }

            Async.each(componentPaths, function(componentPath, callback) {
                Fs.readdir(Path.join(internals.options.templatesFolder, componentPath), function(err, files) {
                    if (err) {
                        return callback(err);
                    }

                    matches = _.reduce(files, function(acc, file) {
                        // remove the extension
                        partialPath = Path.join(componentPath, Path.parse(file).name);
                        if (templatePaths.indexOf(partialPath) === -1) {
                            acc.push(partialPath);
                        }

                        return acc;
                    }, matches);
                    callback();
                });
            }, function(err) {
                if (err) {
                    return callback(err);
                }

                Async.each(matches, resolvePartials, callback);
            });
        });
    }
}

/**
 * Takes a list of templates and grabs their content. It returns simple key/val pair
 * of filename => content
 *
 * @param templatePaths
 * @param callback
 */
function getContent(templatePaths, callback) {
    Async.reduce(templatePaths, {}, getContentReducer, callback);

    function getContentReducer(acc, templatePath, reduceCallback) {
        var file = Path.join(internals.options.templatesFolder, templatePath + internals.options.extension);
        Fs.readFile(file, {encoding: 'utf-8'}, function(err, content) {
            if (err) {
                return reduceCallback(err);
            }

            acc[templatePath] = content;

            reduceCallback(null, acc);
        });
    }
}

对每个模板文件/部分文件递归调用此函数,我可以通过我的console.log语句确认category-images部分不在我的非工作版本的文件列表中码。看起来服务器未设置为从子表达式语法解析模板。此行显示用于查找partials的正则表达式:

partialRegex: /\{\{>\s*([_|\-|a-zA-Z0-9\/]+)[^{]*?}}/g

我假设在评估子表达式之前运行,因此部分永远不会被识别。这听起来像是问题吗?是否存在子表达式部分未被评估的原因?

0 个答案:

没有答案