# Template variables

## `blog_page_path`

Note: Only available within blog templates currently.

Get the page path of the blog root page. Example if you have a blog under `https://www.example.com/locations/seattle/blog/` the `blog_page_path` would be `/blog/`

## `blog_root`

Note: Only available within blog templates currently.

Get the URL of the blog root page. Includes the `base_directory`. Example if you have a blog under `https://www.example.com/locations/seattle/blog/` the `blog_root` would be `/locations/seattle/blog/`

## `filter_posts`

Get blog posts for the current site based on a supplied category slug.  Note: Only available within blog templates currently.

If accessing posts outside blog templates, use `get_posts`

```html
<ul>
{% for post in filter_posts(category_slug='some-category-slug', limit=3) %}
    <li><a href="{{ post.url(**post_url_params) }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
```

## `get_breadcrumbs`

Utility to generate a list of breadcrumb links to show at the top of a page using the Page names and URLs of pages within the Site.

<figure><img src="https://825756965-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-L_zivnvKch6re2urR-L%2Fuploads%2FQnwEGieqw7GHBgJyFH9P%2FScreenshot%202025-01-22%20at%208.04.46%E2%80%AFAM.png?alt=media&#x26;token=fb143672-4443-4f0d-8a7e-545d60f98253" alt=""><figcaption><p>Example breadcrumbs on a Local site</p></figcaption></figure>

In addition to visitor display, it also includes a method to generate JSON schema (`as_schema`) for the breadcrumbs to include in the source of the page.

### Usage

Set the `get_breadcrumbs` to a variable to be used later for the HTML and Schema output.

#### Simple usage

```
{% set breadcrumbs = get_breadcrumbs() %}
```

#### `include_home` option

By default, the home page (at "/") is excluded from the Breadcrumbs. If you would like to include it in the output pass the `include_home` option.

```
{% set breadcrumbs = get_breadcrumbs(include_home=True) %}
```

#### `preprend_items` option

The breadcrumb utility will generate based on the current page and site the code is on. If you want to add additional breadcrumb links before those for the current site (for example if you want Local site breadcrumbs and Corporate level breadcrumbs), you can use the `preprend_items` option to add those additional items.

```
{% set prepend_items = [
    {
       'link': '/locations/',
       'name': 'Locations'
    },
    {
       'link': '/locations/' + primary_location.state_name|slugify + '/',
       'name': primary_location.state_name,
    },
    {
       'link': site.base_directory,
       'name': primary_location.location_name,
    }
] %}
{% set breadcrumbs = get_breadcrumbs(prepend_items=prepend_items) %}
```

### Template example

Using the `breadcrumbs` variable set, you can loop through the links. This example uses `loop.last` as most implementations you don't need a link to the current page and instead just show the page name.

At the end of the template is uses `as_schema`and `set_schema_overrides`to add the JSON schema to the page.

```html
<ul>
{% for item in breadcrumbs.breadcrumbs %}
    {% if loop.last %}
        <li>{{ item.name }}</li>
    {% else %}
        <li><a href="{{ item.link }}">{{ item.name }}</a></li>
    {% endif %}
{% endfor %}
</ul>
{% do set_schema_overrides('breadcrumbs', breadcrumbs.as_schema()) %}
```

## `get_categories`

Get list of all the current blog categories and links. Note: Only available within  blog templates currently.

<pre class="language-html"><code class="lang-html">{% set categories = get_categories() %}
&#x3C;ul>
<strong>{% for cat in categories %}
</strong><strong>    &#x3C;li>&#x3C;a href="{{ cat.url }}">{{ cat.name }}&#x3C;/a>&#x3C;/li>
</strong><strong>{% endfor %}
</strong><strong>&#x3C;/ul>
</strong></code></pre>

Other available category values

| Value        | Description                                      |
| ------------ | ------------------------------------------------ |
| `post_count` | Total number of posts in that category (i.e `5`) |
| `slug`       | Slug of the category (i.e. `some-category-name`) |

## `get_image`

Utility for getting additional image details from an image ID

#### Initialize the image using the ID of the image. <a href="#initialize-the-image" id="initialize-the-image"></a>

```
{% set image = get_image(12345) %}
```

If an image is coming from `custom_fields`, you can access the ID value from an image using the `field_name_id` if the normal image path would have been `field_name`

#### Get an image path by size <a href="#get-an-image-path-by-size" id="get-an-image-path-by-size"></a>

```
{{ image.by_size('thumbnail') }}
```

This will return the full path the image that you can use in CSS or image tags`/img/upload/image-name-here.thumbnail.jpg`

For a list of available sizes, see:

{% content-ref url="../site-builder/images-and-video" %}
[images-and-video](https://docs.devhub.com/site-builder/images-and-video)
{% endcontent-ref %}

## `get_menu`

Load a website menu to use for rendering the menu as a navigation

```
{% set menu = get_menu('mainmenu') %}
```

### Generating a menu tree

The menu from `get_menu` can be iterated over recursively to output a nested `ul` or other element for a navigation

```html
<ul>
{% for item in get_menu('altmenu') recursive -%}
<li style="margin-left:20px;">
  <a {% if item.link %}href="{{ item.link }}"{% endif %}>{{ item.name|safe }} {{ item.depth }}</a>
  {%- if item.children %}
    <ul>{{ loop(item) }}</ul>
  {% endif %}
</li>
{% endfor %}
</ul>
```

### Additional options

#### `root_link` option

This option allows you to filter/search and generate a partial menu for a item with link matching the `root_link`

```
get_menu('altmenu', root_link='/services/heating/')
```

This can be used to grab part of a menu to use in a sidebar or other places without the need to create a separate menu within the template.

Note: the `item.depth` will still reflect the original depth within the entire menu.

## `get_posts`

Get recent blog posts throughout Site pages.

### Simple usage

```html
{% for post in get_posts() %}
    <h2><a href="{{ post.external_url or post.link }}">{{ post.title }}</a></h2>
    <p>{{ post.date|datefmt(format='long') }}</p>
    {% if post.featured_img %}
        <p><img alt="{{ post.featured_img.alt or post.title }}" src="{{ post.featured_img.src }}" /></p>
    {% endif %}
    {% if post.excerpt %}
        <p>{{ post.excerpt }}</p>
    {% elif post.content %}
        <p>{{ post.content|striptags|truncatewords_html(75) }}</p>
    {% endif %}
{% endfor %}
```

### Limiting the number of posts to return

Default is to return 5 posts

```
{% set posts = get_posts(limit=10) %}
```

### Filtering posts by category

You will need to pass in the `category_slug`

```
{% set posts = get_posts(filters={'category_slug': 'some-category'}) %}
```

### Multiple blog roots

If your template has multiple blog root pages (Example a Blog and a Press Releases section), you will need to pass in the Page path to the blog root so that it knows what type of posts to return.

```
{% set posts = get_posts(blog_root='/press-releases/')
```

### Blog posts from a different Site

By default, `get_posts` will grab posts from the current Site. You and optionally provide a different Site ID to pull posts from.

Common use case for this is to pull Corporate blog posts into a Local site

```
{% set posts = get_posts(site_id=12345) %}
```

### Filtering recent posts by location ID

You can pass in `location_id`, `include_locationless` as filters

`{% set posts = get_posts(filters={'location_id': 12345 'include_locationless': True}) %}`

Setting `location_id` will limit posts returned to those associated with a location. `include_locationless` will include posts that are associated with the set location\_id AND posts that have no location association. `include_locationless` is only applied if a `location_id` is also provided.

## `now`

Python datetime object with properties of the current day and time.

Example of outputting the year (i.e. `2024`)

```html
<p>Copyright {{ now.year }}</p>
```

Available properties

* `now.year`
* `now.month`
* `now.day`
* `now.hour`
* `now.minute`

`strftime` can be used to format the date. Format variables available [here](https://www.programiz.com/python-programming/datetime/strftime)

Example of outputting `YYYY-MM-DD`

```
{{ now.strftime('%Y-%m-%d') }}
```

## `pages`

This utility allows you to access and filter the current Pages within a Site.

### Output all pages

```html
<ul>
{% for p in pages %}
    <li>{{ p.full_path }}</li>
{% endfor %}
</ul>
```

### Filtering pages

Example of filtering pages by template page type

```html
<ul>
{% for p in pages.filter({'custom_page_type': 'promotions'}) %}
    <li>{{ p.full_path }}</li>
{% endfor %}
</ul>
```

### Ordering pages

```html
{{ pages.filter({}, order_by='path' }}
```

### Accessing custom fields

```
{% for page in pages %}
    {{ page.custom_fields.some_value }}
{% endif %}
```

### Get a single page

```
{% set home_page = pages.get_one({'path': '/'}) %}
```

### Available page fields

Standard page fields used in templates

| Property           |                                                                                                                                                 | Example               |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| name               | Name of the current page                                                                                                                        | Home                  |
| full\_path         | Full page path which should be used for HTML links. If under a sub-directory, this path will contain the base\_directory of the Local site/page | /local-page/about-us/ |
| path               | Page path set within the Site Builder. Good for looking up a particular page using `filter` or `get_one`                                        | /about-us/            |
| custom\_page\_type | Template page type                                                                                                                              | page\_type\_example   |
| is\_published      | Boolean value if the page is currently published                                                                                                | True                  |
| is\_indexed        | Boolean value if the page is indexable. False would be returned if the Page is set to `noindex` or as a custom canonical setting on the Page    | True                  |
| custom\_fields     | Array of custom field values. Access via custom\_fields.value\_name                                                                             |                       |

## `pages.as_navigation`

Utility for easily creating multi-level navigations for headers, footers and sidebars. Its setup to do recursive looping of items to support any `depth` of page navigations

### Simple example - Full sitemap

Gets all the pages within the Site, then recursively outputs nested `<ul>` and `<li>` elements

```html
<ul>
{% for item in pages.as_navigation(
  {'is_published': True}, order_by='name') recursive -%}
<li>
  <a href="{{ item.full_path }}">{{ item.name|safe }}</a>
  {%- if item.children %}
    <ul>{{ loop(item) }}</ul>
  {% endif %}
</li>
{% endfor %}
</ul>
```

### Sidemenu example

Example of grabbing all pages based on a starting path, then outputting them with a headline. The `item.depth == 0` is used to determine it is the first parent page (`/services/`) and then the subpages (`/services/some-service/)`are output in `<ul>`

You can also add additional differences in the output based on the depth by using `item.depth`

```html
{% for item in pages.as_navigation(
  {'is_published': True, 'path__startswith': '/services/'}, order_by='name') recursive -%}

{% if item.depth == 0 %}
<div class="menu">
  <h2>{{ item.name }}</h2>
  {%- if item.children %}
  <div class="menu-items">
    <ul>{{ loop(item) }}</ul>
  </div>
  {% endif %}
</div>

{% else %}
<li>
  <a href="{{ item.full_path }}">{{ item.name|safe }}</a>
  {%- if item.children %}
    <ul>{{ loop(item) }}</ul>
  {% endif %}
</li>
{% endif %}

{% endfor %}
```

## `primary_location`

Refers to the primary (first assigned) Location to a Site

```html
<h2>Address</h2>
<p>
  {{ primary_location.street }}{% if primary_location.street2 %}{{ primary_location.street2 }}{% endif %}<br />
  {{ primary_location.city }}, {{ primary_location.state }} {{ primary_location.postal_code }}
</p>
```

If a Site does not have a Location assigned, this will return `None`

## `set_schema_overrides`

Override and extend any existing schema blocks generated by DevHub. *Note: this method will not validate the schema values you enter, so make sure you are adding valid Schema names and values to ensure Google and other search engines can properly read the schema.*

Currently supports:

* `localbusiness` - Extend or overwrite the existing [LocalBusiness schema](https://developers.google.com/search/docs/appearance/structured-data/local-business) on the local site/page

```
{% do set_schema_overrides('localbusiness', {
  'logo': 'https://www.someurl.com/logo.jpg'
}) %}
```
