The focus will be on how we made the integration possible, thus managing to minimize our backend development efforts by adopting an MVC approach to WordPress theme development using the Timber framework, the Advanced Custom Fields (ACF) plugin and some magic.
General Context and Motivation
We’ve been working with WordPress for the past 9 years and we love it. We love the technology, the ease of use and flexibility that WordPress offers and the great community and large ecosystem around it.
Just as well, we also love to focus on technical challenges and come up with solutions in order to provide high quality and modern applications to our clients. Like in any line of work we often find ourselves doing repetitive work while implementing similar features for different projects in order to get the job done. Since this is far from ideal, we started searching for a more efficient approach in which the less challenging but time consuming work takes as little time to implement as possible.
It quickly became clear that we needed to automate some of the things we do on a daily basis. Our goal was to allow our backend developers to focus on the truly demanding and business critical features, deliver faster results our clients can benefit from. This approach would help our company scale out and take on more projects without compromising quality.
While analyzing the problem we decided that building theme templates was the area we could optimize the most with automation. Up until now, our backend developers had to basically do the same work over and over again, in this phase of the project. It was nothing very complicated or fancy but it took time and we had no way around it.
We were already using the Advanced Custom Fields (ACF) plugin to create custom fields. When doing this we also had to query each field in the database in order to get the information we needed and have our backend developers write minimal markup before sending anything to our frontend developers. We realized that using a Model-View-Controller (MVC) approach for creating our WordPress themes would enable us to easily export the fields automatically in order to minimize the backend development work. The MVC design pattern decouples these major components allowing for efficient code reuse and parallel development.
To do this we used the Timber plugin together with ACF and wrote our own plugin that acts as glue code linking the two together. Timber provides a faster, easier and more powerful way to build themes. It helps you create fully-customized WordPress themes faster with more sustainable code. Timber uses Twig, a modern PHP templating engine, and our plugin automatically exports the templating information into Twig. With Timber we can write our markup using Twig, separate from our PHP files. This cleans up the theme code so that the PHP code can focus on the data / logic, while the Twig files can focus only on the HTML and display. With this approach we got rid of all spaghetti code and the logic is separated from the presentation layer.
This way the frontend is more decoupled so frontend and backend developers are less dependent of one another. This also brings more structure to our projects and reduces the code complexity thanks to the nature of the MVC pattern. Our backend developers only work in the Controller, which holds the index.php file and all the logic. Frontend developers only deal with the View, where all the Twig templates containing the markup are held. The database along with some WordPress components represent the Model of the architecture.
Normally, backend developers create and configure the ACF fields manually and then query all the necessary data and append it to the context variable. Content managers aren’t involved in this phase and in anything related to the website’s structure, they simply add and manage content. Only after this is done, the frontend developer comes into play and uses the data from the context variable in the Twig template, creates the markup and styles it according to the design. This creates some friction as the backend developer, frontend developer and content manager depend on each other and cannot work simultaneously and independently, thus slowing down the development workflow.
In our approach we’re trying to remove the backend developer from this equation. To do this we automatically map all the ACF fields defined into the Twig context variable.
Timber has objects defined for each WordPress entity, such as Posts, Pages and Custom Post Types mapped as Timber\Post, Categories, Tags and Custom Taxonomies mapped as Timber\Term, Image and Gallery mapped as Timber\Images, and User mapped Timber\User. Before a Timber object is instantiated we go through all the defined fields and verify if they apply to the current object. On the Timber object we add a new key called fields, where all the fields that match the criteria for that object are appended. All the fields added as theme options are stored on a special key called options.
The downside is that while you are processing the fields for a certain object type you need to go through all the field groups defined in ACF. This can impact the performance of your website if you are dealing with a large number of fields. To avoid this we had to implement a field caching system that stores the IDs of the fields for each WordPress entity.
Another challenge we faced was related to avoiding infinite loops when retrieving the field information. If Post A has a reference to Post B and Post B has a reference back to Post A, there is no way of exiting the query. To avoid this we append an empty array instead of the actual object if the object is already appended to the data variable.
Timber, Twig and ACF are all open-source projects and their code is publicly available. They are all stable, well tested projects with a community backing them. The fact that we can see the code and understand what it does, enabled us to create a stable plugin that integrates seamlessly and acts like a bridge between them.
Most high-level frameworks like Ruby on Rails, Spring, ASP.NET or Drupal are modeled after an MVC pattern. WordPress however is not but thanks to Timber we can now have the same decoupling and flexibility as we would normally have with other, high-level frameworks. Our plugin allows for further automation and helps backend developers work in a more efficient way.
WordPress will not become an MVC framework in the foreseeable future because the goal has always been not to break compatibility with older versions of its platform.
Content managers actually have more work to do with this approach, but they receive more control and it’s easier for them to create and configure everything by themselves and not depend on backend developers. From a business perspective it’s also easier to scale your team simply by onboarding more content editors and frontend developers, without the need to also grow on the backend.
While we have seen significant results on small to medium projects, the gains are diminished when working on larger projects. We would not recommend you having this approach on larger projects since you might also see a decrease in performance when having to process a very large number of fields.
Our colleagues Dani and Mircea pitched the idea and have been working on this, in between projects, for the past months. In total they’ve spent almost 100 hours of designing and implementing the plugin and we have already started to use it in production in our latest projects.
All that’s left is to come up with a name, write the documentation for our plugin and we can release it publicly so that the WordPress community can use it. We hope to launch it by the end of the year. So far Mircea has been hard at play in presenting our idea at WordCamp in Bern and WordCamp in Bucharest, where we received positive feedback. Next up is our local WordPress Meetup in Timișoara, where Mircea will hit the stage again.
Further development of the plugin is fairly limited. It’s scope was clear from the start, and it’s already doing what we intended it to do. We’ll have to do minor development when ACF launches new field types, so that we can support those as well, but that’s it.
Outcome and Impact
We have already started to use our plugin in our latest projects and we can say that it meets our expectations and works like a charm. The impact that this has brought to our organization can be summed up in these simple points:
- Our backend developers are more motivated and can focus on more challenging tasks;
- We are able to deliver faster results to our clients and our development process has become more agile;
- We streamlined our workflow, by decoupling frontend, backend and content;
- Frontend and backend developers can work in parallel;
- We involve content editors in the development process and give them more control over the data structures;
- We give back to the WordPress community and help other developers;
Looking forward for the launch and in the meantime feel free to send us your questions or even ideas and check out Mircea’s presentation from WordCamp in Bern and WordCamp in Bucharest for some code samples and a more in-depth technical walkthrough of our implementation.