Nodes are the building blocks of a PushType website. Each node can have siblings and children, so collectively nodes can be arranged to define a tree-like hierarchy of content.

It’s tempting to think of nodes as pages, but they can be so much more. A node can be an article, or an event, or a testimonial, or a promotion… with the power of custom fields a node can be whatever your unique set of requirements demand.

Creating a node

PushType provides a Rails generator for creating new nodes. It is invoked by passing a name for the node along with a list of field names and field types.

rails g push_type:node page description:string body:wysiwyg

The command above will create a model at app/models/page.rb, which looks like:

class Page < PushType::Node

  # By default a node's children can be any other node type.
  # Optionally pass a list of acceptable node types or prevent
  # any descendants by passing false.
  has_child_nodes :all

  # Model the content by adding custom fields to the node.
  field :description, :string
  field :body, :wysiwyg


The generator also created a view at app/views/nodes/page.rb which is rendered by the NodesFrontEndController when you visit the node’s permalink.

Child nodes

By default a node’s children can be any other node type. In most cases this is probably undesired. The has_child_nodes class method can be used to whitelist acceptable children (or prevent descendants from the node entirely by passing false).

For example, a typical blog structure might look like this:

class Blog < PushType::Node
  has_child_nodes :article, order: :blog

On any node instance, Node#children can be called to return all the children. By default children can be ordered arbitrarily through the admin UI. This behaviour can be overridden by passing an SQL fragment as the :order option.

Note that in the example above, the :order option contains the symbol :blog. This is a bit of shorthand magic, essentially translating as ['published_at DESC', 'created_at DESC']

Custom fields

Custom fields are where PushType really begins to flex its muscles. The field class method can be called any number of times, passing the field name, the field type and an optional hash of options for the field type.

For example, an article in our blog might look like this:

class Article < PushType::Node
  field :excerpt, :text
  field :body, :wysiwyg, validates: { presence: true }
  field :testimonial_ids, :relation, multiple: true
  field :tags, :tag_list

Hopefully the above is all pretty self explanatory. The real beauty is that this is all there is to it. Each field has it’s own view so the admin UI will automatically render a rich form for your nodes. And because all field data is stored as as jsonb object in the PostgreSQL database, there are no migrations to run.

Custom fields are an incredibly powerful way to shape and model content. PushType comes packaged with a wide variety of custom field types each with different options and capabilities.

Unexposed nodes

By default all node types are exposed to the NodesFrontEndController when visiting the permalink. Sometimes it may be desirable to effectively hide sections of content from the front end. This can be achieved by calling the unexpose! class method on the node model.

For example, you may have a collection of testimonials that are stored in the content tree, but only ever embedded within other pieces of content (i.e. the testimonial shouldn’t be an HTML document available through it’s own permalink). Simples:

class Testimonial < PushType::Node

For those that are paying attention, this is exactly the same as adding the node type to the unexposed_nodes configuration option.