<commit_before>---
title: Advanced Blueprint Features
page-toc:
  active: true
taxonomy:
    category: docs
---

There are advanced features in the blueprints which allow you to extend them and to have dynamic fields.

## Defining Validation Rules

If you need the same validation rules multiple times, you can create your own custom rule for it.

[prism classes="language-yaml line-numbers"]
rules:
  slug:
    pattern: "[a-z][a-z0-9_\-]+"
    min: 2
    max: 80
form:
  fields:
    folder:
      type: text
      label: Folder Name
      validate:
        rule: slug
[/prism]

Above example creates rule `slug`, which is then used in the folder field of the form.

## Extending Base Type (extends@)

You can extend existing blueprint, which allows you to add new fields as well as modify existing ones from the base blueprint.

[prism classes="language-yaml line-numbers"]
extends@: default
[/prism]

In the extended format you can specify a lookup context for your base file:

[prism classes="language-yaml line-numbers"]
extends@:
  type: default
  context: blueprints://pages
[/prism]

You can also extend the blueprint itself, if there are multiple versions of the same blueprint.

[prism classes="language-yaml line-numbers"]
extends@: parent@
[/prism]

There is no limit on how many blueprints you can extend. Fields defined in the first blueprint will be replaced by any later blueprints in the list.

[prism classes="language-yaml line-numbers"]
extends@:
  - parent@
  - type: default
    context: blueprints://pages
[/prism]

### Understanding the type- and context-properties

In the examples above, `type` is referencing a file and `context` a path. The `context`-property uses [Streams](https://learn.getgrav.org/advanced/multisite-setup#streams), which means that it resolves to a physical location.

`context: blueprints://` by default will yield `/user/plugins/admin/blueprints`, Admin's blueprints-folder. `type: default` will yield `default.yaml`, when looking up files. Because these two properties are used together, they yield a full path that Grav can understand: `/user/plugins/admin/blueprints/default.yaml`.

Whenever you see the `://`-syntax in these docs, you can be pretty sure it's referring to a stream. And when using `context`, this stream must resolve to an existing folder to work.

## Embedding Form (import@)

Sometimes you may want to share some fields or sub-forms between multiple forms.

Let's create `blueprints://partials/gallery.yaml` which we want to embed to our form:

[prism classes="language-yaml line-numbers"]
form:
  fields:
    gallery.images:
      type: list
      label: Images
      fields:
        .src:
          type: text
          label: Image
[/prism]

Our form then has a section where we would like to embed the gallery images:

[prism classes="language-yaml line-numbers"]
form:
  fields:
    images:
        type: section
        title: Images
        underline: true
        import@:
          type: partials/gallery<commit_msg>Document ordering of multiple imported blueprints (#855)<commit_after>---
title: Advanced Blueprint Features
page-toc:
  active: true
taxonomy:
    category: docs
---

There are advanced features in the blueprints which allow you to extend them and to have dynamic fields.

## Defining Validation Rules

If you need the same validation rules multiple times, you can create your own custom rule for it.

[prism classes="language-yaml line-numbers"]
rules:
  slug:
    pattern: "[a-z][a-z0-9_\-]+"
    min: 2
    max: 80
form:
  fields:
    folder:
      type: text
      label: Folder Name
      validate:
        rule: slug
[/prism]

Above example creates rule `slug`, which is then used in the folder field of the form.

## Extending Base Type (extends@)

You can extend existing blueprint, which allows you to add new fields as well as modify existing ones from the base blueprint.

[prism classes="language-yaml line-numbers"]
extends@: default
[/prism]

In the extended format you can specify a lookup context for your base file:

[prism classes="language-yaml line-numbers"]
extends@:
  type: default
  context: blueprints://pages
[/prism]

You can also extend the blueprint itself, if there are multiple versions of the same blueprint.

[prism classes="language-yaml line-numbers"]
extends@: parent@
[/prism]

There is no limit on how many blueprints you can extend. Fields defined in the first blueprint will be replaced by any later blueprints in the list.

[prism classes="language-yaml line-numbers"]
extends@:
  - parent@
  - type: default
    context: blueprints://pages
[/prism]

### Understanding the type- and context-properties

In the examples above, `type` is referencing a file and `context` a path. The `context`-property uses [Streams](https://learn.getgrav.org/advanced/multisite-setup#streams), which means that it resolves to a physical location.

`context: blueprints://` by default will yield `/user/plugins/admin/blueprints`, Admin's blueprints-folder. `type: default` will yield `default.yaml`, when looking up files. Because these two properties are used together, they yield a full path that Grav can understand: `/user/plugins/admin/blueprints/default.yaml`.

Whenever you see the `://`-syntax in these docs, you can be pretty sure it's referring to a stream. And when using `context`, this stream must resolve to an existing folder to work.

## Embedding Form (import@)

Sometimes you may want to share some fields or sub-forms between multiple forms.

Let's create `blueprints://partials/gallery.yaml` which we want to embed to our form:

[prism classes="language-yaml line-numbers"]
form:
  fields:
    gallery.images:
      type: list
      label: Images
      fields:
        .src:
          type: text
          label: Image
[/prism]

Our form then has a section where we would like to embed the gallery images:

[prism classes="language-yaml line-numbers"]
form:
  fields:
    images:
        type: section
        title: Images
        underline: true
        import@:
          type: partials/gallery
          context: blueprints://
[/prism]

It is also possible to import multiple blueprints and order them by appending an index like `import@1`:

[prism classes="language-yaml line-numbers"]
form:
  fields:
    images:
        type: section
        title: Images
        underline: true
        import@1:
          type: partials/gallery
          context: blueprints://
        import@2:
          type: partials/another-gallery
{'fraction_non_alphanumeric': 0.0878033699180708, 'fraction_numerical': 0.002473334363889318, 'mean_word_length': 3.4345442083618916, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1886724', 'n_tokens_mistral': 1858, 'n_tokens_neox': 1774, 'n_words': 795}