Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vertical menu cookbook entry #403

Merged
merged 1 commit into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions pages/10.cookbook/01.general-recipes/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This page contains an assortment of problems and their respective solutions rela
1. [Create a private area](#create-a-private-area)
1. [Add JavaScript to the footer](#add-javascript-to-the-footer)
1. [Override the default logs folder location](#override-the-default-logs-folder-location)
1. [Split vertical menu system](#split-vertical-menu-system)

### Change the PHP CLI version

Expand Down Expand Up @@ -472,3 +473,96 @@ return [
```

This basically overrides the `log` stream with the `grav-logs/` folder rather than the default `logs/` folder as defined in `system/src/Grav/Common/Config/Setup.php`.

### Split vertical menu system

To create a vertical, collapsible, hierarchical menu of pages you need a Twig-loop, a bit of CSS, and a bit of JavaScript. The final result will, when using the Antimatter-theme, look like this:

![Vertical Menu](vertical_menu.png)

Let's start with Twig:

```
<ol class="tree">
{% for page in pages.children.visible %}
{% if page.children.visible is empty %}
<li class="item">
<a href="{{ page.url }}">{{ page.title }}</a>
{% else %}
<li class="parent">
<a href="javascript:void(0);">{{ page.title }}</a>
<ol>
{% for child in page.children.visible %}
{% if child.children.visible is empty %}
<li class="item">
<a href="{{ child.url }}">{{ child.title }}</a>
{% else %}
<li class="parent">
<a href="javascript:void(0);">{{ child.title }}</a>
<ol>
{% for subchild in child.children.visible %}
<li><a href="{{ subchild.url }}">{{ subchild.title }}</a></li>
{% endfor %}
</ol>
{% endif %}
</li>
{% endfor %}
</ol>
{% endif %}
</li>
{% endfor %}
</ol>
```

This creates an ordered list which iterates over all visible pages within Grav, going three levels deep to create a structure for each level. The list wrapped around the entire structure has the class *tree*, and each list-item has the class *parent* if it contains children or *item* if it does not.

Clicking on a parent opens the list, whilst regular items link to the page itself. You could add this to virtually any Twig-template in a Grav theme, provided that Grav can access the visible pages.

To add some style, we add some CSS:

```
<style>
ol.tree li {
position: relative;
}
ol.tree li ol {
display: none;
}
ol.tree li.open > ol {
display: block;
}
ol.tree li.parent:after {
content: '[+]';
}
ol.tree li.parent.open:after {
content: '';
}
</style>
```

This should generally be placed before the Twig-structure, or ideally be streamed into the [Asset Manager](/themes/asset-manager) in your theme. The effect is to add **[+]** after each parent-item, indicating that it can be opened, which disappears when opened.

Finally, let's add a bit of JavaScript to [handle toggling](http://stackoverflow.com/a/36297446/603387) the *open*-class:

```
<script type="text/javascript">
var tree = document.querySelectorAll('ol.tree a:not(:last-child)');
for(var i = 0; i < tree.length; i++){
tree[i].addEventListener('click', function(e) {
var parent = e.target.parentElement;
var classList = parent.classList;
if(classList.contains("open")) {
classList.remove('open');
var opensubs = parent.querySelectorAll(':scope .open');
for(var i = 0; i < opensubs.length; i++){
opensubs[i].classList.remove('open');
}
} else {
classList.add('open');
}
});
}
</script>
```

This should always be placed **after** the Twig-structure, also ideally in the [Asset Manager](/themes/asset-manager).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.