Introduction
While building a website or an application, it’s often useful to control which parts are visibile (and which are not) to the actual users. Maybe you just want to hide a particular functionality on which you are still working, or maybe you just want to reveal things gradually without deploying new code in production. This concept is called Feature flags or Feature toggles.
Feature Flag is a technique to turn some functionality of your application off, via configuration, without deploying new code.
The concept of feature flags is explained really well in this article by Martin Fowler, which also explains why you shouldn’t do feature flags in the first place:
Your first choice should be to break the feature down so you can safely introduce parts of the feature into the product.
With this concept in mind let’s switch to my actual use case.
Recently I had the need to create a basic form of feature toggles inside ProcessWire, during the development of an ecommerce site. In fact in the very first phase the client wants only to showcase the products, without allowing the users to actual buy them. From a practical point of view this means, for example, hiding the “Add to cart” button and all the references to the cart (page, links and UI components).
Therefore I decided to use feature flags to hide relevant parts of the UI and functionalities that are still in development so, when the client is ready, all he needs to do is to flip a switch (or maybe two!).
Let’s dive in
ProcessWire, as always, let’s you build things really easy. Feature Flags makes no exception.
First, after logging to the panel, create a new select options field and call it with a meaningful name. Mine is called features
. In the details tab, choose Checkboxes or SelectMultiple, as we need to select multiple values. Finally define all your options/features in the multi-line text box, where each line represents one option.
Once you save, ProcessWire will assign an ID number to each option.
Next you have to add the field to a new template, which you can call it with the same name of the field. This template doesn’t need to have a file associated with it.
Finally create a new page using this template. I’m gonna call it, guess what, features
! Remember to also make it hidden from list and searches so it doesn’t sneak out in unpredictable places. From this page you can enable/disable all your features, globally for the entire site.
The code
The last thing to do is to extract the flags in our actual code, to check if the corresponding features are allowed or not. In the file that gets prepended in all the templates (usually _init.php
) insert this line to extract the features page and the corresponding features
field
<?php
$features = $pages->findOne('/features')->features;
$view->share('features', $features);
The last line is used to share the $features
variable with the view. I’m using my TemplateEngineBlade module, which allows me to separate the business code from the views.
Finally we can access the $features
variable in the view to check if each corresponding feature is enabled or disabled.
@if($features->findOne("title=feature1"))
{-- UI that should be visible --}
@endif
If feature1 if disabled the condition will be false, otherwise the check will return an instance of ProcessWire\SelectableOption.
The same code can be used to prevent the user to access a specific template, for example the cart.php
<?php
if(! $features->findOne("title=cart")) throw new Exception("Unauthorized");