jekyll-collection-pages 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.devcontainer/devcontainer.json +27 -0
- data/.devcontainer/post-create.sh +17 -0
- data/.github/build.sh +4 -0
- data/.github/bump.sh +28 -0
- data/.github/dependabot.yml +12 -0
- data/.github/pr-labeler.yml +7 -0
- data/.github/release-drafter.yml +40 -0
- data/.github/release.sh +69 -0
- data/.github/test.sh +4 -0
- data/.github/workflows/ci.yml +92 -0
- data/.github/workflows/pr_labeler.yml +16 -0
- data/.github/workflows/release.yml +23 -0
- data/.github/workflows/release_draft.yml +61 -0
- data/.github/workflows/site.yml +91 -0
- data/.gitignore +21 -0
- data/.rubocop.yml +43 -0
- data/.rubocop_todo.yml +33 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +5 -0
- data/.vscode/tasks.json +58 -0
- data/CODE_OF_CONDUCT.md +128 -0
- data/CONTRIBUTING.md +41 -0
- data/Gemfile +39 -0
- data/LICENSE +21 -0
- data/README.md +152 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/demo/CODE_OF_CONDUCT.md +1 -0
- data/demo/_articles/jekyll-collection-pages-comparison.md +90 -0
- data/demo/_articles/jekyll-collection-pages-indices.md +173 -0
- data/demo/_articles/jekyll-for-documentation.md +399 -0
- data/demo/_articles/linking-obsidian-and-jekyll.md +89 -0
- data/demo/_config.yml +83 -0
- data/demo/_docs/configuration-guide.md +113 -0
- data/demo/_docs/examples.md +159 -0
- data/demo/_docs/generated-data.md +76 -0
- data/demo/_docs/layout-recipes.md +122 -0
- data/demo/_docs/quick-start.md +1 -0
- data/demo/_docs/troubleshooting.md +68 -0
- data/demo/_layouts/collection_layout.html +27 -0
- data/demo/_layouts/tags.html +31 -0
- data/demo/articles.md +18 -0
- data/demo/assets/img/articles.png +0 -0
- data/demo/assets/img/docs.png +0 -0
- data/demo/assets/img/jekyll-collection-pages-preview.png +0 -0
- data/demo/assets/img/jekyll-collection-pages.png +0 -0
- data/demo/assets/img/post-img-1.png +0 -0
- data/demo/assets/img/post-img-2.png +0 -0
- data/demo/assets/img/post-img-3.png +0 -0
- data/demo/assets/img/post-img-4.png +0 -0
- data/demo/contributing.md +1 -0
- data/demo/directory.md +36 -0
- data/demo/docs.md +24 -0
- data/demo/gallery.md +14 -0
- data/demo/index.md +63 -0
- data/demo/tags.md +15 -0
- data/jekyll-collection-pages.gemspec +28 -0
- data/lib/jekyll/collection_pages.rb +383 -0
- data/lib/jekyll-collection-pages.rb +4 -0
- metadata +126 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Example configurations"
|
|
3
|
+
category: "Usage"
|
|
4
|
+
description: "Copy-ready YAML and Liquid snippets for common collection setups."
|
|
5
|
+
order: 5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Use this cookbook to copy working `collection_pages` configurations and accompanying Liquid snippets.
|
|
9
|
+
|
|
10
|
+
## Blog categories
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
collection_pages:
|
|
14
|
+
- collection: posts
|
|
15
|
+
field: category
|
|
16
|
+
path: blog/category
|
|
17
|
+
layout: category_page.html
|
|
18
|
+
paginate: 10
|
|
19
|
+
- collection: posts
|
|
20
|
+
field: category
|
|
21
|
+
path: blog/category/:field-page:num.html
|
|
22
|
+
layout: category_page.html
|
|
23
|
+
paginate: 10
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The first entry produces folder-style pagination such as `/blog/category/reference/` and `/blog/category/reference/page2/`. The second entry demonstrates file-style pagination (e.g. `/blog/category/reference.html`, `/blog/category/reference-page2.html`). Both obey the same placeholder rules; pick the style that fits your permalink scheme.
|
|
27
|
+
|
|
28
|
+
Render a category listing with the exported data registry:
|
|
29
|
+
|
|
30
|
+
```liquid
|
|
31
|
+
{%raw %}
|
|
32
|
+
{% assign categories = site.data.collection_pages.posts.category.pages %}
|
|
33
|
+
{% for entry in categories %}
|
|
34
|
+
{% assign name = entry[0] %}
|
|
35
|
+
{% assign docs = entry[1] %}
|
|
36
|
+
<h2>{{ name }}</h2>
|
|
37
|
+
<p>{{ docs.size }} posts</p>
|
|
38
|
+
{% endfor %}
|
|
39
|
+
{% endraw %}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Documentation + tutorials
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
collection_pages:
|
|
46
|
+
- collection: docs
|
|
47
|
+
field: section
|
|
48
|
+
path: documentation/sections
|
|
49
|
+
layout: doc_section.html
|
|
50
|
+
- collection: tutorials
|
|
51
|
+
field: difficulty
|
|
52
|
+
path: tutorials/level
|
|
53
|
+
layout: tutorial_level.html
|
|
54
|
+
paginate: 6
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
This setup produces unpaginated doc sections and paginated tutorial difficulty indexes. Use the metadata map for quick links and pagination helpers:
|
|
58
|
+
|
|
59
|
+
```liquid
|
|
60
|
+
{% raw %}
|
|
61
|
+
{% assign tutorials_info = site.data.collection_pages.tutorials.difficulty %}
|
|
62
|
+
{% for entry in tutorials_info.pages %}
|
|
63
|
+
{% assign label = entry | first %}
|
|
64
|
+
{% assign meta = tutorials_info.labels[label] %}
|
|
65
|
+
<a href="{{ meta.index.url | relative_url }}">View all tutorials for {{ label }}</a>
|
|
66
|
+
{% endfor %}
|
|
67
|
+
{% endraw %}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Project tags
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
collection_pages:
|
|
74
|
+
- collection: projects
|
|
75
|
+
field: tags
|
|
76
|
+
path: portfolio/tags
|
|
77
|
+
layout: project_tag.html
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
In your tag overview page:
|
|
81
|
+
|
|
82
|
+
```liquid
|
|
83
|
+
{% raw %}
|
|
84
|
+
{% assign projects_info = site.data.collection_pages.projects.tags %}
|
|
85
|
+
{% for entry in projects_info.pages %}
|
|
86
|
+
{% assign label = entry | first %}
|
|
87
|
+
{% assign items = entry | last %}
|
|
88
|
+
{% assign meta = projects_info.labels[label] %}
|
|
89
|
+
<a href="{{ meta.index.url | relative_url }}">{{ label }} ({{ items.size }})</a>
|
|
90
|
+
{% endfor %}
|
|
91
|
+
{% endraw %}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## One collection, multiple views
|
|
95
|
+
|
|
96
|
+
You can create pages based on multiple fields for the same collection:
|
|
97
|
+
|
|
98
|
+
```yaml
|
|
99
|
+
collection_pages:
|
|
100
|
+
- collection: books
|
|
101
|
+
field: genre
|
|
102
|
+
path: books/genre
|
|
103
|
+
layout: book_genre.html
|
|
104
|
+
- collection: books
|
|
105
|
+
field: author
|
|
106
|
+
path: books/author
|
|
107
|
+
layout: book_author.html
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Use `site.data.collection_pages.books.genre.pages` and `site.data.collection_pages.books.author.pages` to populate dashboards, and `site.data.collection_pages.books.genre.labels[label].index.url` when you need the generated index URL.
|
|
111
|
+
|
|
112
|
+
## Image gallery collections
|
|
113
|
+
|
|
114
|
+
```yaml
|
|
115
|
+
collection_pages:
|
|
116
|
+
- collection: gallery
|
|
117
|
+
field: tags
|
|
118
|
+
path: gallery/tags
|
|
119
|
+
layout: gallery_tag.html
|
|
120
|
+
paginate: 12
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Overview pages can link to tag indexes via the metadata map, and each generated page exposes `page.paginator` for navigation:
|
|
124
|
+
|
|
125
|
+
```liquid
|
|
126
|
+
{% raw %}
|
|
127
|
+
{% assign gallery_info = site.data.collection_pages.gallery.tags %}
|
|
128
|
+
{% for entry in gallery_info.pages %}
|
|
129
|
+
{% assign label = entry | first %}
|
|
130
|
+
{% assign meta = gallery_info.labels[label] %}
|
|
131
|
+
<a href="{{ meta.index.url | relative_url }}">View all in {{ label }}</a>
|
|
132
|
+
{% endfor %}
|
|
133
|
+
{% endraw %}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
```liquid
|
|
137
|
+
{% raw %}
|
|
138
|
+
{% if page.paginator %}
|
|
139
|
+
<nav class="pager">
|
|
140
|
+
{% if page.paginator.previous_page_path %}
|
|
141
|
+
<a href="{{ page.paginator.previous_page_path | relative_url }}">Prev</a>
|
|
142
|
+
{% endif %}
|
|
143
|
+
<span>Page {{ page.paginator.page }} of {{ page.paginator.total_pages }}</span>
|
|
144
|
+
{% if page.paginator.next_page_path %}
|
|
145
|
+
<a href="{{ page.paginator.next_page_path | relative_url }}">Next</a>
|
|
146
|
+
{% endif %}
|
|
147
|
+
</nav>
|
|
148
|
+
{% endif %}
|
|
149
|
+
{% endraw %}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Because those pagination paths already include the tag directory (`gallery/tags/<label>/…`), you can safely pipe them through `relative_url` without additional string concatenation.
|
|
153
|
+
|
|
154
|
+
## Troubleshooting
|
|
155
|
+
|
|
156
|
+
- Ensure every collection lists `output: true` if you expect to link to its documents.
|
|
157
|
+
- Verify each document sets the `field` you configured (use `site.collections[collection].docs | map: "path"` to inspect).
|
|
158
|
+
- Confirm the layout file exists and uses `{{ page.posts }}` or `{{ page.paginator }}` as required.
|
|
159
|
+
- When debugging, dump `site.data.collection_pages | jsonify` in a temporary page to inspect the computed groups, metadata, and generated paths.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Generated data reference"
|
|
3
|
+
category: "Reference"
|
|
4
|
+
description: "Learn the structure of site.data.collection_pages and use it to build custom indexes."
|
|
5
|
+
order: 4
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
The plugin exports data that mirrors Jekyll’s built-in `site.tags` and `site.categories` helpers, organized under a single hash. Use it to build dashboards, custom index pages, and sidebar navigation without re-walking `site.pages`.
|
|
9
|
+
|
|
10
|
+
## collection_pages
|
|
11
|
+
|
|
12
|
+
`site.data.collection_pages[collection][field]` returns a hash with:
|
|
13
|
+
|
|
14
|
+
- `template` → the full sanitized template used for creating pages with placeholders intact. Directory-style values from `_config.yml` are auto-appended with `:field/page:num/index.html`. (e.g. `/docs/category/:field/page:num/index.html`)
|
|
15
|
+
- `permalink` → the sanitized template for the index with placeholders intact (e.g. `/docs/category/:field/`)
|
|
16
|
+
- `pages` → documents grouped by label (`{ label => [documents...] }`)
|
|
17
|
+
- `labels`: metadata describing the generated index pages
|
|
18
|
+
|
|
19
|
+
### pages
|
|
20
|
+
|
|
21
|
+
`pages` generates a list of documents grouped by label (`{ label => [documents...] }`)
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
|
|
25
|
+
```liquid
|
|
26
|
+
{% raw %}
|
|
27
|
+
{% assign info = site.data.collection_pages.articles.tags %}
|
|
28
|
+
{% for entry in info.pages %}
|
|
29
|
+
{% assign label = entry | first %}
|
|
30
|
+
{% assign documents = entry | last %}
|
|
31
|
+
<h2>{{ label }} ({{ documents.size }})</h2>
|
|
32
|
+
<ul>
|
|
33
|
+
{% for doc in documents %}
|
|
34
|
+
<li><a href="{{ doc.url | relative_url }}">{{ doc.data.title }}</a></li>
|
|
35
|
+
{% endfor %}
|
|
36
|
+
</ul>
|
|
37
|
+
{% endfor %}
|
|
38
|
+
{% endraw %}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The structure is intentionally compatible with existing theme includes that expect `site.tags`.
|
|
42
|
+
|
|
43
|
+
### labels
|
|
44
|
+
|
|
45
|
+
`labels` exposes metadata about each generated index:
|
|
46
|
+
|
|
47
|
+
- `index`: the first generated index page (`index.html`)
|
|
48
|
+
- `pages`: array of all `TagIndexPage` objects
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
|
|
52
|
+
```liquid
|
|
53
|
+
{% raw %}
|
|
54
|
+
## Index of generated pages
|
|
55
|
+
{%- assign index_by_label = site.data.collection_pages.docs.category.labels %}
|
|
56
|
+
|
|
57
|
+
{% for entry in index_by_label %}
|
|
58
|
+
{% assign label = entry | first %}
|
|
59
|
+
{% assign info = entry | last %}
|
|
60
|
+
<h2> <a href="{{ info.index.url | relative_url }}">{{ label }}</a> ( {{ info.pages.size }})</h2>
|
|
61
|
+
<ul>
|
|
62
|
+
{% for entry in info.pages %}
|
|
63
|
+
<li><a href="{{ entry.url }}">Page {{ entry.page_num }}</a></li>
|
|
64
|
+
{% endfor %}
|
|
65
|
+
</ul>
|
|
66
|
+
{% endfor %}
|
|
67
|
+
{% endraw %}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Debugging tips
|
|
71
|
+
|
|
72
|
+
- Dump `site.data.collection_pages | jsonify` in a draft page to inspect the data structure during development (paths, permalinks, labels, and documents).
|
|
73
|
+
- Enable debug logging (`JEKYLL_LOG_LEVEL=debug bundle exec jekyll build`) to see the list of generated labels.
|
|
74
|
+
- When a label is missing, check the source documents for the configured field (case-sensitive).
|
|
75
|
+
|
|
76
|
+
Ready to render the maps? Jump to the [layout recipes](layout-recipes.md) for practical includes and UI patterns.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Layout recipes
|
|
3
|
+
category: "Usage"
|
|
4
|
+
description: "Practical Liquid patterns for rendering collection indexes, pagination, and integrations."
|
|
5
|
+
order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Use these recipes to tailor the generated pages, hook into pagination, or integrate with other plugins.
|
|
9
|
+
|
|
10
|
+
## Category/tag layout template
|
|
11
|
+
|
|
12
|
+
```html
|
|
13
|
+
{% raw %}
|
|
14
|
+
---
|
|
15
|
+
layout: default
|
|
16
|
+
---
|
|
17
|
+
<header class="collection-header">
|
|
18
|
+
<h1>{{ page.tag }}</h1>
|
|
19
|
+
<p>{{ page.posts | size }} items</p>
|
|
20
|
+
</header>
|
|
21
|
+
|
|
22
|
+
<section class="collection-grid">
|
|
23
|
+
{% for doc in page.posts %}
|
|
24
|
+
<article class="collection-card">
|
|
25
|
+
<h2><a href="{{ doc.url | relative_url }}">{{ doc.data.title }}</a></h2>
|
|
26
|
+
<p>{{ doc.data.excerpt }}</p>
|
|
27
|
+
</article>
|
|
28
|
+
{% endfor %}
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
{% if page.paginator %}
|
|
32
|
+
<nav class="collection-pagination">
|
|
33
|
+
{% if page.paginator.previous_page_path %}
|
|
34
|
+
<a href="{{ page.paginator.previous_page_path | relative_url }}">Previous</a>
|
|
35
|
+
{% endif %}
|
|
36
|
+
<span>Page {{ page.paginator.page }} of {{ page.paginator.total_pages }}</span>
|
|
37
|
+
{% if page.paginator.next_page_path %}
|
|
38
|
+
<a href="{{ page.paginator.next_page_path | relative_url }}">Next</a>
|
|
39
|
+
{% endif %}
|
|
40
|
+
</nav>
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% endraw %}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`previous_page_path` and `next_page_path` already include the generated tag directory, so `| relative_url` expands to the correct absolute link no matter how deeply nested the index lives.
|
|
46
|
+
|
|
47
|
+
## “View all” links from an overview page
|
|
48
|
+
|
|
49
|
+
```liquid
|
|
50
|
+
{% raw %}
|
|
51
|
+
{% assign info = site.data.collection_pages.docs.category %}
|
|
52
|
+
|
|
53
|
+
{% for entry in info.pages %}
|
|
54
|
+
{% assign label = entry | first %}
|
|
55
|
+
{% assign documents = entry | last %}
|
|
56
|
+
{% assign meta = info.labels[label] %}
|
|
57
|
+
<div class="category-summary">
|
|
58
|
+
<h2>{{ label }}</h2>
|
|
59
|
+
<p>{{ documents.size }} docs</p>
|
|
60
|
+
<a href="{{ meta.index.url | relative_url }}">View all</a>
|
|
61
|
+
</div>
|
|
62
|
+
{% endfor %}
|
|
63
|
+
{% endraw %}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Dynamic includes
|
|
67
|
+
|
|
68
|
+
If you already have a `post-index.html` include that expects `site.tags`-style input, the plugin’s data map just works. Pass the metadata map when you want each section to know its generated URL:
|
|
69
|
+
|
|
70
|
+
```liquid
|
|
71
|
+
{% raw %}
|
|
72
|
+
{% include post-index.html
|
|
73
|
+
collection=site.data.collection_pages.articles.tags.pages
|
|
74
|
+
collection_permalink=site.data.collection_pages.articles.tags.permalink
|
|
75
|
+
replace_value=":field"
|
|
76
|
+
meta=site.data.collection_pages.articles.tags.labels %}
|
|
77
|
+
{% endraw %}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## SEO & sitemap integration
|
|
81
|
+
|
|
82
|
+
`jekyll-seo-tag` reads `page.title`, so set it for nicer previews:
|
|
83
|
+
|
|
84
|
+
```html
|
|
85
|
+
{% raw %}
|
|
86
|
+
---
|
|
87
|
+
layout: default
|
|
88
|
+
title: "{{ page.tag }} – {{ site.title }}"
|
|
89
|
+
---
|
|
90
|
+
{% seo title=false %}
|
|
91
|
+
{% endraw %}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`jekyll-sitemap` includes generated pages automatically. To exclude a path:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
defaults:
|
|
98
|
+
- scope:
|
|
99
|
+
path: "docs/category"
|
|
100
|
+
values:
|
|
101
|
+
sitemap: false
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Multilingual layouts
|
|
105
|
+
|
|
106
|
+
When you maintain per-language collections, add a language code to your layouts:
|
|
107
|
+
|
|
108
|
+
```liquid
|
|
109
|
+
{% raw %}
|
|
110
|
+
{% assign fr_info = site.data.collection_pages.docs_fr.category %}
|
|
111
|
+
{% assign fr_page = fr_info.labels[page.tag] %}
|
|
112
|
+
{% if fr_page %}
|
|
113
|
+
<link rel="alternate" hreflang="fr" href="{{ fr_page.index.url | relative_url }}">
|
|
114
|
+
{% endif %}
|
|
115
|
+
{% endraw %}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Performance hints
|
|
119
|
+
|
|
120
|
+
- Use the exported data maps instead of iterating over `site.pages` to find generated pages.
|
|
121
|
+
- When rendering large grids, pre-sort with Liquid filters.
|
|
122
|
+
- Cache expensive loops in includes using capture if they are reused in multiple sections.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../../README.md
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Troubleshooting & FAQ
|
|
3
|
+
category: "Reference"
|
|
4
|
+
description: "Diagnose common issues and learn how to inspect the plugin’s output."
|
|
5
|
+
order: 7
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Having trouble seeing generated pages or data? Start here.
|
|
9
|
+
|
|
10
|
+
## Pages not created
|
|
11
|
+
|
|
12
|
+
- Ensure the target collection is defined with `output: true`.
|
|
13
|
+
- Confirm the `collection_pages` entry uses the correct collection name and field spelling.
|
|
14
|
+
- Run `JEKYLL_LOG_LEVEL=debug bundle exec jekyll build` to view the plugin’s log lines. They list each collection processed and how many pages were generated.
|
|
15
|
+
|
|
16
|
+
## Missing tags or categories
|
|
17
|
+
|
|
18
|
+
- Dump the data registry in a draft page:
|
|
19
|
+
|
|
20
|
+
```liquid
|
|
21
|
+
{% raw %}
|
|
22
|
+
<pre>{{ site.data.collection_pages | jsonify }}</pre>
|
|
23
|
+
{% endraw %}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If the label is missing, double-check the source document’s front matter.
|
|
27
|
+
|
|
28
|
+
- Remember that string fields are case-sensitive (`"Docs"` and `"docs"` create different pages).
|
|
29
|
+
|
|
30
|
+
## Pagination navigation broken
|
|
31
|
+
|
|
32
|
+
- When using `paginate`, render pagination links with `page.paginator.previous_page_path` and `page.paginator.next_page_path`. The plugin now emits paths that already include the generated tag/category directory (e.g. `docs/category/reference/`), so piping them through `relative_url` produces working absolute URLs.
|
|
33
|
+
- Verify the configured `paginate` value is a positive integer. Non-numeric values raise an error and zero/negative values fall back to single-page generation.
|
|
34
|
+
- To link back to the first page, use the page directory:
|
|
35
|
+
|
|
36
|
+
```liquid
|
|
37
|
+
{% raw %}
|
|
38
|
+
<a href="{{ page.dir | append: '/' | relative_url }}">Back to first page</a>
|
|
39
|
+
{% endraw %}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Path template errors
|
|
43
|
+
|
|
44
|
+
- `path` values must resolve to exactly one `:field` placeholder and one `:num` placeholder. Directory-style paths (no `.html`/`.htm`) automatically become `<path>/:field/page:num/index.html`, but explicit filenames must include both placeholders.
|
|
45
|
+
- `:field` must appear before `:num`, and they cannot live in the same path segment.
|
|
46
|
+
- When the build fails with an error referencing these placeholders, trim any trailing slashes and adjust the order. The generator logs the sanitized template in debug mode so you can confirm the final value.
|
|
47
|
+
|
|
48
|
+
## Liquid include expects `site.tags`
|
|
49
|
+
|
|
50
|
+
- Pass the plugin’s document map directly:
|
|
51
|
+
|
|
52
|
+
```liquid
|
|
53
|
+
{% raw %}
|
|
54
|
+
{% include post-index.html collection=site.data.collection_pages.docs.category %}
|
|
55
|
+
{% endraw %}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- If the include also needs the generated page URL, read `site.data.collection_pages[collection][field].labels[label].index.url` (or build it from the configured `path` plus the slugified label).
|
|
59
|
+
|
|
60
|
+
## Layout doesn’t see `page.posts`
|
|
61
|
+
|
|
62
|
+
- Make sure the layout file starts with front matter (`---` lines). Without it, Jekyll treats it as a static file and skips Liquid rendering.
|
|
63
|
+
- The variable is `page.posts` (not `page.documents`). When pagination is enabled, it shows only the current page’s slice; use `page.paginator.total_posts` for the total count.
|
|
64
|
+
|
|
65
|
+
## Still stuck?
|
|
66
|
+
|
|
67
|
+
- Open an issue with your `_config.yml` snippet and the relevant front matter.
|
|
68
|
+
- Compare your site with the demo in this repository (`demo/` directory) to spot structural differences.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
<ul>
|
|
5
|
+
{% for post in page.posts %}
|
|
6
|
+
<li><a href="{{ post.url | relative_url }}">{{ post.title }}</a></li>
|
|
7
|
+
{% endfor %}
|
|
8
|
+
</ul>
|
|
9
|
+
|
|
10
|
+
{% if page.paginator %}
|
|
11
|
+
<!-- Pagination is active -->
|
|
12
|
+
{% assign paginator = page.paginator %}
|
|
13
|
+
{% endif %}
|
|
14
|
+
<!-- Show navigation next/previous page links if applicable -->
|
|
15
|
+
{% if paginator.total_pages > 1 %}
|
|
16
|
+
<div class="paginate-container">
|
|
17
|
+
<div role="navigation" aria-label="Pagination" class="d-flex d-md-inline-block pagination">
|
|
18
|
+
{% if paginator.previous_page_path %}
|
|
19
|
+
<a class="previous_page" rel="prev" href="{{ paginator.previous_page_path | relative_url }}"
|
|
20
|
+
aria-disabled="false">Previous</a>
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% if paginator.next_page_path %}
|
|
23
|
+
<a class="next_page" rel="next" href="{{ paginator.next_page_path | relative_url }}">Next</a>
|
|
24
|
+
{% endif %}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
{% endif %}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
---
|
|
4
|
+
<div class="d-flex flex-wrap gutter border-top">
|
|
5
|
+
{% for post in page.posts %}
|
|
6
|
+
{%- if post.feature or forloop.first %}
|
|
7
|
+
{%- include post-feature-card.html %}
|
|
8
|
+
{%- else %}
|
|
9
|
+
{%- include post-card.html border="border-top" %}
|
|
10
|
+
{%- endif %}
|
|
11
|
+
{% endfor %}
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
{% if page.paginator %}
|
|
15
|
+
<!-- Pagination is active -->
|
|
16
|
+
{% assign paginator = page.paginator %}
|
|
17
|
+
{% endif %}
|
|
18
|
+
<!-- Show navigation next/previous page links if applicable -->
|
|
19
|
+
{% if paginator.total_pages > 1 %}
|
|
20
|
+
<div class="paginate-container">
|
|
21
|
+
<div role="navigation" aria-label="Pagination" class="d-flex d-md-inline-block pagination">
|
|
22
|
+
{% if paginator.previous_page_path %}
|
|
23
|
+
<a class="previous_page" rel="prev" href="{{ paginator.previous_page_path | relative_url }}"
|
|
24
|
+
aria-disabled="false">Previous</a>
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% if paginator.next_page_path %}
|
|
27
|
+
<a class="next_page" rel="next" href="{{ paginator.next_page_path | relative_url }}">Next</a>
|
|
28
|
+
{% endif %}
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
{% endif %}
|
data/demo/articles.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Articles
|
|
3
|
+
layout: page
|
|
4
|
+
style: topbar
|
|
5
|
+
permalink: /articles/
|
|
6
|
+
---
|
|
7
|
+
<h1>Articles</h1>
|
|
8
|
+
|
|
9
|
+
<div class="d-flex flex-wrap gutter-spacious">
|
|
10
|
+
<!-- This loops through the articles -->
|
|
11
|
+
{%- for post in site.articles %}
|
|
12
|
+
{%- if post.feature or post == site.posts[0] %}
|
|
13
|
+
{%- include post-feature-card.html %}
|
|
14
|
+
{%- else %}
|
|
15
|
+
{%- include post-card.html border="border-top" %}
|
|
16
|
+
{%- endif %}
|
|
17
|
+
{% endfor %}
|
|
18
|
+
</div>>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
../CONTRIBUTING.md
|
data/demo/directory.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Directory
|
|
3
|
+
layout: page
|
|
4
|
+
permalink: /directory/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Index of generated pages
|
|
8
|
+
{%- assign index_by_tag = site.data.collection_pages.articles.tags.labels %}
|
|
9
|
+
|
|
10
|
+
{% for entry in index_by_tag %}
|
|
11
|
+
{% assign label = entry | first %}
|
|
12
|
+
{% assign info = entry | last %}
|
|
13
|
+
<h2> <a href="{{ info.index.url | relative_url }}">{{ label }}</a> ({{ info.pages.size}} )</h2>
|
|
14
|
+
<p>
|
|
15
|
+
{% for entry in info.pages %}
|
|
16
|
+
<a href="{{ entry.url }}"> Page {{ entry.page_num }} </a>
|
|
17
|
+
{% endfor %}
|
|
18
|
+
</p>
|
|
19
|
+
{% endfor %}
|
|
20
|
+
|
|
21
|
+
## Pages by tag
|
|
22
|
+
|
|
23
|
+
{%- assign articles_by_tag = site.data.collection_pages.articles.tags %}
|
|
24
|
+
{%- assign index_permalink = site.data.collection_pages.articles.tags.permalink %}
|
|
25
|
+
|
|
26
|
+
{% for entry in articles_by_tag.pages %}
|
|
27
|
+
{% assign label = entry | first %}
|
|
28
|
+
{% assign documents = entry | last %}
|
|
29
|
+
{% assign tag_url = index_permalink | replace: ':field', label %}
|
|
30
|
+
<h2> <a href="{{ tag_url | relative_url }}">{{ label }}</a> ({{ documents.size }})</h2>
|
|
31
|
+
<ul>
|
|
32
|
+
{% for entry in documents %}
|
|
33
|
+
<li><a href="{{ entry.url }}">{{ entry.title }}</a></li>
|
|
34
|
+
{% endfor %}
|
|
35
|
+
</ul>
|
|
36
|
+
{% endfor %}
|
data/demo/docs.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Docs
|
|
3
|
+
layout: docs
|
|
4
|
+
toc: false
|
|
5
|
+
order: 1
|
|
6
|
+
permalink: /docs/
|
|
7
|
+
---
|
|
8
|
+
{% assign docs_info = site.data.collection_pages.docs.category %}
|
|
9
|
+
|
|
10
|
+
{% for category in docs_info.pages %}
|
|
11
|
+
{% assign label = category | first %}
|
|
12
|
+
{% assign documents = category | last | sort: "order" %}
|
|
13
|
+
{% assign info = docs_info.labels[label] %}
|
|
14
|
+
<h3><a href="{{ info.index.url | relative_url }}">{{ label | default: "Uncategorized" }}</a></h3>
|
|
15
|
+
<ul>
|
|
16
|
+
{% for entry in documents %}
|
|
17
|
+
<li><a href="{{ entry.url }}">{{ entry.title }}</a>
|
|
18
|
+
{% if entry.description %}
|
|
19
|
+
<p>{{ entry.description }}</p>
|
|
20
|
+
{% endif %}
|
|
21
|
+
</li>
|
|
22
|
+
{% endfor %}
|
|
23
|
+
</ul>
|
|
24
|
+
{% endfor %}
|
data/demo/gallery.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Gallery
|
|
3
|
+
layout: page
|
|
4
|
+
permalink: /gallery/
|
|
5
|
+
---
|
|
6
|
+
{%- assign tags_info = site.data.collection_pages.articles.tags %}
|
|
7
|
+
{%- assign tag_permalink = site.data.collection_pages.articles.tags.permalink %}
|
|
8
|
+
|
|
9
|
+
{% include post-gallery.html
|
|
10
|
+
collection=tags_info.pages
|
|
11
|
+
collection_permalink=tag_permalink
|
|
12
|
+
replace_value=":field"
|
|
13
|
+
per_section=3
|
|
14
|
+
%}
|
data/demo/index.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: page
|
|
3
|
+
style: stacked
|
|
4
|
+
title: jekyll-collection-pages demo
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Welcome to the jekyll-collection-pages Demo
|
|
8
|
+
|
|
9
|
+
Discover how jekyll-collection-pages can transform your site's organization and navigation.
|
|
10
|
+
|
|
11
|
+
## What is jekyll-collection-pages?
|
|
12
|
+
|
|
13
|
+
`jekyll-collection-pages` is a powerful plugin that enhances Jekyll's built-in collections feature. It allows you to:
|
|
14
|
+
|
|
15
|
+
- Automatically generate category and tag pages for your collections
|
|
16
|
+
- Create custom layouts for different types of content
|
|
17
|
+
- Implement pagination for your collection pages
|
|
18
|
+
- Organize your content with unprecedented flexibility
|
|
19
|
+
|
|
20
|
+
## Explore
|
|
21
|
+
|
|
22
|
+
### Documentation
|
|
23
|
+
|
|
24
|
+
See how `jekyll-collection-pages` organizes technical documentation:
|
|
25
|
+
- [Browse Documentation](docs.md)
|
|
26
|
+
|
|
27
|
+
### Articles
|
|
28
|
+
|
|
29
|
+
See how `jekyll-collection-pages` can organize collections like posts:
|
|
30
|
+
|
|
31
|
+
- [Tag directory](directory.md)
|
|
32
|
+
- [Tag index](tags.md)
|
|
33
|
+
- [Tag gallery](gallery.md)
|
|
34
|
+
|
|
35
|
+
## Get Started
|
|
36
|
+
|
|
37
|
+
Ready to use `jekyll-collection-pages` in your own project?
|
|
38
|
+
|
|
39
|
+
1. [Quick Start Tutorial](_docs/quick-start.md)
|
|
40
|
+
2. [Configuration Guide](_docs/configuration-guide.md)
|
|
41
|
+
3. [Troubleshooting and Tips](_docs/troubleshooting.md)
|
|
42
|
+
|
|
43
|
+
## News
|
|
44
|
+
|
|
45
|
+
<div class="d-flex flex-wrap gutter-spacious">
|
|
46
|
+
{%- assign latest_posts = site.articles | sort: "date" | reverse %}
|
|
47
|
+
<!-- This loops through the articles -->
|
|
48
|
+
{%- for post in latest_posts limit: 3 %}
|
|
49
|
+
{%- if post.feature or post == site.posts[0] %}
|
|
50
|
+
{%- include post-feature-card.html %}
|
|
51
|
+
{%- else %}
|
|
52
|
+
{%- include post-card.html border="border-top" %}
|
|
53
|
+
{%- endif %}
|
|
54
|
+
{% endfor %}
|
|
55
|
+
</div>>
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Community and Support
|
|
60
|
+
|
|
61
|
+
- [GitHub Repository](https://github.com/PrimerPages/jekyll-collection-pages)
|
|
62
|
+
- [Report an Issue](https://github.com/PrimerPages/jekyll-collection-pages/issues)
|
|
63
|
+
- [Contribution Guidelines](contributing.md)
|