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

Permalink DuplicatePermalinkOutputError when using .webc with pagination in 2.0.0-canary.16 #36

Closed
rijkvanzanten opened this issue Oct 21, 2022 · 11 comments
Labels
bug Something isn't working

Comments

@rijkvanzanten
Copy link

rijkvanzanten commented Oct 21, 2022

Describe the bug

When rendering a paginated page that is a .webc component, I'm getting a DuplicatePermalinkOutputError. It seems to work as expected with njk or other rendering engines (from what I can tell). This feels very similar to 11ty/eleventy#2333, but seeing that was confirmed fixed, I'm not sure if it's the exact same cause.

To Reproduce

Setup the following structure:

src/
  _data/
    test.json
  index.webc
.eleventy.js

with the following contents:

src/_data/test.json

[{ "title": "Test 1" }, { "title": "Test 2" }, { "title": "Test 3" }]

src/index.webc

---
pagination:
  data: test
  size: 1
  alias: item
permalink: "thing/{{ item.title | slugify }}/"
---

<h1>{{ item.title }}</h1>

.eleventy.js

const pluginWebc = require("@11ty/eleventy-plugin-webc");

module.exports = function (eleventyConfig) {
	eleventyConfig.addPlugin(pluginWebc, {
		components: "./src/_components/**/*.webc",
	});

	return {
		dir: {
			input: "src",
			output: "dist",
		},
	};
}

When you try building the site with eleventy, witness the following error:

> eleventy 

[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] Output conflict: multiple input files are writing to `dist/thing/{{ item.title | slugify }}/index.html`. Use distinct `permalink` values to resolve this conflict.
[11ty]   1. ./src/index.webc
[11ty]   2. ./src/index.webc
[11ty]   3. ./src/index.webc (via DuplicatePermalinkOutputError)
[11ty]
[11ty] Original error stack trace: (Repeated output has been truncated…) [...truncated]

Expected behavior

By changing .webc to .njk or another rendering engine, note how it works as expected:

> eleventy

[11ty] Writing dist/thing/test-1/index.html from ./src/index.njk
[11ty] Writing dist/thing/test-2/index.html from ./src/index.njk
[11ty] Writing dist/thing/test-3/index.html from ./src/index.njk
[11ty] Wrote 3 files in 0.10 seconds (v2.0.0-canary.16)

WebC should work the same here

Environment:

  • OS and Version: macOS 12.6, Node 18.11.0
  • Eleventy Version: 2.0.0-canary.16
  • Eleventy Plugin WebC version: 0.5.1
@rijkvanzanten
Copy link
Author

FWIW the custom dir input/output configuration in .eleventy.js doesn't seem to matter for this bug

@rijkvanzanten
Copy link
Author

Update!

This is caused by the fact that the permalink is rendered by the engine used for the current file (for example a .liquid file uses Liquid for the permalink). For most of the default supported rendering engines, the {{ }} syntax for the permalink (as per the docs) works to render a basic string inline, however webc doesn't have such a syntax. Instead, to make things work, you gotta use permalink: 'books/<template webc:type="11ty" 11ty:type="njk">{{ book.title | slugify }}</template>/' instead of permalink: "books/{{ book.title | slugify }}/"

@rijkvanzanten
Copy link
Author

For other people coming across this, you can achieve the same without having to rely on a nested rendering engine as follows:

permalink: '/example/<template webc:nokeep @html="slugify(data.example)"></template>/'

@zachleat
Copy link
Member

Just for future visitors this bug was fixed with WebC v0.7.0! #27 No workaround needed!

@zachleat zachleat added the bug Something isn't working label Dec 16, 2022
@zachleat zachleat transferred this issue from 11ty/eleventy Dec 16, 2022
@zachleat
Copy link
Member

I am going to move this over to the Eleventy WebC plugin repo, thanks!

@zachleat zachleat added this to the Eleventy WebC Plugin v0.7.0 milestone Dec 16, 2022
@rijkvanzanten
Copy link
Author

I am going to move this over to the Eleventy WebC plugin repo, thanks!

My bad! Was still trying to find my way around the org structure at the time ☺️ Thanks for the fix!

@robb-j
Copy link

robb-j commented Dec 4, 2023

Hey, has this regressed? I've been getting the duplicate files error with the current versions of Eleventy & WebC.
I put together a repro repo if its helpful?

https://github.com/robb-j/eleventy-webc-pagination-permalink-repro

I'm trying to do a permalink with pagination and I can't get it working

layout: html.webc
pagination:
  data: members.users
  size: 1
  alias: member
  resolve: values
permalink: 'share/{{ member.username | hash }}/index.html'

@zachleat
Copy link
Member

@robb-j the takeaway here is that you can’t use njk or liquid syntax in a WebC template permalink. You need to use WebC syntax! #36 (comment) has a good explanation

@robb-j
Copy link

robb-j commented Dec 23, 2023

Hey @zachleat, I've tried that but it still doesn't seem to be working? I tried in the repro repo, so my webc page is this now:

---
layout: html.webc
pagination:
  data: members.users
  size: 1
  alias: member
  resolve: values
permalink: 'share/<template webc:type="11ty" 11ty:type="njk">{{ member.username | hash }}</template>/'
---

<main>
  <h1>Hello there</h1>
  <section class="headshot">
    <p>Hi, <template @text="member" webc:nokeep></template></p>
  </section>
</main>

paginating this data file:

{
  "users": [
    { "username": "geoff-testington" },
    { "username": "jess-smith" },
    { "username": "phil-wang" }
  ]
}

but I'm still getting the DuplicatePermalinkOutputError:

[11ty] Problem writing Eleventy templates: (more in DEBUG output)
[11ty] Output conflict: multiple input files are writing to `_site/share/<template webc:type="11ty" 11ty:type="njk">{{ member.username | hash }}</template>/index.html`. Use distinct `permalink` values to resolve this conflict.
[11ty]   1. ./page.webc
[11ty]   2. ./page.webc
[11ty]   3. ./page.webc (via DuplicatePermalinkOutputError)
[11ty] 
[11ty] Original error stack trace: (Repeated output has been truncated…)
[11ty]     at TemplateMap.checkForDuplicatePermalinks (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateMap.js:803:13)
[11ty]     at TemplateMap.cache (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateMap.js:488:10)
[11ty]     at async TemplateWriter._createTemplateMap (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateWriter.js:330:5)
[11ty]     at async TemplateWriter.generateTemplates (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateWriter.js:360:5)
[11ty]     at async TemplateWriter.write (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateWriter.js:407:23)
[11ty]     at async Eleventy.executeBuild (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/Eleventy.js:1191:13)

looking with DEBUG=1 there is another error actually:

Eleventy:WebC Error evaluating dynamic permalink, returning raw string contents instead: 'share/<template webc:type="11ty" 11ty:type="njk">{{ member.username | hash }}</template>/'
  Eleventy:WebC Error: Check the permalink for ./page.webc
  Eleventy:WebC Original error message: Unexpected token '<'
  Eleventy:WebC     at ModuleScript.evaluateScript (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/webc/src/moduleScript.cjs:71:10)
  Eleventy:WebC     at Object.<anonymous> (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy-plugin-webc/src/eleventyWebcTemplate.js:80:49)
  Eleventy:WebC     at Template._renderFunction (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateContent.js:405:27)
  Eleventy:WebC     at Template.renderPermalink (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateContent.js:454:19)
  Eleventy:WebC     at async Template._getLink (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/Template.js:251:24)
  Eleventy:WebC     at async Template.getOutputLocations (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/Template.js:301:16)
  Eleventy:WebC     at async Pagination.getPageTemplates (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/Plugins/Pagination.js:419:51)
  Eleventy:WebC     at async Template.getTemplates (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/Template.js:705:27)
  Eleventy:WebC     at async TemplateMap.initDependencyMap (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateMap.js:414:22)
  Eleventy:WebC     at async TemplateMap.cache (/Users/rob/tmp/eleventy-webc-pagination-permalink-repro/node_modules/@11ty/eleventy/src/TemplateMap.js:458:5) +1ms

@VAggrippino
Copy link

I don't understand how to make use of "no workaround needed" solution.

I tried this:

permalink: 'blog/history/<template webc:nokeep @html="pagination.pageNumber + 1"></template>/index.html'

I still have the DuplicatePermalinkOutputError.

I've read it has to be WebC syntax but that looks to me like a combination of HTML, WebC, & JavaScript syntax, and very much like a hacky workaround.

I'm probably doing something wrong.

I don't see any reason not to just use Liquid for the files that need pagination with a dynamic permalink.

@JanDW
Copy link

JanDW commented Jan 8, 2025

I couldn't quickly get any of the above suggestions to work, nor did I find the syntax palatable 😬, so let me add another suggestion in case it can help someone out.

Starting with Eleventy 3.0, you can use JS Frontmatter, this allowed me to build the permalink for pagination use as shown here:

---js
let layout = 'layout';
let pagination = {
  data: 'observations.selected',
  size: 50,
  alias: 'obs'
};
let permalink = function(data) {
  return data.pagination.pageNumber > 0 ? `observations/p${data.pagination.pageNumber + 1}/index.html` : 'observations/index.html';
};
---

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants