Skip to content

@apostrophecms/piece-page-type

Extends: @apostrophecms/doc-type ℹ️

This module cooperates with the 'piece-type' module to expose two specialized views. The index page displays all pieces of a particular piece-type in a paginated, filterable manner. The show page is for presenting individual pieces. These features are added to those exposed by the '@apostrophecms/page' module.

Once an editor adds a page of this type to the site via the user interface, it becomes possible to view a listing of pieces by visiting that page's URL, and to view individual pieces of the relevant type by adding the slug of any piece to the page's URL, like this: /slug/of/page/slug-of-piece

This default behavior can be customized as described below.

It is possible to add more than one such page to the site for the same type, and to add custom logic to decide which pieces should be associated with each such page.

Options

PropertyTypeDescription
nextBoolean || ObjectIf set to true, data.next is the next piece based on the sort.
perPageIntegerThe number of pieces to include in a set of GET request results.
piecesFiltersArrayTakes an array of objects where each contains a name key and a value of a field in the piece to filter on.
pieceModuleNameStringOptionally sets the piece-type to a specific name other than the default inferred from the module name.
previousBoolean || ObjectIf set to true, data.previous is the previous piece based on the sort.

next

If this option is set to true, it exposes the next piece in the current sort order as req.data.next (data.next in the template) when serving a show page. This can be used to provide a link to the next item in a series (e.g., the next oldest blog post).

This option can also be set to an object whose keys are query builders, such as project, and whose values are the parameters passed to each query builder.

javascript
module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    next: true
  },
  // …
}

// OR

module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    // The next article piece would be returned with only the `title, `_url`
    // and `lastPublishedAt` properties.
    next: {
      project: {
        title: 1,
        _url: 1,
        lastPublishedAt: 1
      }
    }
  },
  // …
}

perPage

The perPage option should be set to an integer and specifies the number of pieces displayed per page for the index.html page before pagination is offered. It is set to 10 items per page by default.

javascript
module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    perPage: 20
  },
// …
}

piecesFilters

The piecesFilters takes an array of objects to assist in filtering on the index page. Each object must have a name property associated with a valid query builder.

These include:

  • Custom query builders configured in an app that include a launder method
  • Field names whose field types automatically get builders:
    • boolean
    • checkboxes
    • date
    • float
    • integer
    • relationship
    • select
    • slug
    • string
    • url

When the index page is served, filter data will be returned in the req.data.piecesFilters object (data.piecesFilters in the template). This object consists of an array for each configured filter. That array contains objects with value and label properties for every piece-type that matches the filter. Passing filter values back to the index page as query string parameters will filter the results accordingly. If counts: true is included for the filter query, each object in the array will also have a count property with the number of matching pieces.

javascript
module.exports = {
  extend: '@apostrophecms/piece-type',
  options: {
    label: 'Book',
    pluralLabel: 'Books'
  },
  fields: {
    add: {
      _author: {
        label: 'Author',
        type: 'relationship'
      },
      category: {
        label: 'Category',
        type: 'select',
        choices: [
          // category choices here
        ]
      }
    }
    // …
  }
};
javascript
module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    piecesFilters: [
      { name: '_author' },
      {
        name: 'category',
        counts: true
      }
    ]
  }
};
{
  _author: [
    {
      slug: 'gibson',
      _edit: true,
      _publish: true,
      label: 'Gibson',
      value: 'cl64zrra8000fgels5v1k8ums:en:draft'
    },
    {
      slug: 'herbert',
      _edit: true,
      _publish: true,
      label: 'Herbert',
      value: 'cl64zsgi1000vgels1xoi2b9o:en:draft'
    },
    {
      slug: 'le-guin',
      _edit: true,
      _publish: true,
      label: 'Le Guin',
      value: 'cl64zs5h0000ngelsbhzvgdpc:en:draft'
    }
  ],
  category: [
    { value: 'cyberpunk', label: 'cyberpunk', count: 4 },
    { value: 'dystopian', label: 'dystopian', count: 9 },
    { value: 'fantasy', label: 'fantasy', count: 7 }
  ]
}

pieceModuleName

Piece page types are associated with a single piece type. If named with the pattern [piece name]-page, the associated piece type will be identified automatically. You can override this pattern by explicitly setting pieceModuleName to an active piece type. This is useful if there is more than one piece page type for a single piece type (e.g., to support different functionality in each).

javascript
// 👆 This module name would look for a piece type
// named `fiction` if not for `pieceModuleName`
module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    pieceModuleName: 'book'
  }
  // Code to select and group only fiction books
  // …
};

previous

If this option is set to true, it exposes the previous piece in the current sort order as req.data.previous (data.previous in the template) when serving a show page. This can be used to provide a link to the previous item in a series (e.g., the next newest blog post).

This option can also be set to an object whose keys are query builders, such as project, and whose values are the parameters passed to each query builder.

javascript
module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    previous: true
  },
  // …
}

// OR

module.exports = {
  extend: '@apostrophecms/piece-page-type',
  options: {
    // The previous article piece would be returned with only the `title`, `_url`
    // and `lastPublishedAt` properties.
    next: {
      project: {
        title: 1,
        _url: 1,
        lastPublishedAt: 1
      }
    }
  },
  // …
}

The following methods belong to this module and may be useful in project-level code. See the source code for all the modules that belong to this module.

indexQuery(req)

This method should be overridden for a piece-type to call additional query builders when generating the index page.

showQuery(req)

This method should be overridden for a piece-type to call additional query builders when generating the show page.

async beforeIndex(req)

This method is called before indexPage. Within the core module it does nothing, so it can be easily overridden by supplying a new method in the methods section of the custom module. It is a convenient method for manipulating the req being supplied to that page.

async beforeShow(req)

This method is called before showPage. Within the core module it does nothing, so it can be easily overridden by supplying a new method in the methods section of the custom module. It is a convenient method to extend for manipulating the req being supplied to that page.

dispatchAll()

This method can be extended to override the default behavior of invoking showPage if the URL has an additional path after the base, e.g. /blog/good-article. As example, you could override to use /:year/:month/:day/:slug to invoke self.showPage. This should be used in conjunction with the buildUrl()) method of this module. See @apostrophecms/page-type for more about what you can do with dispatch routes.

buildUrl(req, page, piece)

This method can be overridden to change the URLs that are generated as the _url property for individual pieces. Note that the dispatchAll method often must also be overridden to ensure those URLs actually reach those pieces.

filterByIndexPage(query, page)

This method invokes query builders on the supplied query argument to ensure it only fetches results appropriate to the given page. This is typically done when there is more than one pieces-page per page type. Within the core module it does nothing, so it can be easily overridden by supplying a new method in the methods section of the custom module. This should be used in conjunction with the chooseParentPage method of this module.

chooseParentPage(pages, piece)

The pages parameter of this method takes an array of all of the index pages for a particular piece-type, and the piece parameter is an individual piece-type name. The default version of this method will give a warning if it sees more than one page in the array, as it is up to the developer to override this method to provide a sensible way of deciding which page is the best 'parent' for each piece.