-
-
Notifications
You must be signed in to change notification settings - Fork 504
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
Tags only applying to home page when using dynamic permalink #2178
Comments
I think this might be hard for me to reproduce locally unless you can send me a sample of what the But my guts tell me it's likely https://www.11ty.dev/docs/pagination/#add-all-pagination-pages-to-collections {
layout: "layouts/base.html",
pagination: {
data: "pages",
alias: "pg",
size: 1,
+ addAllPagesToCollections: true
},
tags: ['post'],
eleventyComputed: {
permalink: (data) => {
return data.pg.systemProperties.url;
},
}
} |
@pdehaan unfortunately that didn't seem to have any effect. Sample pages JSON here: [
{
"content": {
"body": ""
},
"systemProperties": {
"id": 1069,
"name": "Home",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "homePage",
"url": "/",
"urlSegment": "home"
}
},
{
"content": {
"body": ""
},
"systemProperties": {
"id": 1070,
"name": "Page 1",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-1",
"urlSegment": "page-1"
}
},
{
"content": {
"body": ""
},
"systemProperties": {
"id": 1071,
"name": "Page 2",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-2",
"urlSegment": "page-2"
}
},
{
"content": {
"body": ""
},
"systemProperties": {
"id": 1072,
"name": "Page 3",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-3",
"urlSegment": "page-3"
}
}
] |
@mark-reason Works for me in my sample sandbox: https://github.com/pdehaan/11ty-2178 INPUT---
pagination:
data: collections
size: 1
alias: tag
permalink: "/{{ tag | slug }}/index.html"
---
<h1>Tag: {{ tag }}</h1>
<ol>
{% set taglist = collections[ tag ] %}
{% for post in taglist | reverse %}
<li><a href="{{ post.url | url }}">{{ post.data.pg.systemProperties.name }}</a></li>
{% endfor %}
</ol> Here's my [generated] "post" archive page: <h1>Tag: post</h1>
<ol>
<li><a href="/page-3">Page 3</a></li>
<li><a href="/page-2">Page 2</a></li>
<li><a href="/page-1">Page 1</a></li>
<li><a href="/">Home</a></li>
</ol> Although the one weird bit in your sample "pages.json" data from your CMS is that the URLs don't always have a trailing slash, which is creating a "_site/page-1" file for me, instead of my preferred "_site/page-1/index.html" format. Not sure if you have control over those URLs, or if it's something you'll have to try and fix from the Eleventy side: "systemProperties": {
"id": 1070,
"name": "Page 1",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-1", // <<------- This right here.
"urlSegment": "page-1"
} Here's what my current output directory looks like: tree www
www
├── all/
│ └── index.html
├── index.html
├── page-1
├── page-2
├── page-3
└── post/
└── index.html
2 directories, 6 files |
And I added a few tweaks in a new [pending] PR, if you're curious: pdehaan/11ty-2178#1 Basically I excluded the "collections.all" tag archive pagination, because it somehow felt wrong. eleventyComputed: {
permalink(data) {
let permalink = data.pg.systemProperties.url;
if (!permalink.endsWith("/")) {
permalink += "/";
}
return permalink;
},
} I don't really know your site/config, so that might break other things, but it worked for me, so #YOLO. So now my new output directory looks like this: tree www
www/
├── index.html
├── page-1/
│ └── index.html
├── page-2/
│ └── index.html
├── page-3/
│ └── index.html
└── post/
└── index.html
4 directories, 5 files |
Hi @pdehaan Thanks for looking at this, I got this to work by adding addAllPagesToCollections: true into the pagination object (I didn't do this the first time as I misread your example) so thank you for that. The next step I'm trying to do is then populate the tags via the API by adding a content.categories property but this doesn't seem to work, any idea why that may be? ---js
{
layout: "layouts/base.html",
pagination: {
data: "pages",
alias: "pg",
size: 1,
addAllPagesToCollections: true
},
eleventyComputed: {
permalink: (data) => {
return data.pg.systemProperties.url;
},
tags: (data) => data.pg.content.categories
}
}
---
<h1>{{ pg.systemProperties.name }}</h1>
{{ pg.content.body | safe }} [
{
"content": {
"body": "Homepage",
"categories": ["Category 1", "Category 3"]
},
"systemProperties": {
"id": 1069,
"name": "Home",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "homePage",
"url": "/",
"urlSegment": "home"
}
},
{
"content": {
"body": "page one",
"categories": ["Category 2"]
},
"systemProperties": {
"id": 1070,
"name": "Page 1",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-1",
"urlSegment": "page-1"
}
},
{
"content": {
"body": "Page 2"
},
"systemProperties": {
"id": 1071,
"name": "Page 2",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-2",
"urlSegment": "page-2"
}
},
{
"content": {
"body": "Page number 3",
"categories": ["Category 1"]
},
"systemProperties": {
"id": 1072,
"name": "Page 3",
"createDate": "2021-06-09T12:17:48.38Z",
"updateDate": "2022-01-07T10:23:59.34Z",
"contentTypeAlias": "contentPage",
"url": "/page-3",
"urlSegment": "page-3"
}
}
] Cheers |
@mark-reason Good news, I think that's correct! // Somewhere in .eleventy.js
// Loop over your dynamic data from ./src/_data/pages.js and generate a unique set of categories/tags.
const dynamicTags = [...];
for (const tag of dynamicTags) {
eleventyComputed.addCollection(tag, function (collectionApi) {
return collectionApi.getFilteredByTag(tag);
});
} But that might help unblock you if you're trying to create archive pages for your dynamic pages/tags. |
Yep, this seemed to work for me. With the caveat that I'm using your sample file (saved as a local JSON file in my local ./src/_data/pages.json file). This might get more complex if you're fetching the data async. const pages = require("./src/_data/pages.json");
module.exports = (eleventyConfig) => {
eleventyConfig.addFilter("inspect", require("node:util").inspect);
const dynamicTags = pages.reduce((set, page = {}) => {
// Default to an empty array in case `page.content.categories` is `undefined` or `null`.
for (const cat of page.content?.categories || []) {
set.add(cat);
}
return set;
}, new Set());
for (const tag of dynamicTags) {
// Create a custom Eleventy collection based on our dynamically set tags.
eleventyConfig.addCollection(tag, function (collectionApi) {
return collectionApi.getFilteredByTag(tag);
});
}
return {
dir: {
input: "src",
output: "www",
},
};
}; OUTPUT"Page 2" had no categories, so doesn't appear in our category/tag archive below. tree www/
www/
├── category-1/index.html # "Page 3" and "Home"
├── category-2/index.html # "Page 1"
├── category-3/index.html # "Home"
├── index.html
├── page-1/index.html
├── page-2/index.html
├── page-3/index.html
└── post/index.html
7 directories, 8 files |
Amazing @pdehaan, I've managed to get that working with the remote data also like this: const fetch = require("node-fetch");
module.exports = (eleventyConfig) => {
fetch(ENDPOINT)
.then(function (response) {
response.json().then((pages) => {
const dynamicTags = pages.reduce((set, page = {}) => {
// Default to an empty array in case `page.content.categories` is `undefined` or `null`.
for (const cat of page.content?.categories || []) {
set.add(cat);
}
return set;
}, new Set());
for (const tag of dynamicTags) {
// Create a custom Eleventy collection based on our dynamically set tags.
eleventyConfig.addCollection(tag, function (collectionApi) {
return collectionApi.getFilteredByTag(tag);
});
}
});
});
return {
dir: {
input: "src",
output: "www",
},
};
}; One last question I've got and I was wondering if it is possible is regarding the tags page itself, that obviously uses the pagination set to 1 to generate all the different single tags pages, is there anyway to then paginate the posts (the output of collections[ tag ]) so it could then act as a standard paginated listing page rather than outputs all of the posts at once? I'm aware that if you know the collection name beforehand then you can use for example 'collections.post' and the normal pagination but that isn't an option here. Cheers |
@mark-reason Fantastic! As long as there aren't any timing issues between trying to run an async promise loop to create those tag collections, that looks like a good solution. Feel free to close the issue and open a new issue/discussion if you run into other issues. |
Ah, I missed the last question... |
Ah, I think my local version is already doing tag-based archive pages via your code snippet above: ---
pagination:
data: collections
size: 1
alias: tag
filter:
- all
permalink: "/{{ tag | slug }}/index.html"
---
<h1>Tag: {{ tag }}</h1>
<ol>
{% set taglist = collections[ tag ] %}
{% for post in taglist | reverse %}
<li><a href="{{ post.url | url }}">{{ post.data.pg.systemProperties.name }}</a></li>
{% endfor %}
</ol> But if you're looking for double pagination, this might issue/thread be useful: |
Double pagination looks to be working! const fetch = require("node-fetch");
const lodashChunk = require("lodash.chunk");
module.exports = (eleventyConfig) => {
fetch(`${process.env.BACKEND_API_URL}/umbraco/api/SiteMap/GetAllPages`)
.then(function (response) {
response.json().then((pages) => {
const dynamicTags = pages.reduce((set, page = {}) => {
// Default to an empty array in case `page.content.categories` is `undefined` or `null`.
for (const cat of page.content?.categories || []) {
set.add(cat);
}
return set;
}, new Set());
eleventyConfig.addCollection("pagedPostsByTag", function (collection) {
let paginationSize = 3;
let tagMap = [];
let tagArray = [...dynamicTags];
for (const tag of tagArray) {
let tagItems = collection.getFilteredByTag(tag);
let pagedItems = lodashChunk(tagItems, paginationSize);
console.log(tagItems);
for (
let pageNumber = 0, max = pagedItems.length;
pageNumber < max;
pageNumber++
) {
tagMap.push({
tagName: tag,
pageNumber: pageNumber,
pageData: pagedItems[pageNumber],
});
}
}
return tagMap;
});
});
});
return {
dir: {
input: "src",
output: "www",
},
};
} ---js
pagination: {
data: "collections.pagedPostsByTag",
alias: "tag",
size: 1,
},
permalink: "/{{ tag.tagName }}/{% if tag.pageNumber %}{{ tag.pageNumber + 1 }}/{% endif %}",
---
<h1>Tag: {{ tag.tagName }}</h1>
<ol>
{% for post in tag.pageData %}
<li><a href="{{ post.url | url }}">{{ post.data.title }}</a></li>
{% endfor %}
</ol> Thanks for all your help @pdehaan! |
Hi @pdehaan There's something else I'm trying with this and that's allowing a user to sort the paginated collection by date (and maybe other data in the future) via a filter on the front end. Would the best way to do this be by outputting the normal collection and then outputting another one with the posts then reversed? So you would have /category-1 and /category-1-reversed? Cheers |
Achieved the above by sorting the collection like so: const fetch = require("node-fetch");
const lodashChunk = require("lodash.chunk");
module.exports = (eleventyConfig) => {
fetch(`${process.env.BACKEND_API_URL}/umbraco/api/SiteMap/GetAllPages`)
.then(function (response) {
response.json().then((pages) => {
const dynamicTags = pages.reduce((set, page = {}) => {
// Default to an empty array in case `page.content.categories` is `undefined` or `null`.
for (const cat of page.content?.categories || []) {
set.add(cat);
}
return set;
}, new Set());
eleventyConfig.addCollection("pagedPostsByTag", function (collection) {
let paginationSize = 3;
let tagMap = [];
let tagArray = [...dynamicTags];
for (const tag of tagArray) {
let tagItems = collection.getFilteredByTag(tag);
const pagedItems = lodashChunk(tagItems, paginationSize);
const tagItemsSortNew = tagItems.reverse();
const pagedItemsSortNew = lodashChunk(tagItemsSortNew, paginationSize);
for (
let pageNumber = 0, max = pagedItems.length;
pageNumber < max;
pageNumber++
) {
tagMap.push({
tagName: tag,
pageNumber: pageNumber,
pageData: pagedItems[pageNumber],
});
}
}
for (
let pageNumber = 0, max = pagedItemsSortNew.length;
pageNumber < max;
pageNumber++
) {
tagMap.push({
tagName: `${tag}-sort-newest`,
pageNumber: pageNumber,
pageData: pagedItemsSortNew[pageNumber],
});
}
}
return tagMap;
});
});
});
return {
dir: {
input: "src",
output: "www",
},
};
} |
Hi, I'm using a dynamic permalink (generated from data from an API endpoint) but when I add tags to the page template's front matter and then output a tag page then only thing returned is the home page. Please see my code below.
pages/index.html (this outputs all my pages)
pages/tags.html (as per https://www.11ty.dev/docs/quicktips/tag-pages/)
So if I go to /post it should output all of my pages but currently it just outputs the homepage.
Cheers
Mark
The text was updated successfully, but these errors were encountered: