How to show pieces into the another pieces?

2019-07-15 05:02发布

I have two type of pieces one is Authors and second one is Articles. I can show the list of articles (by using indexAjax.html and index.html in articles-pages) as it is implemented in Apostrophe's Demo and the list of Authors as well (by using indexAjax.html and index.html in authors-pages/views).

My question is how can I show the articles written by some specified author in by using show.html file of authors-pages/views ?
So when user clicks on some author he/she should be able to see the list of articles written by the specified author.

The lib/modules/articles/index.js file is the following

module.exports = {
    extend: 'apostrophe-pieces',
    name: 'articles',
    label: 'Article',
    pluralLabel: 'Articles',
    contextual: true,
    addFields: [
        {
            name: '_author',
            type: 'joinByOne',
            withType: 'author',
            label: 'Author',
            idField: 'author',
            filters: {
                projection: {
                    title: 1,
                    slug: 1,
                    type: 1,
                    tags: 1
                }
            }
        },

....

    ]

};

Any help will be appreciated!

2条回答
等我变得足够好
2楼-- · 2019-07-15 05:26

I'm the architect of Apostrophe at P'unk Avenue.

The code in your own solution effectively reimplements a feature we already have: reverse joins.

You already have a "forward" join (joinByOne). So use joinByOneReverse to make those items available from the "other side."

In the schema for authors, you can write this:

addFields: [
  {
    name: '_articles',
    type: 'joinByOneReverse',
    withType: 'articles',
    label: 'Articles',
    idField: 'author',
    filters: {
      projection: {
        title: 1,
        slug: 1,
        type: 1,
        tags: 1
      }
    }
  }
]

This makes a ._articles array property available on each author.

It is important to note that idField doesn't change. We are intentionally using the same information so that we get the same content.

If you wish, you can also set ifOnlyOne: true on that field to avoid having it fetched for the index page and other contexts where you load more than one author.

Check out the guide to schemas for more information.

查看更多
该账号已被封号
3楼-- · 2019-07-15 05:41

I found an answer for my own question (before seeing the posted alternative answer). Hope it will be useful for others.

So there are two pieces articles and authors.

lib/modules/authors-pages/index.js

module.exports = {
    extend: 'apostrophe-pieces-pages',
    articlesPerPage: 3,
    construct: function (self, options) {
        var beforeShow = self.beforeShow;
        self.beforeShow = function (req, callback) {
            var limit = self.options.articlesPerPage;
            var skip = req.query.page || 1;
            skip = (parseInt(skip) - 1) * limit;
            if (!req.data || !req.data.piece) {
                return beforeShow(req, callback);
            }
            var cursor = self.apos.docs.getManager('articles').find(req, {
                author: req.data.piece._id
            });
            cursor
                .skip(skip)
                .limit(limit)
                .sort({ createdAt: -1 })
                .toArray(function (err, articles) {
                    req.data._articles = articles || [];
                    req.data.currentPage = Math.ceil((skip + 1) / limit);
                    cursor.toCount(function(err, count){
                        if(err)
                            count = 1;
                        req.data.totalPages = Math.ceil(count / limit);
                        beforeShow(req, callback);
                    })

                })
        }
    }
}

lib/modules/authors-pages/view/show.html

{% extends data.outerLayout %} 
{% block title %}
    {{ data.piece.title }}
{% endblock %} 
{% block main %}
    {% for article in data._articles %}
        <p>{{article.title}}</p>    
    {% endfor %}
    {% import 'apostrophe-pager:macros.html' as pager with context %}
    {{ pager.render({ page: data.currentPage, total: data.totalPages }, data.url) }}
{% endblock %}
查看更多
登录 后发表回答