├── .gitignore
├── Gem.gemspec
├── Gemfile
├── LICENSE
├── README.md
├── lib
├── jekyll-menus.rb
└── jekyll
│ ├── menus.rb
│ └── menus
│ ├── drops.rb
│ ├── drops
│ ├── all.rb
│ ├── item.rb
│ └── menu.rb
│ ├── hook.rb
│ ├── utils.rb
│ └── version.rb
└── spec
├── fixture
├── _config.yml
├── _data
│ └── menus.yml
├── _includes
│ └── _menus.html
├── _layouts
│ └── default.html
├── array-of-strings.md
├── empty.md
├── hello
│ └── array-of-strings.md
├── key-hash.md
└── string.md
├── lib
└── jekyll
│ └── menus.rb
└── rspec
└── helper.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle
2 | /vendor/bundle
3 | /spec/fixture/_site
4 | /Gemfile.lock
5 | /*.gem
6 |
--------------------------------------------------------------------------------
/Gem.gemspec:
--------------------------------------------------------------------------------
1 | # Frozen-string-literal: true
2 | # Copyright: 2015 Forestry.io - MIT License
3 | # Encoding: utf-8
4 |
5 | $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
6 | require "jekyll/menus/version"
7 |
8 | Gem::Specification.new do |spec|
9 | spec.authors = ["Jordon Bedwell"]
10 | spec.version = Jekyll::Menus::VERSION
11 | spec.homepage = "http://github.com/forestryio/jekyll-menus/"
12 | spec.description = "Menus (site navigation) for your Jekyll website"
13 | spec.summary = "Menus (navigation) for your very own Jekyll website."
14 | spec.files = %W(Gemfile) + Dir["lib/**/*"]
15 | spec.required_ruby_version = ">= 2.4.0"
16 | spec.email = ["jordon@envygeeks.io"]
17 | spec.require_paths = ["lib"]
18 | spec.name = "jekyll-menus"
19 | spec.has_rdoc = false
20 | spec.license = "MIT"
21 |
22 | spec.add_runtime_dependency("jekyll", ">= 3.6", "< 5.0" )
23 | spec.add_development_dependency(
24 | "rspec", ">= 3", "< 4"
25 | )
26 | end
27 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | gemspec
3 |
4 | group :development do
5 | gem "pry"
6 | end
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015-2016 Forestry.io
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the "Software"),
5 | to deal in the Software without restriction, including without limitation
6 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 | and/or sell copies of the Software, and to permit persons to whom the
8 | Software is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included
11 | in all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 | USE OR OTHER DEALINGS IN THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Jekyll Menus
2 |
3 | A robust, simple-to-use menu plugin for Jekyll that allows for infinitely nested menus.
4 |
5 | ## Installation
6 |
7 | To install and use Jekyll Menus, you should have Ruby, and either [RubyGems](https://jekyllrb.com/docs/installation/#install-with-rubygems), or we recommend using [Bundler](https://bundler.io/#getting-started). Bundler is what Jekyll will prefer you to use by default if you `jekyll new`.
8 |
9 | ### Using Bundler
10 |
11 | You can add our gem to the `jekyll_plugins` group in your `Gemfile`:
12 |
13 | ```ruby
14 | group :jekyll_plugins do
15 | gem "jekyll-menus"
16 | end
17 | ```
18 |
19 | And then install from shell.
20 |
21 | ```sh
22 | bundle install
23 | # --path vendor/bundle
24 | ```
25 |
26 | ***If you are using Jekyll Docker, you do not need to perform this step, Jekyll Docker will perform it on your behalf when you launch the image, you only need to perform this step if you are working directly on your system.***
27 |
28 | ### Using RubyGems
29 |
30 | ```sh
31 | sudo gem install jekyll-menus
32 | sudo gem update jekyll-menus
33 | ```
34 |
35 | Once installed, add the Gem to your `_config.yml`:
36 |
37 | ```yaml
38 | plugins:
39 | - jekyll-menus
40 | ```
41 |
42 | ***Note in earlier versions of Jekyll, `plugins` should instead be `gems`***
43 |
44 | ## Usage
45 |
46 | Jekyll Menus allows you to create menus by attaching posts and pages to menus through their front matter, or by defining custom menu items via `_data/menus.yml`.
47 |
48 | Jekyll Menus adds a new option to the site variable called `site.menus`, which can be looped over just like pages, posts, and other content:
49 |
50 | ```liquid
51 |
58 | ```
59 |
60 | ## Menus via Front Matter
61 |
62 | The easiest way to use Jekyll Menus is to start building menus using your existing posts and pages. This can be done by adding a `menus` variable to your front matter:
63 |
64 | ```markdown
65 | ---
66 | title: Homepage
67 | menus: header
68 | ---
69 | ```
70 |
71 | This will create the `header` menu with a single item, the homepage. The `url`, `title`, and `identifier` for the homepage menu item will be automatically generated from the pages title, file path, and permalink.
72 |
73 | You can optionally set any of the available [menu item variables](#menu-items) yourself to customize the appearance and functionality of your menus. For example, to set a custom title and weight:
74 |
75 | ```markdown
76 | ---
77 | title: Homepage
78 | menus:
79 | header:
80 | title: Home
81 | weight: 1
82 | ---
83 | ```
84 |
85 | ## Custom Menu Items via `_data/menus.yml`
86 |
87 | The other option for configuring menus is creating menus using `_data/menus.yml`. In this scenario, you can add custom menu items to external content, or site content that isn’t handled by Jekyll.
88 |
89 | In this file, you provide the menu key and an array of custom menu items. Custom menu items in the data file must have `url`, `title`, and `identifier` variable:
90 |
91 | ```markdown
92 | ---
93 | header:
94 | - url: /api
95 | title: API Documentation
96 | identifier: api
97 | ---
98 | ```
99 |
100 | ## Sub-menus
101 |
102 | Jekyll Menus supports infinitely nested menu items using the `identifier` variable. Any menu item can be used as a parent menu by using its identifier as the menu.
103 |
104 | For example, in `_data/menus.yml`:
105 |
106 | ```yaml
107 | header:
108 | - url: /api
109 | title: API Documentation
110 | identifier: api
111 | ```
112 |
113 | In a content file called `/api-support.html`:
114 |
115 | ```markdown
116 | ---
117 | title: Get API Support
118 | menus: api
119 | ---
120 | ```
121 |
122 | Which can then be used in your templates by looping over the menu item’s `children` variable:
123 |
124 | ```liquid
125 |
141 | ```
142 |
143 | You can also do this [recursively using a re-usable include](#recursive-menus), allowing for easily managed infinitely nested menus.
144 |
145 | ## Variables
146 |
147 | Jekyll Menus has the following variables:
148 |
149 | ### Menus
150 |
151 | | Variable | Description |
152 | |---|---|
153 | | menu.menu | Returns a JSON object with all of the menu’s items. |
154 | | menu.identifier | The unique identifier for the current menu, generated from the menu key. Allows for nested menu items. |
155 | | menu.parent | The parent menu. Resolves to the site.menus object for top-level menus. |
156 |
157 | ### Menu Items
158 |
159 | | Variable | Description |
160 | |---|---|
161 | | item.title | The display title of the menu item. Automatically set as the post or page title if no value is provided in front matter. |
162 | | item.url | The URL the menu item links to. Automatically set to the post or page URL if no value is provided in front matter. |
163 | | item.weight | Handles the order of menu items through a weighted system, starting with 1 being first. |
164 | | item.identifier | The unique identifier for the current menu item. Allows for nested menu items. Automatically resolved to the page’s file path and filename if not provided in front matter. |
165 | | item.parent | The parent menu. |
166 | | item.children | An array of any child menu items. Used to create sub-menus. |
167 |
168 | ## Custom Variables
169 |
170 | Menu items also support custom variables, which you add to each menu item in the front matter or data file.
171 |
172 | For example, adding a `pre` or `post` variable to add text or HTML to your menu items:
173 |
174 | ```markdown
175 | ---
176 | title: Homepage
177 | menus:
178 | header:
179 | pre:
180 | post: " · "
181 | ---
182 | ```
183 |
184 | ## Recursive Menus
185 |
186 | If you’re looking to build an infinitely nested menu (or a menu that is nested more than once up to a limit) then you should set up a reusable menu include that will handle this for you.
187 |
188 | In `_includes/menu.html` :
189 |
190 | ```liquid
191 | {% if menu %}
192 |