Node and content type are arguably the two most common concepts that we hear when starting to learn Drupal. Sometimes they are used interchangeably, but they represent different concepts. Let's learn the difference and how they relate to one another. We are going to learn attributes that all nodes share, how content types can provide default values, and how content types serves as templates to collect different kinds of information.
A node is a container of information that can tell a story by itself. For example, if you are describing the first car you owned, you can say it was a 2001 Toyota Yaris running on gas with plate M1Q-2TY. This information can be stored in a Drupal node. Note that you are describing a specific car which is different from someone else's car. Maybe your father's first car was a 1971 Dodge Ram running on diesel with plate P80-1SN. Each specific car will be stored in a different Drupal node. Similarly, if your website stores information about motorcycles, events, blog posts, etc. each of them will be its own node.
As you can imagine, a car and a motorcycle are very different objects with distinct and unique properties. For instance, cars have doors and windows while motorcycles do not. This is where content types come into place. A content type is a template to collect information from different kinds of objects or ideas. These can be tangible like a car or intangible like an event. The content type will detail what information will be collected in each case. For a car, this can include the year, make, model, type of fuel, plate, number of windows, and number of doors. For an event this can be the date, location, price, and capacity.
It is key to understand that a content type is the template and a node is the specific instance. Therefore, every node is of one, and only one, particular content type and each content types can have multiple nodes associated with it. It is not recommended to have a content type that has only one or two nodes of its type. When something like this could happen consider creating one single content type to store similar elements. Then, use Drupal fields as part of the template to make the distinction between them. The reason for doing this is reducing the maintenance overhead of the Drupal site. For example, for each content type you have to configure permissions per role. Imagine that you have 10 permissions per content type and 5 roles in your website. If you go from 4 to 7 content types you will be going from 200 to 350 permissions you need to configure. Of course, only you know the content model required for your website so create as many content types as truly needed.
Attributes all nodes share
Every node in a Drupal site no matter its type will have some common attributes. The following list is not complete, but it includes some of the more important node attributes:
- Title: it is always required.
- Node ID (nid): This is a numeric identifier that Drupal uses internally to differentiate between nodes. The first one will have Node ID 1 and this number will increment by 1 each time a new node is created. Once set this number is not changed. Deleting a node does not make its nid available for future use.
- URL alias: Every node in a Drupal site can be accessed via its Node ID appending /node/[nid] to the domain of the site. Nevertheless, humans are better remembering phrases than numbers. Imagine that someone tells you to read the blog post at /node/491827. Wouldn't it be easier to remember something like /blog/intro-to-drupal-views? In my humble opinion, the latter is easier to remember. That is a URL alias: some text that you can set as an alternative to access a specific node. The URL alias is optional and even if set the node will continue to be available in its canonical /node/[nid] path. Using modules like Pathauto you can define rules for creating URL aliases so you do not have to write them manually each time.
- Publication status: this is a 'yes' or 'no' (boolean) value that indicates whether a node is available to the general public or not. You might start creating a blog post, but need to review some resources before making it public. Instead of losing your progress, you can save the node as a draft (not published) making it available only to certain privileged users. Later you can revisit the node and, when it is ready, save it as published making it available to everyone.
- Type: this is the content type the node belongs to. For example: basic page, article, car, event, etc.
- Author and publication time: Who created the node and when (date and time) it was published. If content revisioning is enabled for the content type then Drupal keeps track of who performed each modification and when it was made. Content revisioning will be explained in a later blog post.
- Menu settings: whether this node should be included in a menu, for example, to appear in the main navigation of the website. Imagine a node containing general information about your organization having an "About Us" link in the main navigation.
Remember that nodes are created in a particular content type template. As such, the content type can set default values for all nodes created under that type. For example, you can configure all blog posts to be unpublished by default assuming they need peer review before being available to the general public. Or, nodes of types blog post cannot be added to menus because you do not want any specific blog post to appear in the main navigation. Instead, you can create a special menu item that lists all the blog posts on the website. Note that depending of user permissions, these defaults can be overridden or not so it is important to set permissions properly.
Content type templates
Because a content type serves as the template to collect information, each one can set different templates to collect for the nodes of those types. These content type specific attributes are Drupal fields. They will be explained in detail in a future blog post. For now, consider the following examples:
- Content type car with fields: year, make, model, type of fuel, plate, number of windows, and number of doors.
- Content type event with fields: date, location, price, and capacity.
- Content type blog post with fields: image, body, and category.
In a default Drupal set up, using the standard installation profile, two content types are created: Basic page and Article. When creating a node of type Basic page you can only set the title and body fields. On the other hand, when creating a node of type Article you can additionally set an image and tags. That is because the Article content type template defines two extra fields: image and tags. Also note that by default Articles are aggregated in the homepage while basic pages do not. This is because the Article content type sets a default for a node attribute named 'Promoted to the homepage' as 'yes' while the Basic page content type sets it as 'no'. Today this node attribute is rarely used as there are several mechanisms to achieve the same behavior.
Naming things is hard
To finish this blog post let's consider some synonyms for the words "nodes" and "content types" that Drupal uses in its user interface and the underlying code base.
- "Content" is a synonym for "nodes." This is particularly common in the Views user interface. When creating a view, if you choose to show "Content" that tells the view to show nodes.
- "Bundle" is a synonym for "content type." Technically speaking, contents types are the "bundles of the node entity." Leaving the discussion about entities for a future blog post, it is important to remember that when talking about nodes the bundle refers to the content type. For example, you can have an entity reference content field with the "target bundle" configured to "Article". This means that this field can only reference nodes of the "Article" content type.
When learning a new technology, it is key to understand the basic building blocks. For Drupal, nodes and content types are concepts you need to understand since the beginning. Are there more things about nodes and content types that you consider important to know? Please share them in the comments.