search
HomeBackend DevelopmentPHP TutorialBuilding a Simple Grav CMS Theme with Twig, PHP, and CSS

This article first appeared on Symfony Station.

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

Introduction

If you're reading this you know building content-oriented websites today is an overcomplicated clusterfuck.

But there is a content management system that makes it easier and simpler. And this is especially true for frontend developers. It's Grav CMS.

I'm going to customize a theme for grav.mobileatom.net which is my main business site. Guess what? It won't involve any AI.

And writing this article is going to be my way to learn how to do it plus help the community. You don't see many articles about Grav.

We're going to cover:

(1) Organization / file structure
(2) Twig templates
(3) CSS
(4) Twig functionality
(5) Customization

If you don't know, GravCMS is one of the many CMSs based on Symfony.

The technical details of this article are mostly paraphrased from the Grav documentation. As I just said, I'm learning this myself.

Grav says:

"The core of Grav is built around the concept of folders and markdown files for content. These folders and files are automatically compiled into HTML and cached for performance.

Its pages are accessible via URLs that directly relate to the folder structure that underpins the whole CMS. By rendering the pages with Twig Templates, you have complete control over how your site looks, with virtually no limitations."

Alright, let's take a look at themes.

Grav themes

Themes in Grav are built with Twig templates and you can learn much more about Twig in my article, Twig: The Ultimate Guide to the Premier PHP Templating Language. Plus, we will go into some details here.

As I wrote there, Twig is a PHP templating language that outputs variables into the HTML of views in MVC (models, views, controllers) programming. So, it contributes to the structure of your website's frontend.

It was created by Fabien Ponticier who also created Symfony, thus it's no surprise it's used in Grav.

He noted that "a template language is something that helps you to write templates that respect this (MVC) separation of concerns. A template language should find a good balance between giving enough features to ease implementing the presentation logic and restricting the advanced features to avoid having the business logic cripple your templates."

What exactly are PHP templates? As noted above, they are used to separate the view of your PHP application from its models and objects.

Twig's key features are that it's:

  • Fast: Twig compiles templates down to plain optimized PHP code. The overhead compared to regular PHP code was reduced to the very minimum.
  • Secure: Twig has a sandbox mode to evaluate untrusted template code. This mode allows Twig to be used as a template language for applications where users modify the template design.
  • Flexible: Twig is powered by a flexible lexer and parser. This flexibility allows the developer to define custom tags and filters (more about those later) and create their unique DSL.

A few final quick notes:

  • Twig Template names end with .html.twig.
  • You configure them with YAML.
  • And they work well with vanilla CSS.

Each page you create in Grav via the admin interface references a Twig template file. A best practice is to match template file names to page names as much as possible. Or at least your content files' folder structure.

For example, blog.md would render with the Twig template blog.html.twig

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

(1) Organization / file structure

Ok, let's look at how a Grav theme is structured.

Each theme has a definition file named blueprints.yaml. It can also provide form definitions for the admin panel.

To use theme definition options, provide default settings in a your_theme_name.yaml file.

Include a 303x300 jpg named thumbnail.jpg in the theme root.

(2) Twig Templates and more

Your Grav page's Twig templates should be in a templates/ folder with subfolders for:

  • forms/
  • modular/
  • partials/

A best practice is to develop your theme in conjecture with your content. This strategy is one of the reasons why I'm so invested with Grav. Page files = Twig templates.

Again, default.md, blog.md, error.md, item.md, modular.md would equate to default.html.twig, blog.html.twig, etc.

Your theme needs a css/ folder for your CSS.

Add images/, fonts/, and js/ folders to your root as well for storing custom assets.

A blueprints/ folder will house the file with your form definitions as mentioned earlier.

Plugins are brought into Grav themes via hooks.

So, your_theme_name.php will house your non-Twig logic.

Just FYI, if you want to build a commercial theme to sell to others you will also need these files:

  • CHANGELOG.md
  • LICENSE.md
  • README.md
  • screenshot.jpg
  • thumbnail.jpg

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

A Base Template

You could get my with just a default Twig template with Grav.

But, it's better to use the Twig Extends tag to define a base layout via blocks in a base template. This file is stored in the partials/ subfolder as base.html.twig. See the image above.

In your default and other specialized templates use the extends tag to pull in your base layout from base.html.twig.

So, for your default.html.twig file using Twig syntax you would code:

{% extends 'partials/base.html.twig'%}

{%block content %}
  {{page.content | raw}}
{%endblock%}

The first set of code extends the base template which contains your base layout.

The second overides the content from the base template with your new template's code.

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

(3) Theme CSS

Next let's look at the CSS for your Grav theme. There are several ways to implement it including SCSS. But, in the vein of keeping it simple I will focus on vanilla CSS. It's short. Add a custom.css file and go to town.
Building a Simple Grav CMS Theme with Twig, PHP, and CSS

(4) Twig Functionality

Let's also take a quick look at how Twig works.

Twig tags like Extend control the logic of your templates. They tell Twig what to do. IMHO, Block is the most important tag.

Others include:

  • cache
  • markdown
  • script
  • style
  • switch
  • etc

Twig filters are useful for formatting and manipulating text and variables.

They include:

  • date
  • escape
  • join
  • lower
  • slice
  • etc

Functions can generate content and implement functionality (obviously). They can also do some of the same things filters can do.

So, for your templates use the Twig tags, filters, and functions required for your unique needs.

Grav's Twig tags

In addition to your the tags you choose, Grav includes custom Twig tags to extend its capabilities.

They include:

  • markdown
  • script (you can pull in JavaScript for example)
  • style
  • link
  • switch
  • deferred (loading of assets)
  • throw (exceptions)
  • try/catch
  • render (flex objects)
  • cache

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

Theme Configuration

With Grav you can access theme configuration and blueprints information from your Twig and PHP files. You can do this via theme objects or you can use a Grav plugin with PHP syntax.

As a best practice, don't change your theme's default your_theme_name.yaml file (see image above). Override it in a user/config/themes folder.

As a final note, Twig also has custom objects and variables which we won't discuss here. Remember, I'm keeping it simple.

Building a Simple Grav CMS Theme with Twig, PHP, and CSS

Asset Manager

Grav's Asset Manager provides a flexible way to manage CSS and JavaScript files. It includes an Asset Pipeline to minify, compress, and inline assets.

It's available and can be accessed in plugin event hooks or directly in themes via Twig calls. It has its own configuration file in user/config/system.yaml.

You can get enterprise-level granular with Asset Manager so we won't cover in any greater detail here.

In the vein of keeping it simple, I recommend using the Assets plugin (see image above). Download it from the Grav admin. Then use it to update or add assets as needed.

(5) Customization

So, we're covered the way to build a quick and simple Grav Theme. Set up your structure, build your Twig templates, and add CSS and JavaScript as needed.

And you have seen there are a variety of ways for making a Grav theme meet your simple or complex needs, but Grav provides features and functionality to make it even easier. And it's the way I'm going to customize my site's theme.

Theme Inheritance

That easier way is to use theme inheritance. I like this because it's similar to what I have done with WordPress and Drupal themes.

It's also Grav's preferred way to customize a theme.

You define a base theme that your are inheriting from. For example the default theme Quark or one you've bought. Then you add or edit what you want customized and let the base theme handle the rest.

This strategy also let's you update the base theme without losing the customizations of your inheritance theme.

There are several ways to create an inheritance theme. But again in the interest of simplicity, let's look at the manual process.

Create a new folder -> user/themes/your_theme_name to hold the custom theme.

Then copy the YAML file from the theme you will be inheriting from into the new folder. Name it your_theme_name.yaml and switch the new theme name wherever you see Quark.

Next, copy the users/themes/quark/blueprint.yaml file into your user/themes/your_theme_name folder.

Now, change the default theme in the user/config/system.yaml file.

pages:
theme : your_theme_name

Finally, to add advanced event-driven functionality, create a user/themes/your_theme_name/your_theme_name.php file.

{% extends 'partials/base.html.twig'%}

{%block content %}
  {{page.content | raw}}
{%endblock%}

You have now set up Grav's streams so that it looks in your_theme_name first, then tries Quark.

Now, provide the CSS, JS, and Twig template modifications you require.

You're done. Fairly simply.

Conclusion

Wow. Thanks for reading the entire article.

You now know more about Grav themes':

(1) Organization / file structure
(2) Twig templates
(3) CSS
(4) Twig functionality
(5) Customization

Consider using Grav for its simplicity, especially when customizing themes. What's not to love about PHP, Twig, vanilla CSS and JS. You even create your content in markdown.

Keep coding Symfonistas and Gravinauts!

Resources

https://learn.getgrav.org/17/themes

https://twig.symfony.com/

https://twig.symfony.com/doc/3.x/

https://www.drupal.org/docs/contributed-modules/twig-tweak-2x/cheat-sheet

The above is the detailed content of Building a Simple Grav CMS Theme with Twig, PHP, and CSS. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Working with Flash Session Data in LaravelWorking with Flash Session Data in LaravelMar 12, 2025 pm 05:08 PM

Laravel simplifies handling temporary session data using its intuitive flash methods. This is perfect for displaying brief messages, alerts, or notifications within your application. Data persists only for the subsequent request by default: $request-

PHP Logging: Best Practices for PHP Log AnalysisPHP Logging: Best Practices for PHP Log AnalysisMar 10, 2025 pm 02:32 PM

PHP logging is essential for monitoring and debugging web applications, as well as capturing critical events, errors, and runtime behavior. It provides valuable insights into system performance, helps identify issues, and supports faster troubleshoot

cURL in PHP: How to Use the PHP cURL Extension in REST APIscURL in PHP: How to Use the PHP cURL Extension in REST APIsMar 14, 2025 am 11:42 AM

The PHP Client URL (cURL) extension is a powerful tool for developers, enabling seamless interaction with remote servers and REST APIs. By leveraging libcurl, a well-respected multi-protocol file transfer library, PHP cURL facilitates efficient execution of various network protocols, including HTTP, HTTPS, and FTP. This extension offers granular control over HTTP requests, supports multiple concurrent operations, and provides built-in security features.

Simplified HTTP Response Mocking in Laravel TestsSimplified HTTP Response Mocking in Laravel TestsMar 12, 2025 pm 05:09 PM

Laravel provides concise HTTP response simulation syntax, simplifying HTTP interaction testing. This approach significantly reduces code redundancy while making your test simulation more intuitive. The basic implementation provides a variety of response type shortcuts: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

12 Best PHP Chat Scripts on CodeCanyon12 Best PHP Chat Scripts on CodeCanyonMar 13, 2025 pm 12:08 PM

Do you want to provide real-time, instant solutions to your customers' most pressing problems? Live chat lets you have real-time conversations with customers and resolve their problems instantly. It allows you to provide faster service to your custom

Explain the concept of late static binding in PHP.Explain the concept of late static binding in PHP.Mar 21, 2025 pm 01:33 PM

Article discusses late static binding (LSB) in PHP, introduced in PHP 5.3, allowing runtime resolution of static method calls for more flexible inheritance.Main issue: LSB vs. traditional polymorphism; LSB's practical applications and potential perfo

Customizing/Extending Frameworks: How to add custom functionality.Customizing/Extending Frameworks: How to add custom functionality.Mar 28, 2025 pm 05:12 PM

The article discusses adding custom functionality to frameworks, focusing on understanding architecture, identifying extension points, and best practices for integration and debugging.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
3 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor