【问题标题】:Assemble - How do I limit a collect to display X posts?组装 - 如何限制收藏以显示 X 个帖子?
【发布时间】:2015-03-26 14:08:09
【问题描述】:

详情:

组装: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

标题:

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

创建日期:2014 年 6 月 23 日

slug:“欢迎”

面包屑:假

发布时间: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?

困惑。

【问题讨论】:

    标签: handlebars.js assemble static-site grunt-assemble


    【解决方案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
    

    那么你就可以像这样使用helper了

      <ul>
        {{#latest pages 5}}
          <li><a href="{{relativeLink}}">{{data.title}}</a></li>
        {{/latest}}
      </ul>
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      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”,然后从我网站上的站点站点文件夹(同样,在 data.yml 中定义)和“src”页面变量(其中我传递给我的自定义车把模板)。 “src”页面变量不是我需要的——它通常看起来像 /src/about/index.hbs 或类似的东西——所以我去掉了“src”并将“.hbs”替换为“ext” (在本例中为“.html”)。

      这是车把助手:

      helper-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}}。

      正如我所说,我确定我做错了什么,而且上下文令人困惑——但至少我做到了。

      【讨论】:

        【解决方案3】:

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

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

        Gruntfile

        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>
        

        【讨论】:

        • 非常感谢!我会试一试并报告。
        【解决方案4】:

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

        已编辑:我错了,可能有一种将集合排序和 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 助手的简洁源代码。您需要在 Gruntfile 的 Assemble 配置中注册它,如 options.helpers docs 中所述。

        /*
         * 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);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-07-07
          • 2021-11-06
          • 2021-05-18
          相关资源
          最近更新 更多