1

细节:

组装:0.4.4

咕噜声:0.4.1

问题:

我正在设计一个博客,我想在首页上放 5 个最新的帖子。我根据关键字为我的帖子创建了一个集合:

assemble: {
  options: {
    flatten: false,
    partials: '<%= build.src %>/_partials/*.hbs',
    layoutdir: '<%= build.src %>/_layouts',
    data: ['<%= build.src %>/_data/*.{json,yml}', 'package.json'],
    assets: '<%= build.out %>/',
    helpers: [ 'helper-moment','<%= build.src %>/helpers/helper-*.js'],
    collections: [
    { name: 'keywords', inflection: 'keyword' }
    ]

  },

各个帖子上的 YAML 头条内容与此类似:

--

布局:default.hbs

标题:<%= site.title %>

描述:“2015 年成人重新部署所有站点峰会”

创建日期:2014 年 6 月 23 日

蛞蝓:“欢迎”

面包屑:假

发布时间:2014 年 1 月 12 日

关键词:

  • 消息

导航排序:100

--

我显示标题和摘要的代码是这样的:

<div>
  {{#each keywords}}
   {{#is keyword "news"}}
   {{#withSort pages "data.posted" dir="desc"}}
    <div>
     <h2><a href="/{{relativeLink}}">{{data.title}}</a></h2>
      <p>{{formatDate data.posted "%F"}}</p>
    <div>
        {{#markdown}}{{data.summary}}{{/markdown}}
    </div>
    <p><a href="/{{relativeLink}}">more...</a></p>
  </div>
  {{/withSort}}
  {{/is}}
  {{/each}}
 </div>

这行得通。它显示所有博客没问题。但我想限制为 5 个——最近的五个。

我看过这个问题:

https://github.com/assemble/assemble/issues/463

但我不确定如何将其合并到上面的示例中。有没有办法限制页面#withSort?

使困惑。

4

4 回答 4

1

有同样的问题,最终为它创建了一个助手。

var _ = require('underscore');

var helpers = {
    latest: function(array, amount, fn) {
        var buffer = "";

        _.chain(array)
            .filter(function(i) {
                return i.data.date;
            })
            .sortBy(function(i) {
                return i.data.date;
            })
            .reverse()
            .first(amount)
            .forEach(function(i) {
                buffer += fn.fn(i);
            });

        return buffer;
    },

};

module.exports.register = function(Handlebars, options) {
    options = options || {};

    for (var helper in helpers) {
        Handlebars.registerHelper(helper, helpers[helper]);
    }
    return this;
};

将它添加到 assemble.helpers 搜索路径的某处。确保您已安装下划线依赖项

npm install underscore --save-dev --save-exact

然后你可以像这样使用助手

  <ul>
    {{#latest pages 5}}
      <li><a href="{{relativeLink}}">{{data.title}}</a></li>
    {{/latest}}
  </ul>
于 2015-05-03T11:39:37.977 回答
0

好吧,我终于得到了这个工作,但这可能不是最好的方法。事实上,这一路都是蛮力。但我将发布最终奏效的内容。

这是设置——对我原来的问题稍作修改。

我想创建一个部分 --sidebar.hbs -- 列出 5 个最近的帖子。然后,当我想要一个包含最新内容的侧边栏时,我想在我的“正常”页面中调用该部分。好的,设置就到这里。

我在 grunt.js 中的汇编程序:

咕噜声

assemble: {
  options: {
    flatten: false,
    partials: '<%= build.src %>/_partials/*.hbs',
    layoutdir: '<%= build.src %>/_layouts',
    data: ['<%= build.src %>/_data/*.{json,yml}', 'package.json'],
    assets: '<%= build.out %>/',
    helpers: [ 'helper-moment','<%= build.src %>/helpers/helper-*.js'],
    collections: [
    {  name: 'keywords',
      inflection: 'keyword',
      sortby: 'posted',
      sortorder: 'desc',
    }
    ]

  },

然后我意识到——就像你在上面友好地回应一样——我可以循环浏览这个集合:

sidebar.hbs(不工作 - {{relativeLink}} 未定义 - 但已排序!)

     {{#each keywords}}
        {{#is keyword "news"}}
        {{#withFirst pages 3}}
           <h5 style="padding-left: 7px; padding: 0; margin: 0;">
<a href="{{relativeLink}}">{{data.slug}}</a></h5>
       {{/withFirst}}
  {{/is}}
  {{/each}}
          
     

除了 - 问题是:{{relativeLink}} 在这里没有正确设置。它什么也不返回——它是空白的。我怀疑我通过从模板页面调用 sidebar.hbs 部分来混淆上下文。我不确定,但我知道下面的代码是部分代码——并返回正确的 {{relativeLink}}:

sidebar.hbs(工作,没有排序——只显示站点中的所有页面)

{{#each pages}}


{{data.slug}} -- {{relativeLink}}
<br/>

{{/each}}

当然,那里的问题是它返回了所有页面——而且它们没有排序。

所以,为了让我的侧边栏部分工作——无论我们在站点层次结构中的哪个位置返回正确的链接——我创建了这样的链接(我很尴尬地发布这个——但它有效)。我在#withFirst 循环中使用了“page.src”变量。这适用于我想要的但似乎很尴尬:

sidebar.hbs (工作,排序,但似乎不是正确的方法):

    {{#each keywords}}
  {{#is keyword "news"}}
  {{#withFirst pages 4}}

  <div class="myArticle">
    <article class="recent-posts" >


      <h5 style="padding-left: 7px; padding: 0; margin: 0;"><a href="{{data.siteFolder}}{{constructPostLinks src ext}}">{{data.slug}}</a></h5>
    <p>

      <span >
        {{moment data.posted format ="DD MMM YYYY"}}

      </span>



    </p>



  </article>
</div>

  {{/withFirst}}
  {{/is}}
  {{/each}}

我本质上要做的是调用一个助手——“constructPostLinks”,并将我网站上站点文件夹中的 URL(同样,在 data.yml 中定义)和“src”页面变量(我传递给我的自定义车把模板)。“src”页面变量不是我需要的——它通常看起来像 /src/about/index.hbs 或类似的东西——所以我去掉了“src”并将“.hbs”替换为“ext” (在这种情况下,'.html')。

这是车把助手:

助手-constructPostLinks.js

module.exports.register = function (Handlebars)  {
  Handlebars.registerHelper('constructPostLinks', function(page,ext) {
    pageLink = page.replace('src/','').replace('.hbs',ext);
    return new Handlebars.SafeString(pageLink);
  });
};

我不知道。这似乎是一种非常笨拙的生成链接的方法,但它确实有效。我可以写一个页面——index.hbs——然后包括侧边栏部分{{>sidebar}}——然后所有的东西都被放在默认的页面模板(page.hbs)中,链接是为最近发表的文章。有用。但我希望集合排序例程包含正确的 {{relativeLinks}}。

正如我所说,我确信我做错了事情并混淆了上下文——但至少我已经做到了。

于 2015-01-30T20:04:45.710 回答
0

应该可以通过以下组合来实现您的目标:

  1. 在 Gruntfile 中为您的关键字集合指定自定义排序规则。
  2. 使用{{#withFirst pages 5}}帮助器将现在排序的列表限制为您的前五个帖子。

咕噜文件

assemble: {
  options: {
    flatten: false,
    partials: '<%= build.src %>/_partials/*.hbs',
    layoutdir: '<%= build.src %>/_layouts',
    data: ['<%= build.src %>/_data/*.{json,yml}', 'package.json'],
    assets: '<%= build.out %>/',
    helpers: [ 'helper-moment','<%= build.src %>/helpers/helper-*.js'],
    collections: [
      { name: 'keywords', inflection: 'keyword', sortby: 'posted', sortorder: 'desc' }
    ]
  },

页面模板

<div>
  {{#each keywords}}
    {{#is keyword "news"}}
      {{#withFirst pages 5}}
        <div>
          <h2><a href="/{{relativeLink}}">{{data.title}}</a></h2>
          <p>{{formatDate data.posted "%F"}}</p>
          <div>
          {{#markdown}}{{data.summary}}{{/markdown}}
          </div>
          <p><a href="/{{relativeLink}}">more...</a></p>
        </div>
      {{/withFirst}}
    {{/is}}
  {{/each}}
</div>
于 2015-01-29T19:45:16.693 回答
0

有好消息也有坏消息。坏消息是我不相信有一个内置的帮助器可以对页面集合进行排序和限制,你也不能将它们中的两个拼凑在一个管道中。

编辑:我错了,可能有一种结合集合排序和 withFirst 助手的内置方式。我会单独回答。

好消息是您可以编写自己的自定义 Handlebars Helper 来执行此操作。我在下面基于withSort Helper编写了一个示例助手。你会像这样使用它:

<div>
  {{#each keywords}}
    {{#is keyword "news"}}
      {{#withSortLimit pages sortBy="data.posted" dir="desc" limit=5}}
        <div>
          <h2><a href="/{{relativeLink}}">{{data.title}}</a></h2>
          <p>{{formatDate data.posted "%F"}}</p>
          <div>
          {{#markdown}}{{data.summary}}{{/markdown}}
          </div>
          <p><a href="/{{relativeLink}}">more...</a></p>
        </div>
      {{/withSortLimit}}
    {{/is}}
  {{/each}}
</div>

withSortLimit.js 这是 withSortLimit 助手的简洁源代码。您需要按照options.helpers 文档中的说明在 Gruntfile 的 Assemble 配置中注册它。

/*
 * withSortLimit Handlebars Helper for Assemble
 * Sample usage:
 *   {{#withSortLimit pages sortBy="data.posted" dir="desc" limit=5}}
 *     <li>{{formatDate data.posted "%F"}}: {{data.title}}</li>
 *   {{/withSortLimit}}
 */
(function() {

    var _ = require("lodash");

    function getPropertyFromSpec(obj, propertySpec) {
        var properties = propertySpec.split('.');
        var resultObj = obj;
        _.each(properties, function (property) {
            if (resultObj[property]) {
                resultObj = resultObj[property];
            }
        });
        return resultObj;
    }

    module.exports.register = function(Handlebars, options) {
        Handlebars.registerHelper("withSortLimit", function(collection, options) {
            var result = "";
            var selectedPages = collection;

            // Sorting
            var sortProperty = options.hash.sortBy || "basename";
            selectedPages = _.sortBy(collection, function (item) {
                return getPropertyFromSpec(item, sortProperty);
            });
            if (options.hash.dir && options.hash.dir === "desc") {
                selectedPages = selectedPages.reverse();
            }

            // Limit
            if (options.hash.limit && options.hash.limit > 0) {
                selectedPages = _.first(selectedPages, options.hash.limit);
            }

            // Rendering
            _.each(selectedPages, function (page, index, pages) {
                result += options.fn(page);
            });

            return result;
        });
    };

}).call(this);
于 2015-01-29T18:41:27.967 回答