> ## Documentation Index
> Fetch the complete documentation index at: https://sol.advantagelearn.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Twig

# Twig

## Twig template architecture

### Base.twig

There are a few boilerplate sections that each page needs, such as:

* meta tags, title and important scripts and styles which live in `<head></head>`
* the main div which generally sets the basic layout
* Secondary scripts and styles which are loaded below the main div
* `<footer></footer>` which contains footer links and other global information

These sections should be [blocks](https://twig.symfony.com/doc/2.x/tags/block.html) within a file called `base.twig` which all pages extend:

```php theme={null}
{% extends "base.twig" %}

{% block content %}
// Page content goes here
{% endblock %}
```

If a page needs to customize any of the other sections, then it can include those blocks as well:

```php theme={null}
{% extends "base.twig" %}

{% block header %}
// Custom header content goes here
{% endblock %}

{% block content %}
// Page content goes here
{% endblock %}
```

<aside>
  💡 The above system works in a very similar way to Vue.js slots.
</aside>

#### Adding new base files

There may be situations where you need a base file which is very different to the standard `base.twig` . Instead of hacking it to pieces by extending all the blocks, rather just create a new file, such as `base-login.twig` or `base-ecommerce.twig` and extend that in the page template instead

### Macros

[Documentation link](https://twig.symfony.com/doc/2.x/tags/macro.html)

Macros are essentially functions which spit out template partials. You can pass arguments to the macro which will then be available in the template. They help to reduce code re-use and improve readability.

```php theme={null}
{% macro textarea(name, value, rows = 10, cols = 40) %}
    <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols }}">{{ value|e }}</textarea>
{% endmacro %}
```

<aside>
  💡 You can think of macros as being similar to the base components in the common folders on the Delta LMS repo
</aside>

#### Suggested use

Create a macros folder and files to organize related macros:

```php theme={null}
- macros
	- dates.twig
	- forms.twig
	- images.twig
	- videos.twig
```

Each of these files when include macros which can be imported into templates. You can either include the whole macro file:

```php theme={null}
{% import "forms.twig" as forms %}
```

Or just the specific macros that you need:

```php theme={null}
{% from 'forms.twig' import input as input_field, textarea %}
```

### Partials

We need some way to break page templates up into smaller pieces to keep them from becoming unwieldy as the site grows. These smaller templates could be thought of as 'sections', or 'components', but I think the most accurate name is 'partials' as they are really just isolated groups of HTML that get pulled into templates. Sections fit the same definition, but a `section` is the name of a semantic HTML element so that might get a bit confusing.

<aside>
  💡 If we follow semantic HTML best practices, each partial should ideally have a `section` as the root element.
</aside>

#### Creating and including partials

A partial should be linked to a specific page. If its global, its probably better placed as a macro. Therefore to help with search, each partial should start with the name of the page its linked to, followed by an underscore and then the name of the partial, e.g `contact_form.twig`. The partial should also be stored in a `partials` folder contained within the page folder.

A partial file just contains HTML, it doesn't need any special Twig syntax. To include the partial, you add the following line wherever you want it rendered:

```php theme={null}

{% extends "base.twig" %}

{% block content %}
	{% include "/partials/contact-form.twig" %}
{% endblock %}
```

### Embeds

If your partial has slots that can be overwritten, then you can create your partial with `blocks`:

```php theme={null}
<div>
	{% block title %}
		<h1>A title</h1>
	{% endblock %}
</div>
```

Your page template could then just do a regular `include` as in the above example if it wants to just output the defaults, or it can use the `embed` keyword to change it:

```php theme={null}
{% extends "base.twig" %}

{% block content %}
	{% embed 'title_example.twig' %}
		{% block title %}
			    <h1>Edited title</h1>
		{% endblock %}
	{% endembed %}
{% endblock %}
```

<aside>
  💡 `Embed` partials become very useful when your site grows to have page templates which many pages extend rather than a one to one relationship between the page and the template
</aside>

### Full folder structure example

```php theme={null}
- templates/
	- base.twig
	- base-errors.twig
	- errors/
		- 401.twig
		- 404.twig
		- 500.twig
	- macros/
		- dates.twig
		- forms.twig
		- images.twig
		- videos.twig
	- pages/
		- about/
			- about.twig
			- partials/
				- about-header.twig
				- about-history.twig
		-contact/
			- contact.twig
			- partials/
				- contact-form.twig
				- contact-map.twig
		- home/
			- home.twig
			- partials/
				- home-header.twig
				- home-aboutus.twig


```
