diff --git a/.travis.yml b/.travis.yml
index f530f5c6..9b2383cf 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,7 +25,6 @@ jobs:
- pip install poetry
- poetry install
script:
- - cp README.md docs/README.md
- poetry run mkdocs build
deploy:
- provider: pages
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 4d252e7a..14e29c87 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -53,6 +53,17 @@ npm run build
npm run start
```
+### Documentation
+
+The project’s documentation website is built with [MkDocs](https://www.mkdocs.org/).
+
+```sh
+# One-off build.
+poetry run mkdocs build
+# Rebuild the docs as you work on them
+poetry run mkdocs serve
+```
+
## Running the tests
To run the python tests, use the script in the root of the repo:
diff --git a/README.md b/README.md
index 33baef00..2f7b7b8d 100644
--- a/README.md
+++ b/README.md
@@ -1,150 +1,52 @@
-# Django pattern library
+# [django-pattern-library](https://torchbox.github.io/django-pattern-library/)
[](https://pypi.org/project/django-pattern-library/) [](https://pypi.org/project/django-pattern-library/) [](https://travis-ci.com/torchbox/django-pattern-library) [](https://lgtm.com/projects/g/torchbox/django-pattern-library/alerts/)
-A module for Django that helps you to build pattern libraries.
+> UI pattern libraries for Django templates

-## Documentation
-
-Documentation is located on GitHub in [`docs/`](https://github.com/torchbox/django-pattern-library/tree/master/docs).
-
-## Objective
-
-At the moment, the main focus is to allow developers and designers
-use exactly the same Django templates in a design pattern library
-and in production code.
-
-There are a lot of alternative solutions for building
-pattern libraries already. Have a look at [Pattern Lab](http://patternlab.io/) and
-[Astrum](http://astrum.nodividestudio.com/), for example.
-But at [Torchbox](https://torchbox.com/) we mainly use Python and Django and
-we find it hard to maintain layout on big projects in several places:
-in a project's pattern library and in actual production code. This is our
-attempt to solve this issue and reduce the amount of copy-pasted code.
-
-To learn more about how this package can be used, have a look at our Wagtail Space 2020 talk: [Reusable UI components: A journey from React to Wagtail](https://www.youtube.com/watch?v=isrOufI7TKc)
-
-[](https://www.youtube.com/watch?v=isrOufI7TKc)
-
-## Concepts
-To understand how `django-pattern-library` works, the following concepts are important.
-
-### Patterns
-Any template that is displayed by the pattern library is referred to as a pattern. Patterns are divided into two categories: fragments and pages.
-
-### Fragments
-A fragment is a pattern whose markup does not include all of the resources (typically CSS and Javascript) for it to be displayed correctly on its own. This is typical for reusable component templates which depend on global stylesheets or Javascript bundles to render and behave correctly.
-
-To enable them to be correctly displayed in the pattern library, `django-pattern-library` will inject the rendered markup of fragments into the **pattern base template** specified by `PATTERN_LIBRARY['PATTERN_BASE_TEMPLATE_NAME']`.
-
-This template should include references to any required static files. The rendered markup of fragments will be available in the `pattern_library_rendered_pattern` context variable (see the tests for [an example](https://github.com/torchbox/django-pattern-library/blob/master/tests/templates/patterns/base.html)).
-
-### Pages
-In contrast to fragments, pages are patterns that include everything they need to be displayed correctly in their markup. Pages are defined by `PATTERN_LIBRARY['BASE_TEMPLATE_NAMES']`.
-
-Any template in that list — or that extends a template in that list — is considered a page and will be displayed as-is when rendered in the pattern library.
-
-It is common practice for page templates to extend the pattern base template to avoid duplicate references to stylesheets and Javascript bundles. Again, [an example](https://github.com/torchbox/django-pattern-library/blob/master/tests/templates/patterns/base_page.html) of this can be seen in the tests.
+## Features
-## How to install
+This package automates the maintenance of UI pattern libraries or styleguides for Django projects, and allows developers to experiment with Django templates without having to create Django views and models.
-First install the library:
+- Create reusable patterns by creating Django templates files as usual.
+- All patterns automatically show up in the pattern library’s interface.
+- Define data as YAML files for the templates to render with the relevant Django context.
+- Override Django templates tags as needed to mock the template’s dependencies.
+- Document your patterns with Markdown.
-```sh
-pip install django-pattern-library
-# ... or...
-poetry add django-pattern-library
-```
+## Why you need this
+Pattern libraries will change your workflow for the better:
-Then, in your Django settings, add `pattern_library` into your `INSTALLED_APPS`, and `pattern_library.loader_tags` to `OPTIONS['builtins']` into the `TEMPLATES` setting. For example:
+- They help separate concerns, both in code, and between members of a development team.
+- If needed, they make it possible for UI development to happen before models and views are created.
+- They encourage code reuse – defining independent UI components, that can be reused across apps, or ported to other projects.
+- It makes it much simpler to test UI components – no need to figure out where they’re used across a site or app.
-```python
-INSTALLED_APPS = [
- # ...
- 'pattern_library',
- # ...
-]
-
-TEMPLATES = [
- {
- 'BACKEND': 'django.template.backends.django.DjangoTemplates',
- 'DIRS': [],
- 'APP_DIRS': True,
- 'OPTIONS': {
- 'context_processors': [
- 'django.template.context_processors.debug',
- 'django.template.context_processors.request',
- 'django.contrib.auth.context_processors.auth',
- 'django.contrib.messages.context_processors.messages',
- ],
- 'builtins': ['pattern_library.loader_tags'],
- },
- },
-]
-```
-
-Note that this module only supports the Django template backend.
-
-### Settings
-
-Next, set the `PATTERN_LIBRARY` setting. Here's an example showing the defaults:
-
-```python
-PATTERN_LIBRARY = {
- # PATTERN_BASE_TEMPLATE_NAME is the template that fragments will be wrapped with.
- # It should include any required CSS and JS and output
- # `pattern_library_rendered_pattern` from context.
- 'PATTERN_BASE_TEMPLATE_NAME': 'patterns/base.html',
- # Any template in BASE_TEMPLATE_NAMES or any template that extends a template in
- # BASE_TEMPLATE_NAMES is a "page" and will be rendered as-is without being wrapped.
- 'BASE_TEMPLATE_NAMES': ['patterns/base_page.html'],
- 'TEMPLATE_SUFFIX': '.html',
- # SECTIONS controls the groups of templates that appear in the navigation. The keys
- # are the group titles and the values are lists of template name prefixes that will
- # be searched to populate the groups.
- 'SECTIONS': (
- ('atoms', ['patterns/atoms']),
- ('molecules', ['patterns/molecules']),
- ('organisms', ['patterns/organisms']),
- ('templates', ['patterns/templates']),
- ('pages', ['patterns/pages']),
- ),
-}
-
-```
-
-Note that the templates in your `PATTERN_LIBRARY` settings must be available to your project's
-[template loaders](https://docs.djangoproject.com/en/3.1/ref/templates/api/#loader-types).
-
-### URLs
-
-Include `pattern_library.urls` in your `urlpatterns`. Here's an example `urls.py`:
-
-```python
-from django.apps import apps
-from django.conf.urls import url, include
-
-urlpatterns = [
- # ... Your URLs
-]
+## Documentation
-if apps.is_installed('pattern_library'):
- urlpatterns += [
- url(r'^pattern-library/', include('pattern_library.urls')),
- ]
-```
+Documentation is available at [torchbox.github.io/django-pattern-library/](https://torchbox.github.io/django-pattern-library/), with source files in the `docs` directory.
-This package is not intended for production. It is **highly recommended** to only enable this package in testing environments for a restricted, trusted audience. One simple way to do this is to only expose its URLs if `apps.is_installed('pattern_library')`, as demonstrated above, and only have the app installed in environment-specific settings.
+- [Getting started](https://torchbox.github.io/django-pattern-library/getting-started/)
+- Guides
+ - [Defining template context](https://torchbox.github.io/django-pattern-library/guides/defining-template-context/)
+ - [Overriding template tags](https://torchbox.github.io/django-pattern-library/guides/overriding-template-tags/)
+ - [Customizing template rendering](https://torchbox.github.io/django-pattern-library/guides/customizing-template-rendering/)
+ - [Workflows that work](https://torchbox.github.io/django-pattern-library/guides/workflows-that-work/)
+- Reference
+ - [API & settings](https://torchbox.github.io/django-pattern-library/reference/api/)
+ - [Known issues and limitations](https://torchbox.github.io/django-pattern-library/reference/known-issues/)
## Contributing
See anything you like in here? Anything missing? We welcome all support, whether on bug reports, feature requests, code, design, reviews, tests, documentation, and more. Please have a look at our [contribution guidelines](https://github.com/torchbox/django-pattern-library/blob/master/CONTRIBUTING.md).
-If you just want to set up the project on your own computer, the contribution guidelines also contain all of the setup commands.
+If you want to set up the project on your own computer, the contribution guidelines also contain all of the setup commands.
## Credits
View the full list of [contributors](https://github.com/torchbox/django-pattern-library/graphs/contributors). [BSD](https://github.com/torchbox/django-pattern-library/blob/master/LICENSE) licensed.
+
+Project logo from [FxEmoji](https://github.com/mozilla/fxemoji). Documentation website built with [MkDocs](https://www.mkdocs.org/), and hosted in [GitHub Pages](https://pages.github.com/).
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 00000000..aa456244
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,5 @@
+# Documentation
+
+This documentation is built as a website with [MkDocs](https://www.mkdocs.org/): [torchbox.github.io/django-pattern-library/](https://torchbox.github.io/django-pattern-library/). The documentation uses non-standard Markdown extensions, and will be best viewed on the website rather than GitHub.
+
+To build locally, view the project’s `CONTRIBUTING.md`.
diff --git a/docs/getting-started.md b/docs/getting-started.md
new file mode 100644
index 00000000..351093bc
--- /dev/null
+++ b/docs/getting-started.md
@@ -0,0 +1,179 @@
+# Getting started
+
+## Installation
+
+django-pattern-library is available [on PyPI](https://pypi.org/project/django-pattern-library/). First install it in your Django project:
+
+```sh
+# With pip,
+pip install django-pattern-library
+# Alternatively, with Poetry,
+poetry add --dev django-pattern-library
+```
+
+### Compatibility
+
+We support:
+
+- Django 2.2.x, 3.0.x, 3.1.x
+- Python 3.6, 3.7, 3.8
+- Django Templates only, no Jinja support
+
+## Configuration
+
+### Django settings
+
+In your Django settings file, add `pattern_library` to `INSTALLED_APPS`:
+
+```python
+INSTALLED_APPS = [
+ # ...
+ "pattern_library",
+ # ...
+]
+```
+
+Also add `pattern_library.loader_tags` to `OPTIONS["builtins"]` into the `TEMPLATES` setting:
+
+```python hl_lines="13 14 15"
+TEMPLATES = [
+ {
+ "BACKEND": "django.template.backends.django.DjangoTemplates",
+ "DIRS": [],
+ "APP_DIRS": True,
+ "OPTIONS": {
+ "context_processors": [
+ "django.template.context_processors.debug",
+ "django.template.context_processors.request",
+ "django.contrib.auth.context_processors.auth",
+ "django.contrib.messages.context_processors.messages",
+ ],
+ "builtins": [
+ "pattern_library.loader_tags"
+ ],
+ },
+ },
+]
+```
+
+### Pattern library settings
+
+Still in Django settings, set the [`PATTERN_LIBRARY`](./reference/api.md#pattern_library) setting. Here is an example showing the defaults:
+
+```python
+PATTERN_LIBRARY = {
+ # Groups of templates for the pattern library navigation. The keys
+ # are the group titles and the values are lists of template name prefixes that will
+ # be searched to populate the groups.
+ "SECTIONS": (
+ ("components", ["patterns/components"]),
+ ("pages", ["patterns/pages"]),
+ ),
+
+ # Configure which files to detect as templates.
+ "TEMPLATE_SUFFIX": ".html",
+
+ # Set which template components should be rendered inside of,
+ # so they may use page-level component dependencies like CSS.
+ "PATTERN_BASE_TEMPLATE_NAME": "patterns/base.html",
+
+ # Any template in BASE_TEMPLATE_NAMES or any template that extends a template in
+ # BASE_TEMPLATE_NAMES is a "page" and will be rendered as-is without being wrapped.
+ "BASE_TEMPLATE_NAMES": ["patterns/base_page.html"],
+}
+```
+
+Note the templates in your [`PATTERN_LIBRARY`](./reference/api.md#pattern_library) settings must be available to [template loaders](https://docs.djangoproject.com/en/3.1/ref/templates/api/#loader-types).
+
+### URLs
+
+Include `pattern_library.urls` in your `urlpatterns`. Here is an example `urls.py`:
+
+```python
+from django.apps import apps
+from django.urls import include, path
+
+urlpatterns = [
+ # … Your URLs
+]
+
+if apps.is_installed("pattern_library"):
+ urlpatterns += [
+ path("pattern-library/", include("pattern_library.urls")),
+ ]
+```
+
+!!! warning "Security"
+
+ This package isn’t intended for production usage, and hasn’t received extensive security scrutiny.
+
+It is **highly recommended** to only enable this package in testing environments, for a restricted, trusted audience. One way to do this is to only expose its URLs if `apps.is_installed("pattern_library")`, as demonstrated above, and only have the app installed in environment-specific settings.
+
+---
+
+Alright, now that we got this far, we can navigate to `http://localhost:8000/pattern-library/` to see our pattern library! But if we tried to do this now, we would likely get a `PatternLibraryEmpty` error – this is expected, as we haven’t added any patterns yet.
+
+
+
+Now let’s look at adding our first template!
+
+## First pattern
+
+Now we’ve done all of the configuration – let’s create a UI component. We’ll use `quote-block` as an example, and place it at `patterns/components/quote_block/quote_block.html` inside one of our Django apps:
+
+```jinja2
+
+
+
{{ quote }}
+ {% if attribution %}
+
{{ attribution }}
+ {% endif %}
+
+
+```
+
+### Base template
+
+We additionally need to customize a base template, so the standalone component can be rendered within a page with CSS. This is what the `PATTERN_BASE_TEMPLATE_NAME` setting is for. As a separate template in `patterns/base.html`:
+
+```jinja2 hl_lines="11"
+
+
+
+
+
+ My Base
+
+
+ {% block content %}
+ {# pattern_library_rendered_pattern is where the pattern library will inject the rendered pattern. #}
+ {{ pattern_library_rendered_pattern }}
+ {% endblock %}
+
+
+```
+
+`quote_block` should now appear in the pattern library UI menu! But the template doesn’t display anything – we additionally need to provide it with test data.
+
+### Component data
+
+We can provide context and tags overrides for our new component by creating a `quote_block.yaml` YAML file alongside the HTML, at `patterns/components/quote_block/quote_block.yaml` in our example.
+
+```yaml
+context:
+ quote: What is love?
+ attribution: Haddaway
+```
+
+We could also provide it with a custom name:
+
+```yaml
+name: Quote Block
+context:
+ quote: What is love?
+ attribution: Haddaway
+```
+
+And that’s it! Our `quote_block` should finally appear in the pattern library, along with its rendering with this mock data.
+
+
diff --git a/docs/guides/customizing-template-rendering.md b/docs/guides/customizing-template-rendering.md
new file mode 100644
index 00000000..7308779b
--- /dev/null
+++ b/docs/guides/customizing-template-rendering.md
@@ -0,0 +1,48 @@
+# Customizing template rendering
+
+## Customizing all patterns’ surroundings
+
+All patterns that are not pages are rendered within a base page template. The pattern library will render patterns inside the `content` block, which you can tweak to change how patterns are displayed.
+
+You can for example add a theme wrapper around the components:
+
+```jinja2
+{% block content %}
+ {% if pattern_library_rendered_pattern %}
+
+ {{ pattern_library_rendered_pattern }}
+
+ {% endif %}
+{% endblock %}
+```
+
+`pattern_library_rendered_pattern` can also be used to do other modifications on the page for the pattern library only, for example adding an extra class to ``:
+
+```jinja2
+
+```
+
+## Customizing a single pattern’s rendering
+
+There is no API to customize a single pattern’s rendering, but it can be done by using pattern-library-only templates. For example, with our `quote_block.html` component:
+
+```django
+
+
+
{{ quote }}
+ {% if attribution %}
+
{{ attribution }}
+ {% endif %}
+
+
+```
+
+We could create another template next to it called `quote_block_example.html`,
+
+```django
+
+ {% include "patterns/components/quote_block/quote_block.html" with attribution=attribution quote=quote %}
+
+```
+
+This is a fair amount of boilerplate, but neatly solves the problem per pattern.
diff --git a/docs/guides/defining-template-context.md b/docs/guides/defining-template-context.md
new file mode 100644
index 00000000..3ae240fd
--- /dev/null
+++ b/docs/guides/defining-template-context.md
@@ -0,0 +1,59 @@
+# Defining template context
+
+To define fake context you need to create a YAML file alongside your
+template file. For example, for the template `big_red_button.html` you need to
+create a file called `big_red_button.yaml`.
+
+Let's imagine that your `big_red_button.html` template looks like this:
+
+```django
+
+ {{ button_text }}
+
+```
+
+The `big_red_button.yaml` can be something like this:
+
+```yaml
+context:
+ button_link: https://example.com/
+ button_text: Example link
+```
+
+In the same way you can provide context in more complex templates. Here is
+an example on how you can define fake context that pretends to be a `QuerySet`.
+
+Let's assume you have the following template:
+
+```django
+{% if my_objects.exists %}
+ {{ items_title }}
+
+{% endif %}
+```
+
+You might define a `yaml` file similar to this to provide fake data:
+
+```yaml
+name: My example pattern
+
+context:
+ items_title: Related pages
+ my_objects:
+ exists: true # simulate `QuerySet`'s `exists` method
+ all: # simulate `QuerySet`'s `all` method
+ - title: Page 1
+ link: /page1
+ - title: Page 2
+ link: /page2
+```
+
+You can define a list or a dict or anything that [`PyYAML`](http://pyyaml.org/wiki/PyYAMLDocumentation) allows you to create in `yaml` format without creating a custom objects.
diff --git a/docs/overview.md b/docs/guides/overriding-template-tags.md
similarity index 51%
rename from docs/overview.md
rename to docs/guides/overriding-template-tags.md
index 617237cf..f0e9b3a0 100644
--- a/docs/overview.md
+++ b/docs/guides/overriding-template-tags.md
@@ -1,160 +1,42 @@
-# Overview
-
-The main idea of this package is
-to allow you use template in both: your pattern library and
-production code of your Django project.
-
-To achieve this the package must to provide a way to:
-
-* Define a fake context for templates
-* Override template tags (default and custom ones)
-
-## Directory structure
-
-The initial structure of your pattern library should look like this:
-
-```
-.
-├── templates
-| └── patterns
-| |── atoms
-| |── molecules
-| |── organisms
-| |── templates
-| └── pages
-└── templatetags
-```
-
-- a `templates/patterns` directory with subfolders for the different levels of
- pattern, following standard atomic design naming conventions.
- - Your `PATTERN_LIBRARY_TEMPLATE_DIR` setting should point to the library's
- root `templates` directory
-- a `templatetags` directory for holding template tag overrides (see below)
-
-
-## Defining fake context for templates
-
-To define fake context you need to create a `yaml` file alongside your
-template file. For example, for the template `big_red_button.html` you need to
-create a file called `big_red_button.yaml`.
-
-Let's imagine that your `big_red_button.html` template looks like this:
-
-```django
-
- {{ button_text }}
-
-```
-
-The `big_red_button.yaml` can be something like this:
-
-```yaml
-context:
- button_link: https://example.com/
- button_text: Example link
-```
-
-In the same way you can provide context in more complex templates. Here is
-an example on how you can define fake context that pretends to be a `QuerySet`.
-
-Let's assume you have the following template:
-
-```django
-{% if my_objects.exists %}
- {{ items_title }}
-
-{% endif %}
-```
-
-You might define a `yaml` file similar to this to provide fake data:
-
-```yaml
-name: My example pattern
-
-context:
- items_title: Related pages
- my_objects:
- exists: true # simulate `QuerySet`'s `exists` method
- all: # simulate `QuerySet`'s `all` method
- - title: Page 1
- link: /page1
- - title: Page 2
- link: /page2
-```
-
-You can define a list or a dict or anything that
-[`PyYAML`](http://pyyaml.org/wiki/PyYAMLDocumentation)
-allows you to create in `yaml` format without creating a custom objects.
-
-## Customising the patterns’ surroundings
-
-All patterns that are not pages are rendered within a base page template, `pages/base.html` by default. The pattern library will render patterns inside the `content` block, which you can tweak to change how patterns are displayed.
-
-You can for example add a theme wrapper around the components:
-
-```html
-{% block content %}
- {% if pattern_library_rendered_pattern %}
-
- {{ pattern_library_rendered_pattern }}
-
- {% endif %}
-{% endblock %}
-```
-
-`pattern_library_rendered_pattern` can also be used to do other modifications on the page for the pattern library only, for example adding an extra class to ``:
-
-```html
-
-```
-
-## Override template tags
+# Overriding template tags
The package overrides the following Django tags:
-* `{% extends %}`
-* `{% include %}`
+- `{% extends %}`
+- `{% include %}`
-It's required to allow us to define fake template context
-and override other template tags in `yaml` files.
-This package uses custom behaviour for these tags only when
-rendering pattern library and falls back to Django's standard behaviour
-on all other cases.
+It's required to allow us to define fake template context and override other template tags in YAML files.
+This package uses custom behaviour for these tags only when rendering pattern library and falls back to Django's standard behaviour on all other cases.
The override process has two parts:
-1. Override your template tag with a mock implementation
-2. Define fake result for your tag in a `yaml` file
+1. Override your template tag with a mock implementation
+2. Define fake result for your tag in a YAML file
+## Providing a default value for template tags
-### Providing a default value for template tags
To provide a default for a template tag, you need to provide a keyword argument default_html when overriding your tag.
-```
+```python
from pattern_library.monkey_utils import override_tag
-override_tag(register, 'a_tag_name', default_html="https://potato.com")
+override_tag(register, 'a_tag_name', default_html="https://example.com/")
```
This default is used for any tag that's not passed its own context, allowing specificity for those elements that need it while preventing the tag from breaking when it's not structural to the component.
-#### Limitation
-Currently this feature only supports providing a default for the output of the tag, this does not support modifying context in templates such as {% an_example_tag page.url as example_variable %}.
+### Limitation
+
+Currently this feature only supports providing a default for the output of the tag, this does not support modifying context in templates such as `{% an_example_tag page.url as example_variable %}`.
+
### When do I need to override a template tag?
Ideally your pattern library should be independent, so it doesn't fail when
you run it with a project that has no entries in DB or on a local machine
-without internet connection. This means that you need to override
-a template tag when it hits DB or any other resource
-(cache, or requests URL, for example).
+without internet connection.
+This means that you need to override a template tag when it hits DB or any other resource (cache, or requests URL, for example).
+
+You amy also need to override template tags in other cases, when data provided by the pattern library’s context mocking is of a different type to what Django would expect – this is because the pattern library only uses data types that are de-serializable from YAML.
### Override modes
@@ -210,23 +92,20 @@ our production code.
Assuming that you already have module installed in your project,
to define a fake implementation we need to:
-1. Create [a `templatetags` package](https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#code-layout)
- in one of your apps. Note that your app should be defined in
- [`INSTALLED_APPS`](https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-INSTALLED_APPS)
- and it should be defined after the package you are
- overriding (`some_package` in our case).
-2. Create `image_utils.py` in this package with the following code:
+First, create a [`templatetags` package](https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/#code-layout) in one of your apps. Note that your app should be defined in [`INSTALLED_APPS`](https://docs.djangoproject.com/en/2.0/ref/settings/#std:setting-INSTALLED_APPS) and it should be defined after the package you are overriding (`some_package` in our case).
+
+Then, create `image_utils.py` in this package with the following code:
- ```python
- from some_package.templatetags.image_utils import register
+```python
+from some_package.templatetags.image_utils import register
- from pattern_library.monkey_utils import override_tag
+from pattern_library.monkey_utils import override_tag
- # We are monkey patching here
- # Note that `register` should be an instance of `django.template.Library`
- # and it's important to the instance where the original tag is defined.
- override_tag(register, name='image')
- ```
+# We are monkey patching here
+# Note that `register` should be an instance of `django.template.Library`
+# and it's important to the instance where the original tag is defined.
+override_tag(register, name='image')
+```
**Note:** it's recommended to have a single app that contains all template tag
overrides, so it's easy to exclude it from `INSTALLED_APPS` in production,
@@ -375,116 +254,3 @@ tags:
```
Note the `target_var` field.
-
-## Some more examples
-
-### Looping over a template tag
-
-#### HTML
-
-```
-{% social_media_links as social_links %}
-
- {% for link in social_links %}
- {# Only render if we have a link #}
- {% if link.url %}
-
-```
-
-#### Yaml
-
-```
-tags:
- social_media_links:
- as social_links:
- raw:
- - url: '#'
- type: twitter
- label: Twitter
- - url: '#'
- type: facebook
- label: Facebook
- - url: '#'
- type: instagram
- label: Instagram
- - url: '#'
- type: youtube
- label: YouTube
- - url: '#'
- type: linkedin
- label: LinkedIn
-```
-
-### Inclusion tags
-
-#### HTML
-
-```
-
-```
-
-#### YAML
-
-```
-tags:
- footernav:
- "":
- template_name: "patterns/molecules/navigation/footernav.html"
-```
-
-### Image lazy load example
-
-#### HTML
-
-```
- {% image slide.image fill-100x71 as imageSmall %}
- {% image slide.image fill-829x585 as imageLarge %}
-
- {% include "patterns/atoms/image/image--lazyload.html" with imageSmall=imageSmall width=829 height=585 imageLarge=imageLarge classList='slide__image' %}
-```
-
-#### YAML
-```
-tags:
- image:
- slide.image fill-100x71 as imageSmall:
- target_var: imageSmall
- raw:
- url: '//placekitten.com/100/71'
- slide.image fill-829x585 as imageLarge:
- target_var: imageLarge
- raw:
- url: '//placekitten.com/829/585'
- width: '829'
- height: '585'
-```
-
-##### Image inlude example
-
-#### HTML
-```
-
-```
-
-#### YAML
-```
-context:
- width: '829'
- height: '585'
- imageSmall:
- url: '//placekitten.com/100/71'
- imageLarge:
- url: '//placekitten.com/829/585'
-```
diff --git a/docs/guides/reuse-across-projects.md b/docs/guides/reuse-across-projects.md
new file mode 100644
index 00000000..6a08b8e0
--- /dev/null
+++ b/docs/guides/reuse-across-projects.md
@@ -0,0 +1,18 @@
+# Reuse across projects
+
+django-pattern-library is designed to be useful for component reuse within a single project, but it can also be set up to create a component library reusable between multiple projects. Reusing pattern library components is a matter of packaging and publishing a Django app (that happens to contain a lot of templates, CSS, and JS).
+
+Here are the rough steps:
+
+- **Decide where to store the shared pattern library**. Whether it has its own repository, whether it’s published on PyPI, or in another way.
+- **Choose a versioning and release methodology**. With multiple projects reusing the code, it’s important for them to be able to pin specific versions, and have a clear sense of how to do updates.
+- **Provide a pattern library development environment**. Developers will need a way to iterate on pattern library components in isolation from the projects the UI components are reused in.
+
+## Static files
+
+As part of your pattern library’s build process, make sure that the static files (CSS, JS, etc.) of each component can be reused individually of each-other. Different projects likely will reuse different components, and you don’t want to be paying the performance cost of loading components you don’t need.
+
+## Useful resources
+
+- Django’s official [How to write reusable apps](https://docs.djangoproject.com/en/3.1/intro/reusable-apps/)
+- InVision’s [Guide to Design Systems](https://www.invisionapp.com/inside-design/guide-to-design-systems/)
diff --git a/docs/guides/workflows-that-work.md b/docs/guides/workflows-that-work.md
new file mode 100644
index 00000000..9b653620
--- /dev/null
+++ b/docs/guides/workflows-that-work.md
@@ -0,0 +1,42 @@
+# Workflows that work
+
+The workflow of developing UI components in a pattern library can be quite different from one-off templates that are only rendered where they are used. Here are tips to make the most of it.
+
+## Keep the pattern library in sync
+
+One of the upsides of having the pattern library built with Django is that the HTML templates can never go out of sync – but the data can! Make sure your template context and tag overrides keep in sync with your actual templates. This can for example be part of a code review checklist.
+
+## Document your patterns
+
+Patterns support defining a custom `name` in YAML, as well as rendering fully-fledged documentation in Markdown. Create a file next to the template to document it:
+
+```markdown
+This template can be used in different places. In streamfield block
+or directly in a page template. To use this template pass `call_to_action` into context.
+
+Example:
+
+{% include "patterns/molecules/cta/call_to_action.html" with call_to_action=call_to_action %}
+```
+
+## Back-end first
+
+Traditionally, Django development starts from models and everything else is derived from it. This is very natural from a back-end perspective – first define your data model, then the view(s) that reuse it, and finally templates.
+
+We generally recommend this approach, but keep in mind that:
+
+- With this workflow it’s natural to write templates that are heavily tied to the database structure, and as such not very reusable, and may be out of touch with visual design (which generally uses basic data structures like lists and mappings)
+- There will be work to do to reconcile the data structure as defined by the back-end, with what is mandated by the designs.
+
+To mitigate this effort, and overall make templates more reusable, take the time to massage data into simple structures that map better to visual representations.
+
+## Front-end first
+
+Alternatively, the pattern library makes it possible to write templates without models and views. This can be very convenient if your project’s schedule requires this kind of progression.
+
+With this approach, keep in mind that:
+
+- When creating the template from UI principles, there will be assumptions made about the underlying data structures to be provided by Django. Templates will be heavily tied to their visual design (which generally uses basic data structures like lists and mappings), and may be out of touch with the models once they are created.
+- There will be work to do to reconcile the data structure as defined in the UI components, with what is mandated by the models.
+
+To mitigate this effort, and overall make templates more reusable, take the time to massage data into simple structures that map better to visual representations.
diff --git a/docs/images/favicon.png b/docs/images/favicon.png
new file mode 100644
index 00000000..128e4326
Binary files /dev/null and b/docs/images/favicon.png differ
diff --git a/docs/images/favicon.svg b/docs/images/favicon.svg
new file mode 100644
index 00000000..10a6f2a8
--- /dev/null
+++ b/docs/images/favicon.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/docs/images/getting-started/PatternLibraryEmpty.png b/docs/images/getting-started/PatternLibraryEmpty.png
new file mode 100644
index 00000000..073349c3
Binary files /dev/null and b/docs/images/getting-started/PatternLibraryEmpty.png differ
diff --git a/docs/images/getting-started/getting-started-complete.png b/docs/images/getting-started/getting-started-complete.png
new file mode 100644
index 00000000..6b1178f2
Binary files /dev/null and b/docs/images/getting-started/getting-started-complete.png differ
diff --git a/docs/images/logo.svg b/docs/images/logo.svg
new file mode 100644
index 00000000..10a6f2a8
--- /dev/null
+++ b/docs/images/logo.svg
@@ -0,0 +1,26 @@
+
+
\ No newline at end of file
diff --git a/docs/images/pattern-library-screenshot.webp b/docs/images/pattern-library-screenshot.webp
new file mode 100644
index 00000000..dcdbc0a8
Binary files /dev/null and b/docs/images/pattern-library-screenshot.webp differ
diff --git a/.github/pattern-library-talk-youtube.webp b/docs/images/pattern-library-talk-youtube.webp
similarity index 100%
rename from .github/pattern-library-talk-youtube.webp
rename to docs/images/pattern-library-talk-youtube.webp
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..a732f1c5
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,41 @@
+# Django pattern library
+
+> UI pattern libraries for Django templates
+
+## Features
+
+This package automates the maintenance of UI pattern libraries or styleguides for Django projects, and allows developers to experiment with Django templates without having to create Django views and models.
+
+- Create reusable patterns by creating Django templates files as usual.
+- All patterns automatically show up in the pattern library’s interface.
+- Define data as YAML files for the templates to render with the relevant Django context.
+- Override Django templates tags as needed to mock the template’s dependencies.
+- Document your patterns with Markdown.
+
+Here is a screenshot of the pattern library in action:
+
+[](images/pattern-library-screenshot.webp)
+
+## Why you need this
+
+Pattern libraries will change your workflow for the better:
+
+- They help separate concerns, both in code, and between members of a development team.
+- If needed, they make it possible for UI development to happen before models and views are created.
+- They encourage code reuse – defining independent UI components, that can be reused across apps, or ported to other projects.
+- It makes it much simpler to test UI components – no need to figure out where they’re used across a site or app.
+
+## Why this exists
+
+We want to make it possible for developers to maintain large pattern libraries with minimal fuss – no copy-pasting of templates between a static library and the “production” templates.
+
+There are a lot of alternative solutions for building pattern libraries, or to have [UI development playgrounds](https://www.componentdriven.org/).
+At [Torchbox](https://torchbox.com/) we mainly use Django and Wagtail, and we found it hard to maintain large libraries with those tools that have no awareness of Django Templates.
+This is our attempt to solve this issue – [Pattern Lab](http://patternlab.io/) goes Django!
+
+To learn more about how this package can be used, have a look at our talk:
+
+[Reusable UI components: A journey from React to Wagtail](https://www.youtube.com/watch?v=isrOufI7TKc)
+
+[](https://www.youtube.com/watch?v=isrOufI7TKc)
+
diff --git a/docs/recipes/image-include.md b/docs/recipes/image-include.md
new file mode 100644
index 00000000..e498f5bc
--- /dev/null
+++ b/docs/recipes/image-include.md
@@ -0,0 +1,17 @@
+## Image include
+
+```jinja2
+
+```
+
+YAML:
+
+```yaml
+context:
+ width: '720'
+ height: '400'
+ imageSmall:
+ url: https://source.unsplash.com/pZ-XFIrJMtE/360x200
+ imageLarge:
+ url: https://source.unsplash.com/pZ-XFIrJMtE/720x400
+```
diff --git a/docs/recipes/image-lazyload.md b/docs/recipes/image-lazyload.md
new file mode 100644
index 00000000..f1260d9b
--- /dev/null
+++ b/docs/recipes/image-lazyload.md
@@ -0,0 +1,23 @@
+## Image lazy load
+
+```jinja2
+{% image slide.image fill-100x71 as imageSmall %}
+{% image slide.image fill-829x585 as imageLarge %}
+
+{% include "patterns/atoms/image/image--lazyload.html" with imageSmall=imageSmall width=829 height=585 imageLarge=imageLarge classList='slide__image' %}
+```
+
+```yaml
+tags:
+ image:
+ slide.image fill-100x71 as imageSmall:
+ target_var: imageSmall
+ raw:
+ url: '//placekitten.com/100/71'
+ slide.image fill-829x585 as imageLarge:
+ target_var: imageLarge
+ raw:
+ url: '//placekitten.com/829/585'
+ width: '829'
+ height: '585'
+```
diff --git a/docs/recipes/inclusion-tags.md b/docs/recipes/inclusion-tags.md
new file mode 100644
index 00000000..ff885187
--- /dev/null
+++ b/docs/recipes/inclusion-tags.md
@@ -0,0 +1,14 @@
+## Inclusion tags
+
+```jinja2
+
+```
+
+```yaml
+tags:
+ footernav:
+ "":
+ template_name: "patterns/molecules/navigation/footernav.html"
+```
diff --git a/docs/recipes/looping-for-tags.md b/docs/recipes/looping-for-tags.md
new file mode 100644
index 00000000..8407d548
--- /dev/null
+++ b/docs/recipes/looping-for-tags.md
@@ -0,0 +1,45 @@
+## Looping over a template tag
+
+For a template such as:
+
+```jinja2
+{% social_media_links as social_links %}
+
+ {% for link in social_links %}
+ {# Only render if we have a link #}
+ {% if link.url %}
+
+```
+
+You can use the following syntax to mock the tag’s output:
+
+```yaml
+tags:
+ social_media_links:
+ as social_links:
+ raw:
+ - url: '#'
+ type: twitter
+ label: Twitter
+ - url: '#'
+ type: facebook
+ label: Facebook
+ - url: '#'
+ type: instagram
+ label: Instagram
+ - url: '#'
+ type: youtube
+ label: YouTube
+ - url: '#'
+ type: linkedin
+ label: LinkedIn
+```
diff --git a/docs/recipes/multiple-variants.md b/docs/recipes/multiple-variants.md
new file mode 100644
index 00000000..0ed01e55
--- /dev/null
+++ b/docs/recipes/multiple-variants.md
@@ -0,0 +1,62 @@
+# Multiple template variants
+
+See [#87](https://github.com/torchbox/django-pattern-library/issues/87). There is currently no support for trying out a single component with different variations in context or tag overrides, but this can worked around by creating pattern-library-only templates.
+
+For example, for this `call_to_action` template:
+
+```django
+
+
+
{{ call_to_action.title }}
+ {% include "patterns/atoms/link/link.html" with type="primary" classes="call-to-action__link" href=call_to_action.get_link_url text=call_to_action.get_link_text %}
+
+```
+
+We can try it out once with the following YAML:
+
+```yaml
+context:
+ call_to_action:
+ title: Will you help us protect these magnificant creatures in the UK waters?
+ illustration:
+ url: /static/images/illustrations/sharks.svg
+ get_link_text: Sign up for our appeal
+ get_link_url: '#'
+```
+
+If we want to try multiple variants, simply create a custom template for pattern library usage only, that renders `call_to_action` multiple times:
+
+```django
+
+
Call to action
+ {% for call_to_action in ctas %}
+
+
{{ call_to_action.type }}
+ {% include "patterns/molecules/cta/call_to_action.html" with call_to_action=call_to_action %}
+
+ {% endfor %}
+
+```
+
+```yaml
+context:
+ ctas:
+ - type: Call to action
+ title: Will you help us protect these magnificant creatures in the UK waters?
+ illustration:
+ url: /static/images/illustrations/sharks.svg
+ get_link_text: Sign up for our appeal
+ get_link_url: '#'
+ - type: Call to action with short title
+ title: Will you help us?
+ illustration:
+ url: /static/images/illustrations/sharks.svg
+ get_link_text: Sign up for our appeal
+ get_link_url: '#'
+ - type: Call to action with long title
+ title: Will you help us protect these magnificant and learn how to make environmentally responsible choices when buying seafood?
+ illustration:
+ url: /static/images/illustrations/sharks.svg
+ get_link_text: Sign up for our appeal
+ get_link_url: '#'
+```
diff --git a/docs/reference/api.md b/docs/reference/api.md
new file mode 100644
index 00000000..b6254d25
--- /dev/null
+++ b/docs/reference/api.md
@@ -0,0 +1,118 @@
+# API and settings
+
+## YAML structure
+
+YAML isn’t everyone’s favorite markup language, but it has the advantage of being very lean, mapping well to both JSON and Python data structures, and supporting comments.
+
+Here is what you need to know:
+
+- Always use `.yaml` for patterns configuration.
+- Use Mappings in place of Python Dictionaries.
+- Use Sequences in place of Python lists (or iterables like QuerySets).
+- The pattern library uses [PyYAML](https://pyyaml.org/wiki/PyYAMLDocumentation) in particular
+
+Here is an example in practice:
+
+```yaml
+name: Test
+# Nested structure, dependent on template.
+context:
+ quote: What is love?
+ attribution: Haddaway
+ my_list:
+ - 1
+ - 2
+ - 3
+# Mapping from tag names to tag overrides.
+tags:
+ error_tag:
+ include:
+ template_name: 'non-patterns/include.html'
+```
+
+## Templates
+
+### `pattern_library_rendered_pattern`
+
+`pattern_library_rendered_pattern` is required in the template defined as [`PATTERN_BASE_TEMPLATE_NAME`](#pattern_base_template_name). This gets replaced by the rendered pattern’s HTML when displaying patterns in the library.
+
+```django
+
+ {% block content %}{{ pattern_library_rendered_pattern }}{% endblock %}
+
+```
+
+## Settings
+
+See [Getting started](../getting-started.md) for more guided information.
+
+### `PATTERN_LIBRARY`
+
+All settings should be set as keys of the `PATTERN_LIBRARY` object.
+
+```python
+PATTERN_LIBRARY = {
+ # […]
+}
+```
+
+### `SECTIONS`
+
+`SECTIONS` controls the groups of templates that appear in the navigation.
+The keys are the group titles and the values are lists of template name prefixes that will be searched to populate the groups.
+
+You can use this to create basic two-folder "includes and pages" hierarchies:
+
+```python
+PATTERN_LIBRARY = {
+ "SECTIONS": (
+ ("components", ["patterns/components"]),
+ ("pages", ["patterns/pages"]),
+ ),
+}
+```
+
+Or more detailed structures following [Atomic Design](https://atomicdesign.bradfrost.com/):
+
+```python
+PATTERN_LIBRARY = {
+ "SECTIONS": (
+ ("atoms", ["patterns/atoms"]),
+ ("molecules", ["patterns/molecules"]),
+ ("organisms", ["patterns/organisms"]),
+ ("templates", ["patterns/templates"]),
+ ("pages", ["patterns/pages"]),
+ ),
+}
+```
+
+### `TEMPLATE_SUFFIX`
+
+Defaults to `.html`. Only set this if your templates use another file extension.
+
+```python
+PATTERN_LIBRARY = {
+ "TEMPLATE_SUFFIX": ".dj",
+}
+```
+
+### `PATTERN_BASE_TEMPLATE_NAME`
+
+`PATTERN_BASE_TEMPLATE_NAME` is the template that fragments will be wrapped with.
+It should include any required CSS and JS, and output [`pattern_library_rendered_pattern`](#pattern_library_rendered_pattern) from context.
+
+```python
+PATTERN_LIBRARY = {
+ "PATTERN_BASE_TEMPLATE_NAME": "patterns/base.html",
+}
+```
+
+### `BASE_TEMPLATE_NAMES`
+
+Any template in `BASE_TEMPLATE_NAMES` or any template that extends a template in `BASE_TEMPLATE_NAMES` is a "page" and will be rendered as-is without being wrapped.
+
+```python
+PATTERN_LIBRARY = {
+ "BASE_TEMPLATE_NAMES": ["patterns/base_page.html"],
+}
+```
diff --git a/docs/reference/concepts.md b/docs/reference/concepts.md
new file mode 100644
index 00000000..b7304c84
--- /dev/null
+++ b/docs/reference/concepts.md
@@ -0,0 +1,24 @@
+# Concepts
+
+To understand how `django-pattern-library` works, the following concepts are important.
+
+## Patterns
+
+Any template that is displayed by the pattern library is referred to as a pattern. Patterns are divided into two categories: fragments and pages.
+
+## Fragments
+
+A fragment is a pattern whose markup does not include all of the resources (typically CSS and Javascript) for it to be displayed correctly on its own. This is typical for reusable component templates which depend on global stylesheets or Javascript bundles to render and behave correctly.
+
+To enable them to be correctly displayed in the pattern library, `django-pattern-library` will inject the rendered markup of fragments into the **pattern base template** specified by `PATTERN_LIBRARY['PATTERN_BASE_TEMPLATE_NAME']`.
+
+This template should include references to any required static files. The rendered markup of fragments will be available in the `pattern_library_rendered_pattern` context variable (see the tests for [an example](https://github.com/torchbox/django-pattern-library/blob/master/tests/templates/patterns/base.html)).
+
+## Pages
+
+In contrast to fragments, pages are patterns that include everything they need to be displayed correctly in their markup. Pages are defined by `PATTERN_LIBRARY['BASE_TEMPLATE_NAMES']`.
+
+Any template in that list — or that extends a template in that list — is considered a page and will be displayed as-is when rendered in the pattern library.
+
+It is common practice for page templates to extend the pattern base template to avoid duplicate references to stylesheets and Javascript bundles. Again, [an example](https://github.com/torchbox/django-pattern-library/blob/master/tests/templates/patterns/base_page.html) of this can be seen in the tests.
+
diff --git a/docs/reference/known-issues.md b/docs/reference/known-issues.md
new file mode 100644
index 00000000..25344550
--- /dev/null
+++ b/docs/reference/known-issues.md
@@ -0,0 +1,105 @@
+# Known issues and limitations
+
+django-pattern-library has a few known limitations due to its design, which are worth knowing about when authoring templates or attempting to document them in the pattern library.
+
+## No way to specify objects that have attributes and support iteration
+
+See [#10](https://github.com/torchbox/django-pattern-library/issues/10). It’s impossible to mock the context when a variable needs to support iteration _and_ attributes. Here is an example of this impossible case:
+
+```django
+{% for result in search_results %}
+{# […] #}
+{% if search_results.paginator.count %}
+```
+
+## Overriding filters is not supported
+
+See [#114](https://github.com/torchbox/django-pattern-library/issues/114). PRs welcome!
+
+## Django form fields are not well supported
+
+See [#113](https://github.com/torchbox/django-pattern-library/issues/113). If a template contains `{% for field in form %}` or even `{% if form %}`, then it's easy enough to render in django-pattern-library so long as we force the form to be null in the YAML context, and are happy not to have the form.
+
+If the form is rendered explicitly by field names, then it requires a lot more work, which can quickly become too much of a maintenance burden – for example creating deeply nested structures for form fields:
+
+```yaml
+ form:
+ email:
+ bound_field:
+ field:
+ widget:
+ class:
+ __name__: char_field
+```
+
+While this is in theory possible, it’s not a very desirable prospect.
+
+## Can’t override context in a child template
+
+See [#8](https://github.com/torchbox/django-pattern-library/issues/8).
+
+If you have a `some_page.html`, `some_page.yaml`, and `include_me.html`, `include_me.html`, and `some_page.html` includes `include_me.html`.
+
+`some_page.yaml` with something like:
+
+```yaml
+context:
+ page:
+ pk: 1
+ title: "my title"
+```
+
+and `include_me.yaml` with something like:
+
+```yaml
+context:
+ page:
+ title: "Title from include"
+```
+
+`Title from include` will appear on both patterns. It's impossible to override single key in `some_page.html`
+
+## No support for pattern variations
+
+See [#87](https://github.com/torchbox/django-pattern-library/issues/87). There is currently no support for trying out a single component with different variations in context or tag overrides.
+
+This can be worked around by creating pattern-library-only templates, see [Multiple template variants](../recipes/multiple-variants.md)
+
+## Can’t mock each use of a template tag with different attributes
+
+For example, with a template that uses the same tag many times like:
+
+```django
+{% load wagtailcore_tags %}
+ {% for link in primarynav %}
+ {% with children=link.value.page.get_children.live.public.in_menu %}
+
+ {% include_block link with has_children=children.exists nav_type="primary-nav" %}
+
+
{% include_block link with nav_type="sub-nav" %}
+ {% for child in children.all %}
+
+ {% include_block link with page=child nav_type="sub-nav" %}
+
+ {% endfor %}
+
+
+ {% endwith %}
+ {% endfor %}
+```
+
+This can’t be mocked for all usage of `include_block`.
+
+## Can’t mock objects comparison by reference
+
+With instances of models, the following works fine in vanilla Django, due to `item` and `page` being the same object:
+
+```django
+{% if item == page %}
+```
+
+This can’t be mocked with the pattern library’s context mocking support. As a workaround, you can switch equality checks to using literals:
+
+```django
+{% if item.id == page.id %}
+```
diff --git a/docs/reference/related-projects.md b/docs/reference/related-projects.md
new file mode 100644
index 00000000..23913288
--- /dev/null
+++ b/docs/reference/related-projects.md
@@ -0,0 +1,27 @@
+# Related projects
+
+Here are other projects that are similar to django-pattern-library, and may be relevant if you’re looking to go further, or wanting to try out alternatives:
+
+- [storybook-django](https://github.com/torchbox/storybook-django) – attempting to bridge the gap between React and Django, by bringing django-pattern-library patterns into Storybook stories.
+- [django-reusable-components](https://github.com/EmilStenstrom/django-components/) – Reusable UI components for Django, going further than template partials.
+
+## Alternatives
+
+- [Storybook](https://storybook.js.org/), and in particular [Storybook for Server](https://github.com/storybookjs/storybook/tree/master/app/server) – Storybook integration with server-rendered UI components.
+- [Pattern Lab](http://patternlab.io/) – PHP or Node pattern library, from which this project is heavily inspired.
+- [Astrum](http://astrum.nodividestudio.com/) – Similar to Pattern Lab, Node based.
+- [rikki-patterns](https://github.com/springload/rikki-patterns) – Experimental Django-friendly pattern library generator, for Jinja2 and Nunjucks templates
+
+## Pattern libraries based on Django
+
+Here are open-source projects that maintain pattern libraries for Django.
+
+With `django-pattern-library`:
+
+- [rca.ac.uk](https://github.com/torchbox/rca-wagtail-2019)
+- [Department for Transport: Road Freight Survey - Alpha project](https://github.com/torchbox/dft-rfs-alpha)
+
+Without `django-pattern-library`:
+
+- [Wagtail NHS.UK frontend](https://github.com/nhsuk/wagtail-nhsuk-frontend)
+- [consumerfinance.gov](https://github.com/cfpb/consumerfinance.gov)
diff --git a/mkdocs.yml b/mkdocs.yml
index e269d9c9..e5abeda5 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -8,6 +8,10 @@ dev_addr: 0.0.0.0:8001
theme:
name: material
font: false
+ palette:
+ primary: indigo
+ logo: images/logo.svg
+ favicon: images/favicon.png
markdown_extensions:
- codehilite
- admonition
@@ -20,8 +24,29 @@ markdown_extensions:
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
-
+plugins:
+ - search
+ - git-revision-date
nav:
- # Auto-magically copied from the root of the project in the CI build.
- - 'Home': 'README.md'
- - 'Overview': 'overview.md'
+ - 'Home': 'index.md'
+ - 'Getting started': 'getting-started.md'
+ # Ideally these should be in a "Guides" section, however it’s not currently possible to
+ # display those sections expanded by default.
+ # See https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/.
+ # Choose the order carefully from fundamental topics to advanced ones.
+ - 'Template context': 'guides/defining-template-context.md'
+ - 'Overriding tags': 'guides/overriding-template-tags.md'
+ - 'Customizing rendering': 'guides/customizing-template-rendering.md'
+ - 'Workflows that work': 'guides/workflows-that-work.md'
+ - 'Reuse across projects': 'guides/reuse-across-projects.md'
+ - 'Recipes':
+ - 'Inclusion tags': 'recipes/inclusion-tags.md'
+ - 'Looping for tags': 'recipes/looping-for-tags.md'
+ - 'Image include': 'recipes/image-include.md'
+ - 'Image lazyload': 'recipes/image-lazyload.md'
+ - 'Multiple variants': 'recipes/multiple-variants.md'
+ - 'Reference':
+ - 'API and settings': 'reference/api.md'
+ - 'Concepts': 'reference/concepts.md'
+ - 'Known issues': 'reference/known-issues.md'
+ - 'Related projects': 'reference/related-projects.md'
diff --git a/pyproject.toml b/pyproject.toml
index dd11da5f..9bc16558 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -48,6 +48,7 @@ isort = {version = "^4.3", extras = ["pyproject"]}
mkdocs = "^1.1.2"
mkdocs-material = "^5.5.14"
pymdown-extensions = "^8.0"
+mkdocs-git-revision-date-plugin = "^0.3.1"
[tool.isort]
known_first_party = "pattern_library"