Now, for something different from my usual musings, a tech blog!
I recently started setting up a website for a casual gaming group I am part of. I decided to try Drupal as it seemed to have the ultimate flexibility I was looking for and I didn’t have time to code all the features I wanted into the site myself. As I got the ball rolling with Drupal 8, I became increasingly unhappy with the fact that Drupal had no way built into it’s Core to restrict content access to certain authenticated users or, in my case, members. You can use block configuration to limit the visibility of certain elements by roles, but it does not put a hard restriction on viewing the element if the user knows the address. By default, Drupal has several ways to restrict who can create and edit content but assumes that all published content can/should be seen by everyone.
To compound the problem, because Drupal 8 had been “recently” released (out for 4 months when I started with it), the module support for it had not caught up and none of the known modules that restricted access in Drupal 7 were ready for Drupal 8. Eventually, a drupal community member named Peter Majmesku found he needed this functionality so badly that he created the module Permissions by Term: https://www.drupal.org/project/permissions_by_term
Permissions by Term allows you to create a Taxonomy term in Drupal (like a tag) and then apply restrictions to that term by individual users or role groups. Then, any content to which you add a reference to the term will be restricted (i.e. viewable or editable) to only people you have specified.
Making it Work
To begin, install the Permissions by Term module the way you would any other Drupal 8 module using either the link or the download from the project page located at https://www.drupal.org/project/permissions_by_term . Be sure to install/enable it so that it is checked in the Admin Menu > Extend list.
There are many different needs and use cases for restricting access to specific content. I imagine the most common will be that you have content on the site that you want accessible by authenticated users belonging to a specific role group but not the public. Going beyond this, you may want different role groups to be able to access different types of content. In any case, it’s a good idea to have the users, or at least the roles, exist in your system before you attempt to restrict access to them.
It also might be a good idea to grant users the role you intend to restrict access by, though not strictly necessary. You can, of course, add more roles and users after setting the permissions and alter the permissions after they have been specified. So don’t worry if you don’t have your entire permission structure fully baked. However, it would probably help to have a good idea about how you are going to want to organize access in the future before you start restricting it.
If you are satisfied that you know how you want to restrict access, the first step is to create a new Taxonomy vocabulary. This is basically creating a container for the various terms that you might use to restrict access in different ways. You could technically create different vocabularies, each with their own terms to be used for restricting access and your needs might demand it. But I think the most straightforward way to organize it would be to create a vocabulary called something like “Access Restrictions” that you use to put all the restricting terms in. You do this by going to Admin Menu > Structure > Taxonomy and click the + Add vocabulary button. Give your Vocabulary a name and a description of the types of terms it might contain. Once done, click Save.
You will then be presented with the terms associated with the new vocabulary, of which there will be none by default. Click the +Add Term button to add a new one. You can call it whatever you think is appropriate, probably something descriptive of how you plan on using it to restrict access. If you are familiar with Drupal Taxonomy, you will notice a new section for the term called PERMISSIONS. This is where you can restrict access to any number of roles or specific users. Give the term a description, again a good choice would be something that indicates to whom access is restricted by this term and then Save it.
You’ll now have a term you can use to restrict content with. You could certainly add more to suit your restriction needs now or at a later time.
Now you’ll want to create a content type that you are going to restrict access to. Go to Admin Menu > Content types and click the + Add content type button. Drupal being what it is, this could be anything from a type of page to a file. In my case, let’s say it is a type of page that you want to put content on that can only be seen by certain users who are authenticated with your site and members of a specific role group (so not visible to the public). Once you have the details set, click Save and manage fields.
After the content type is created you will be presented with the fields that it will contain. By default there is only a body field. Click the + Add field button to add the field that will activate the access restriction. For this new field you want to ensure that Taxonomy term is selected under Add a new field (this assumes you haven’t already created such a field previously, if you have you can simply select it under Re-use an existing field). You can give the field any label you want, the key part is that the Machine name reads field_secured_areas with that exact spelling. Once you have done this click Save and continue to move on.
You should then be presented with the Field Settings which you should ensure that Type of item to reference is set to Taxonomy term and the Allowed number of values is set to 1 (as of this writing this is all the module supports, though there has been talk about changing it here: https://www.drupal.org/node/2725627). Once you have ensured the above, select Save field settings.
You will then be presented with the field details to edit. You can give the field any label you like, again it might be useful to call it something that refers to the fact that it is there to provide the restriction to the content. Ensure that the Reference method is set to Default and that you check the box next to the vocabulary you created that contains the terms with the restrictions you want to use. At this point you can click Save settings or you can optionally add a DEFAULT VALUE first.
Whether you use a default value, or not, is up to you. If you don’t specify one, then any time a new instance of this content type is created, the value will have to be specified. Otherwise, the content will not be restricted. You may want this. You also may want the field to be editable so anyone with edit rights to this content type can change the restrictions (though importantly, even if a user has the Drupal permissions to edit the content type, they will not be able to edit it if the term permissions restrict their access). Conversely, you may want to specify a default value and then hide the field in the content type’s form display so that any time this content type is created or edited, it automatically has the correct restriction without the creator/editor even knowing it is there. You could also specify a default simply so content creators have a guide so that when they create new content they might usually leave the field alone but could change it if they have specific need.
Once the field is created, you will see it in the list of fields for the content type. Ensure that the machine name for the field is field_secured_areas. You could also add any other fields you want to be part of this content type. It is now ready to use. You can also grant create and edit permissions to other users/roles or add it to their shortcuts.
Now, in any content list you can click the + Add Content button, if you have permissions to do so, and you will see it in the list of content type options. Select it to start creating a new piece of content.
If the field is visible in the Manage form display settings for the content type, you will see it in the editor and possibly be able to edit it. The rest of the content creation is the same as any other Drupal content creation.
If the field is visible in the Manage display settings for the content type, you will see it displayed with the rest of the content.
Any user not specified in the term permissions who attempts to access (either viewing or editing) the content will simply get an access denied response.
That’s it! I can’t speak highly enough about how this module saved my site. I feel as though restricting access to content for certain users is common enough to warrant that functionality being part of Drupal’s Core. Some day it probably will. But for now, you can use this module with Drupal 8 to restrict access any way you need to.
Drupal, as any other open source CMS, and a framework, has a specific architecture and API for achieving both standard and custom functionalities. Some websites are simple and straightforward, whereas others are more complex, with many inter-related problems in it. But no matter the scale – effective initial technical specification is vital for your project’s overall success.
Drupal is great for both site builders, and developers. Hand site builders can achieve a lot of rich features only with configurations. No programming or coding needed. On the other hand, Drupal has a well-documented and features-rich API. These are the reasons why millions of developers and site builders love the system – Drupal is an excellent choice for building a quick and features-rich proof of concept web applications before and during your project’s cycle.
Once you’ve decided to head on the Drupal-way of making good specifications, you’ll need to understand and adopt some new ideas on how things work. (on a Drupal-paradigm level) Developers and Drupal configurators working with you will love you when they see well-written, system-specific specification. Eventually, this saves your time, and their time as well.
A list of topics and components we’re going to include for your Drupal-paradigm thinking is following. Knowing them will make you a good Drupal specifications writer:
- Content types;
- Users and permissions;
The term is self-explanatory – these are simply the various types of content you’ll be having in your project. The “content type” and “node type” terms are synonyms. You can use both, but the first is more close to non-Drupal people who don’t know what a “node” is. Most commonly, content types are news, static pages, articles, products, brochures, etc. By default, Drupal comes with 2 content types – basic page and an article.
How can you recognize what part of the website should be a content type? Asking your client questions with that note in mind:
Any piece of content, which will go in a separate places of the website, and serves a different purpose – this is a separate content type. At any case, when you have separate input forms for uploading content to Drupal, these are content types.
The second thing you should define after content types, are fields definitions. Ask yourself – what are the fields that my client will input when he uploads a new piece of content from a given content type? Keep in mind that the tile field is obligatory, the rest of the fields can be managed via configurations. Some fields examples:
- Text area field for content description;
- Date field for any start/end or just original post date information, default value – today;
- Image field for uploading a thumbnail or gallery pictures;
- File attachment field for adding documents and files;
- Text field for any data input – decimal numbers, normal text, etc
For example, you can define News content type in the following type:
“News” content type:
- Title – text field input – obligatory
- Original publish date – date field with a calendar pop-up, no repeating options
- News contents – text area input – rich text editing options with WYSIWYG controls;
- Meta information about author, url path alias and system date of publish
Once you understand the concept about content types and fields, it’s natural to go a step further. Now let’s talk about the next new (and big) concept in Drupal 7.
Entities are objects.
For site builders, entities are objects that can have fields attached to them. These are the same fields we spoke about in the content types section above.
In Drupal 7 core, entities are:
- Nodes; (content types);
- Users; (people using the website)
- Categories; (taxonomy terms)
If a given object in Drupal is an entity, that means that it can have fields attached to it, just the same way content types can.
For example – we can define user profiles (Users type of entity) in the following way:
Definition of an authenticated (registered) user on the website:
- First name – text field input – obligatory
- Last name – text field input – obligatory
- Birthday – date field with calendar pop-up widget input; no repeating options, possible choice for – 70 years back from today
- Bio – text area field; rich text editing options, with WYSIWYG controls
- Profile image – image field – file upload with picture manipulation widget
If you’re coming from an OOD/P background and are trying to understand the entity concept, you can think of it as an object or an instance of a base class of an entity type.
Another common example of entity usage is that entities can be also categories: this is useful when you want your product category to have image and description only relevant to the given category set.
Taxonomies and categorization
Taxonomy categorization is something you can expect from any CMS. Every website has content that have to be separated and organized in a given manner – for various reasons: better navigation, SEO, and others.
Basically, every piece of entity item in Drupal can be categorized. This is because, as you already know, every entity can have fields assigned to it. Categorization is the event when a piece of content is assigned to be referenced by a term reference field. It doesn’t really matter whether the content will have only one value, or multiple values.
Important note on categorization: think well when you promise “relevant content” features and functionalities. It’s a popular project request to build a block (also known as a box/widget) of items that are relevant to the currently displayed content, i.e. a block listing people with similar interests. These features are usually built with taxonomy term categorization. When content items are categorized under one and the same term, they can be displayed to be relevant to each other.
Example cases are when your client wants a block showing people that have same interests with the authenticated user, or events that are on the same topic with the event currently displayed, etc.
Even though seemingly the simplest part of the project specifications, templates can actually become the most tricky one. We won’t go into details about the code of the template, but rather how site administrators (and your clients) will work with content layouts and settings.
In order to make your client feel comfortable managing the website’s content, you have to minimize your client’s interaction with the system. Optimally, the client has to be able to publish content in 2 or 3 clicks. And in order to do that, your best approach would be to organize the website’s templates in a repetitive patterns and logic rules (so your client won’t click here and there unnecessarily)
In order to organize Drupal in a repetitive layouts and templates, you can combine code templates for node types, and configurations of Blocks and Context modules. The first one is coming from core, and the second one makes your work even easier.
Blocks are like boxes or widgets you put in specific places of your website. Logic is simple – as in any modern system, blocks are every piece of independent content or functionality that can change positions within regions of the website.
After initial install, Drupal comes with default Bartik Drupal theme – these are the active regions where you can place blocks.
Therefore, when you speak about layout, templates and designs with the client, it’s handy if you imagine all website components in reusable block regions with the corresponding features.
For example, latest news block will be shown in the right sidebar, only for first page, where as the news section will show a calendar of events, or functionalities alike. Most importantly, you have to know that blocks have the following default set of visibility settings options to your help:
Blocks core visibility settings – these are the logical rules you can use out of the box
- Region settings – where the block will appear;
- Pages visibility – on which pages does the block appear, and on which – not;
- Content types visibility – on which content types does the block appear, and on which – not;
- Roles visibility – for which roles does the block appear, and for which – not;
Once you understand the blocks management concept in Drupal, you’ll be seeing how templates are actually built in Drupal
- template files with code defining regions in the Drupal theme;
- set of rules which blocks are shown where; (in which regions)
- set of rules to turn on/off a given set of blocks on specific pages;
- set of rules to turn on/off a given set of blocks on specific content types;
- any other set of rules with conditions to hide/display blocks in set regions;
Context module in Drupal is helping you greatly to set these rules and output depending on various rules.
Public profile template example
- Layout contains site-general header, footer and content body areas;
- Public profile template includes right sidebar;
- In the right sidebar, there are several widgets in the following order and features
- About – short bio about the person
- Friends – box with pictures of this person’s relationships
- Favorites – box with list of links that the user has liked on the website
- Relevant products – box with products that are relevant to the user
- Right sidebar is visible only for authenticated users.
- Right sidebar is removed when the profile is viewed by anonymous user
How does this specification requirement translate to the language of Drupal configurations
- Use site-general template
- There is a set of contextual conditions for showing and hiding blocks in the right side – we’ll use Context module
- A single context configuration is created, with the list of desired blocks
- conditions for the context to appear:
- user role visibility: authenticated users can see this
- page visibility: page of a user is viewed
- all conditions have to be met in order for the layout to work
- conditions for the context to appear:
And it’s actually pretty simple – you don’t need 2 templates. You need only 1 template, with a right sidebar block region, where the block gets shown based on visibility settings.
In almost all projects, you can start templates definition with several quite common templates:
- Home page template – the home page! 🙂
- Article internal page template – how articles look in full view;
- Articles dynamic section with list of latest items – usually a thumbnail and an excerpt;
- Contacts page;
- Others …
If you can define what blocks are needed for which pages of your website, and how they show/hide, you’re most probably already good enough describing your project’s templates in a Drupal way.
Yet another tricky component in your specifications.
If you want, skip all the rest, but please take note – never assume!
Assumptions during project and functional specifications are killers, because very frequently people assume that if open source system X has feature A, then system Y will have the same feature A. This is not the case. Systems’ architectures vary. So give your best to learn a bit about the system you write specification for, and try to stick to native functionalities through core and contributed modules, when possible.
It’s really hard to categorize functionalities you can achieve out of the box. The outcomes you achieve with modules vary. So, from my experience, I divide modules into 2 very broad categories:
- popular modules you can trust and work on a daily basis, with predictable results, and
- not-so popular modules you have to first test before promising.
Surely enough, if we speak full custom development, story is different.
What you can specify about functionalities, however, is what input you provide for the given functionality, and what is the expected outcome. Don’t let functionalities just pop-up in your project without clear sense why they exist, and how the client will work with them. Simply put, think about, and analyze needs well, before you promise a feature.
Users and permissions
It makes sense to specify the people that will be using your website – their roles, permissions and workflows.
By default, Drupal comes with 2 roles: anonymous users, and authenticated users.
Anonymous users, or non-authenticated users, browse the website without logging in. Whereas authenticated users are those who have provided credentials to log in to the system. This usually includes additional privileges assigned to the user, so that he can do more things with and on your website.
Drupal has very granular permissions settings. You can use the system’s logic about specifying your features vs roles and permissions to define them in your specification. It could be as simple as making a table with a CRUD rules vs your website’s roles and functionalities.
For example, you have a website with 2 additional roles for site administrators and assistance. Both types of users will see only limited administration functionalities so to work comfortably with the website. In this example case, site administrators will have a bit extended permissions to manage all content, whereas assistants will be able to only upload and edit their own content.
|Feature / Functionality||Anonymous users||Authenticated users||Assistant||Site admin|
|Create new content of type News||+||+|
|Edit own content of type News||+||+|
|Delete own content of type News||+||+|
|Edit any content of type News||+|
|Delete any content of type News||+|
Drupal is a complex system, and it has many specifics. The more you know about the system, the better you’ll be in writing functional documentation. You can even prepare a simple base Drupal core install on your computer so you can quickly test things there. Eventually, you’ll grow more aware of generic functionalities’ options, and the quality and functions of any modules you like. Next, you can download a sample specification template for a Drupal-based website with comments coming from this blog post.
Download a specification template for a Drupal website