Grav Twig Debugging — Dump, Debug Bar and Variable Inspection
In this tutorial, you'll learn Grav Twig debugging techniques — using the dump function, enabling the debug bar, inspecting template variables, leveraging the DevTools plugin, and troubleshooting common template errors.
What You'll Learn
- The
{{ dump() }}function for variable inspection - Grav's debug bar and what it shows
- The DevTools plugin for development
- Enabling Twig errors and error reporting
- Debugging template inheritance and block resolution
- Performance debugging: template render times, cache hits
Why It Matters
Every developer writes incorrect template code at some point — a variable that doesn't exist, a filter that's misspelled, a block that isn't being overridden. In WordPress, you might var_dump() in PHP or use Query Monitor. In Grav, Twig debugging tools show you exactly what variables are available, which templates are being used, how long each template takes to render, and what configuration values are active. Without these tools, you're guessing.
Real-World Use
A developer is building a custom Grav theme and a template shows blank content. Using {{ dump(page) }}, they discover that page.collection is empty because the frontmatter collection definition uses @self.children but the page has no children. The dump() output reveals the missing data immediately, turning a 30-minute debugging session into a 30-second fix.
Learning Path
flowchart LR
A["Twig Inheritance"] --> B["Twig Debugging
← You are here"]:::current
B --> C["Custom Twig Extensions"]
C --> D["Theme Configuration"]
D --> E["Theme Assets"]
E --> F["Theme Inheritance"]
classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px
Dumping Variables
The {{ dump() }} function outputs a structured view of any variable:
{{ dump(page) }}
This shows all properties of the page object: title, content, header, children, parent, url, collection, taxonomy, and more.
Dump Specific Fields
{{ dump(page.title) }}
{{ dump(page.header) }}
{{ dump(page.children) }}
{{ dump(page.collection) }}
{{ dump(config.site) }}
Dump All Variables
{{ dump(_context) }}
The _context variable is a special Twig variable that contains all variables available in the current template context. This is the most comprehensive dump.
Dump with Labels
{{ dump(page, 'Page Object') }}
{{ dump(page.header.taxonomy, 'Taxonomy Data') }}
Enabling the Debug Bar
Grav has a built-in debug bar powered by PHP Debug Bar. Enable it in user/config/system.yaml:
system:
debugger:
enabled: true
twig: true
What the Debug Bar Shows
After enabling, a debug bar appears at the bottom of every page (admin users only by default):
- Request tab: Current route, method, and parameters
- Configuration tab: All Grav configuration values
- Timeline tab: Event timing and template render times
- Twig tab: Template names and render times
- Cache tab: Cache hits and misses
- Messages tab: Debug messages and notices
Twig Tab Details
The Twig tab shows:
Template Render Time
--------------------------------------------
partials/base.html.twig 1.2ms
default.html.twig 0.8ms
partials/header.html.twig 0.3ms
partials/footer.html.twig 0.2ms
This reveals which template is the slowest, helping you optimize render performance.
DevTools Plugin
The DevTools plugin provides additional debugging capabilities:
bin/gpm install devtools
DevTools Features
- Twig variable inspector: Shows all variables available in the current template context with their types and values
- Template suggestions: Shows which templates Grav considered and which one was selected
- YAML validator: Validates frontmatter YAML syntax
- Performance profiler: Detailed timing of Grav events and plugins
Enable DevTools
# user/config/plugins/devtools.yaml
enabled: true
twig: true
profiler: true
Debugging Template Inheritance
When a template is not being used as expected, enable Twig debugging to see template resolution:
# user/config/system.yaml
twig:
cache: false
debug: true
Then add to your page:
{# List all template suggestions for this page #}
{# Available only with DevTools plugin #}
{{ dump(page.template()) }}
Debugging Configuration Values
{# Check if a plugin is enabled #}
{{ dump(config.plugins.email.enabled) }}
{# Check site configuration #}
{{ dump(config.site.title) }}
{{ dump(config.site.author) }}
{# List all plugins #}
{{ dump(grav.config.plugins) }}
Debugging Collections
{# Count collection items #}
Collection has {{ page.collection|length }} items.
{# Dump first item #}
{% if page.collection|length > 0 %}
{{ dump(page.collection|first) }}
{% endif %}
{# List all item titles #}
{% for item in page.collection %}
{{ item.title }} ({{ item.url }})
{% endfor %}
Debugging Assets
{# List all registered CSS assets #}
{{ dump(grav.assets.css()) }}
{# List all registered JS assets #}
{{ dump(grav.assets.js()) }}
Error Reporting
Enable detailed error messages in development:
# user/config/system.yaml
twig:
autoescape: true
auto_reload: true
cache: false
debug: true
system:
debugger:
enabled: true
strict: true
With strict: true, Grav shows Twig errors with full backtraces instead of blank pages.
Common Twig Errors
Variable does not exist:
Twig_Error_Runtime: Variable "nonexistent" does not exist.
Fix: Check the variable name or use default('fallback').
Template not found:
Twig_Error_Loader: Unable to find template "partials/missing.html.twig".
Fix: Verify the file path relative to the templates/ directory.
Filter does not exist:
Twig_Error_Syntax: The filter "nonexistent" does not exist.
Fix: Check the filter spelling or install the plugin that provides it.
Performance Debugging
Template Render Times
Add timing markers to identify slow templates:
{% set start = time() %}
{# Your template content here #}
<!-- Template rendered in {{ (time() - start) * 1000 }}ms -->
Cache Debugging
Check if a page is served from cache:
{# Add to base template #}
<!-- Cache key: {{ grav.cache.getKey() }} -->
<!-- Cached: {{ grav.cache.getCacheStatus() ? 'yes' : 'no' }} -->
Logging Debug Messages
{# Log a message (available with Debugger plugin) #}
{% do grav.debugger.addMessage('Custom debug message') %}
Learning Path
flowchart LR
A["Twig Inheritance"] --> B["Twig Debugging
← You are here"]:::current
B --> C["Custom Twig Extensions"]
C --> D["Theme Configuration"]
D --> E["Theme Assets"]
classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px
Common Mistakes
Leaving debug tools enabled in production: The debug bar and Twig debug mode expose sensitive information. Always disable them in production by setting
debugger.enabled: falseandtwig.debug: false.Dumping without checking if the variable exists:
{{ dump(page.collection) }}shows an error ifpage.collectiondoes not exist. Use a conditional or|default(null)before dumping.Confusing
dump()withprint()in Twig:dump()outputs structured debug data with types.{{ page.title }}renders the value. They serve different purposes.Not clearing cache after enabling debug: Twig debug settings require cache clearing to take effect. Run
bin/grav cache --clearafter changing debug configuration.Using
var_dump()in PHP instead of Twigdump(): If you are debugging Twig templates, use{{ dump() }}in the template.var_dump()in PHP files prints before the HTML response and breaks the layout.
Practice Questions
How do you view all available variables in a Twig template? Answer: Use
{{ dump(_context) }}. The_contextvariable contains every variable accessible in the current template scope.What configuration enables Grav's debug bar? Answer: Set
system.debugger.enabled: trueinuser/config/system.yaml. For Twig-specific debugging, also settwig.debug: true.How do you check if a collection returns any items? Answer: Use
{{ page.collection|length }}to count items, or{% if page.collection|length > 0 %}to conditionally check.What is the difference between
twig.cache: falseandsystem.cache.enabled: false? Answer:twig.cache: falsedisables Twig template Caching only (templates recompile on every request).system.cache.enabled: falsedisables all Grav caching.Challenge: Debug a complex template that renders a blog listing page. The blog page shows no content. Use
dump()to inspect the page object, the collection, the frontmatter configuration, and the available template variables. Identify which variable is empty and trace the root cause through the template inheritance chain. Document each debugging step and the fix applied.
FAQ
Mini Project
Goal: Debug and optimize a Grav template with performance issues.
- Enable the debug bar and Twig debug mode
- Create a template that intentionally has errors: missing variable, wrong filter name, incorrect block name
- Use
{{ dump() }}to identify each error and fix it - Use the debug bar's Timeline tab to identify the slowest template
- Use
{{ dump(_context) }}to list all available variables - Profile the page before and after enabling Twig cache
- Log custom debug messages using
grav.debugger.addMessage() - Disable all debug tools and verify the page renders cleanly
- Create a development-only configuration that enables debug tools
- Document the debugging workflow for future reference
What's Next
Now you can debug any template issue. Next, learn to extend Twig with custom filters and functions:
Continue to Lesson 19: Custom Twig Extensions — Register custom filters, functions, and tests in Grav plugins.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro