Reserved Words in Grav

I’m studying the documentation and trying to learn Grav and Twig. Please bear with me, there are some things I’m not able to figure out on my own. One thing I’m having difficulty with is that I come from a language where all variables or objects must be declared and defined before they are used. Twig, obviously, isn’t that way. Take this code fragment for instance – code sample borrowed from the documentation:

{% for image in page.media.images %}
    <li>
        <div class="image-surround">
            {{ image.cropResize(300,200).html|raw }}
        </div>
        <div class="image-info">
            <h2>{{ image.meta.title }}</h2>
            <p>{{ image.meta.description }}</p>
        </div>
    </li>
{% endfor %}

“page.media.images” is a collection of images in all of a given group of pages, right? “image” is an object created just by using it. Then in each iteration the object is reused and set with the next set of data. and output. That seems straightforward enough…

But there are other objects that are not so obvious where it’s getting the data from and how it knows where to go to get the data. Here’s an example that is not so difficult to figure out:

In some config file…

dropdown:
   -  enabled: true

(but where is the file and how does Twig know where to find it?)

then you reference it in a twig file:

{% if config.plugins.dropdown.enabled %}
  .....
{% endif %}

So the word “dropdown” is declared in the config file, right? Otherwise it would throw and error on the line with the “if” statement. In otherwords, “dropdown” never existed before it was typed into the .yaml config file, right?

But in the case of “page.media.images” these are reserved words of Grav, right?

I have to guess a lot of these things by studying the code, since I have no way to test my theories. There are a lot of other words that are hard to figure out where they come from, why they exist and what they do. Is there a list of reserved words in Grav and what they do and/or where they come from?

So we have this directory structure with config files in them:

/user/accounts
/user/blueprints
/user/config
/user/data
/user/images
/user/languages
/user/pages
/user/plugins
/user/themes

So “config.plugins.breadcrumbs.enabled”, for example, would be defined in a .yaml file in the folder “/user/plugins” ? Or where?

I’ve read the documentation, but I’m still having difficulty figuring out how this all works…

@dpdoug,

“page.media.images” is a collection of images in all of a given group of pages, right?

Considering the name of variable “page”, I guess it points at only a single page and not a “given group of pages”

{% if config.plugins.dropdown.enabled %}
....
{% endif %}

So the word “dropdown” is declared in the config file, right? Otherwise it would throw and error on the line with the “if” statement. In otherwords, “dropdown” never existed before it was typed into the .yaml config file, right?

Yes, the word “dropdown” is declared in the config file. But no error will be thrown by Twig. Twig silently ignores it by returning null.

Note, that config.plugins.dropdown.enabled is probably incorrect. The syntax should be: config.themes.themeName.variableName or config.plugins.pluginName.variableName

I have to guess a lot of these things by studying the code, since I have no way to test my theories.

You could use {{ dump(variable) }} and watch the output in the Clockwork tab in the console of the browser.

Is there a list of reserved words in Grav and what they do and/or where they come from?

Have a look at the docs Theme Variables + Twig Filters + Twig Functions for a list of predefined variables, filters and functions.

Apart from that, any theme/plugin can add variables/filters/functions into Twig’s namespace.

@dpdoug,

So “config.plugins.breadcrumbs.enabled”, for example, would be defined in a .yaml file in the folder “/user/plugins” ? Or where?

Not quite… The default value of variable config.plugins.breadcrumbs.enabled would be defined in file “breadcrumbs.yaml” inside folder “/user/plugins/breadcrumbs”.

The default value can be overridden in:

  • “user/config/plugins/breadcrumbs.yaml”,
  • which in turn can be overridden by “/user/env/[domainname]/config/plugins/breadcrumbs.yaml”. See Environment Configuration

By the way, when you {{ dump(config) }}, you will see that variable config only contains configuration data. Info collected from /user/[themes|plugins]/*/*,yaml, /user/config/**/*.yaml and /user/env/[domain]/config/**/*.yaml.

Array(1) object: Grav\Common\Config\Config
* object: Grav\Common\Config\Config
  * *gettersVariable: "items"
  * *items: Array(13)
    * themes: Array(1)
    * plugins: Array(9)
    * backups: Array(2)
    * media: Array(1)
    * mime: Array(1)
    * permissions: Array(2)
    * security: Array(7)
    * site: Array(9)
    * system: Array(30)
    * versions: Array(1)
    * streams: Array(1)
    * environment: "dev-dev"
    * theme: Array(10)

Variable grav on the other hand, contains broader information from multiple sources, like config, accounts, pages, etc.

Array(1) object: Grav\Common\Grav
* object: Grav\Common\Grav
  * ~values: Array(51)
    * loader: Composer\Autoload\ClassLoader
    * debugger: Grav\Common\Debugger
    * grav: anonymous function
    * permissions: anonymous function
    * accounts: Grav\Common\User\DataUser\UserCollection
    * user_groups: anonymous function
    * users: anonymous function
    * assets: Grav\Common\Assets
    * backups: Grav\Common\Backup\Backups
    * setup: Grav\Common\Config\Setup
    * blueprints: Grav\Common\Data\BlueprintSchema
    * config: Grav\Common\Config\Config
    * mime: anonymous function
    * languages: Grav\Common\Config\Languages
    * language: Grav\Common\Language\Language
    * errors: Grav\Common\Errors\Errors
    * filesystem: anonymous function
    * flex: Grav\Framework\Flex\Flex
    * inflector: Grav\Common\Inflector
    * log: Monolog\Logger
    * output: anonymous function
    * pages: Grav\Common\Page\Pages
    * page: Grav\Common\Page\Page
    * request: Nyholm\Psr7\ServerRequest
    * route: anonymous function
    * session: Grav\Common\Session
    * messages: Grav\Framework\Session\Messages
    * locator: RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator
    * streams: RocketTheme\Toolbox\StreamWrapper\StreamBuilder
    * task: null
    * action: null
    * browser: Grav\Common\Browser
    * cache: Grav\Common\Cache
    * events: Symfony\Component\EventDispatcher\EventDispatcher
    * exif: anonymous function
    * plugins: Grav\Common\Plugins
    * scheduler: Grav\Common\Scheduler\Scheduler
    * taxonomy: Grav\Common\Taxonomy
    * themes: Grav\Common\Themes
    * twig: Grav\Common\Twig\Twig
    * uri: Grav\Common\Uri
    * clockwork: Clockwork\Clockwork
    * flex_objects: anonymous function
    * login: Grav\Plugin\Login\Login
    * base_url_absolute: "http://dev-dev"
    * base_url_relative: ""
    * base_url: ""
    * user: Grav\Common\User\User
    * Email: Grav\Plugin\Email\Email
    * forms: Grav\Plugin\Form\Forms
    * theme: Grav\Theme\Quark