11ty / eleventy-plugin-webc

Adds support for WebC *.webc files to Eleventy
https://www.11ty.dev/docs/languages/webc/
119 stars 10 forks source link

Webc file breaking permalink in directory data? #50

Closed robjwood closed 1 year ago

robjwood commented 1 year ago

Operating system

Windows 10

Eleventy

@11ty/eleventy@beta

Describe the bug

I'm getting an error in the terminal when I add a .webc file to a '/pages' directory.

Reproduction steps

I have a directory called '/pages/' with .md files inside it. There is a data file in this directory:

{
  "layout": "page.njk",
  "tags": "pages",
  "permalink": "/{{ page.fileSlug }}/"
}

This works fine

BUT

I added a .webc file into that directory with just this markup:

---
layout: base.njk
title: Results
---

I then get the following error in the terminal:

Original error stack trace: TypeError: link.slice is not a function

Has anyone experienced the same thing?

Expected behavior

I would expect the .webc file to render a page relative to the site route, just like the .md files do.

Reproduction URL

No response

Screenshots

No response

zachleat commented 1 year ago

The issue is that the permalink is interpreted as WebC after the data cascade is calculated. I think this is probably a common pitfall of setting permalink in the data cascade.

The workaround is to use a callback function instead of a template syntax for the permalink, which will be syntax independent.

This requires your data file to be js instead of json, for the record, something like this:

module.exports = {
  "layout": "page.njk",
  "tags": "pages",
  "permalink": function(data) {
     return `/${page.fileSlug}/`
  }
}
robjwood commented 1 year ago

Thanks for the response.

I managed to get around it by amending the input directories in the eleventy.config.js like this (a blatant copy from @darthmall's excellent 11ty.webc.fun site):

dir: {
  input: "src/pages",
  includes: "../components",
  layouts: "../layouts",
  data: "../data",
},

This negated the need for the directory data file, but it's good to know why this happens and how to get around it.

clindholm commented 1 year ago

The issue is that the permalink is interpreted as WebC after the data cascade is calculated. I think this is probably a common pitfall of setting permalink in the data cascade.

The workaround is to use a callback function instead of a template syntax for the permalink, which will be syntax independent.

This requires your data file to be js instead of json, for the record, something like this:

module.exports = {
  "layout": "page.njk",
  "tags": "pages",
  "permalink": function(data) {
     return `/${page.fileSlug}/`
  }
}

Hi,

I tried this:

function toPermalink(slug) {
    let cutPoint = slug.indexOf("_") + 1;
    slug = slug.substr(cutPoint);
    return `${slug}/`;
};

module.exports = {
    "layout": "chapter.webc",
    "permalink": data => toPermalink(data.page.fileSlug)
};

Works with .md files but not webc. I get this error:

link.slice is not a function (via TypeError)
[11ty] 
[11ty] Original error stack trace: TypeError: link.slice is not a function
[11ty]     at TemplatePermalink._addDefaultLinkFilename ([...]/node_modules/@11ty/eleventy/src/TemplatePermalink.js:86:25)
[11ty]     at TemplatePermalink.toOutputPath ([...]/node_modules/@11ty/eleventy/src/TemplatePermalink.js:95:26)
[11ty]     at TemplatePermalink.toPath ([...]/node_modules/@11ty/eleventy/src/TemplatePermalink.js:188:20)
[11ty]     at Template.getOutputLocations ([...]/node_modules/@11ty/eleventy/src/Template.js:308:19)
[11ty]     at async Template.addComputedData ([...]/node_modules/@11ty/eleventy/src/Template.js:614:28)
[11ty]     at async Template.getTemplates ([...]/node_modules/@11ty/eleventy/src/Template.js:682:7)
[11ty]     at async TemplateMap.initDependencyMap ([...]/node_modules/@11ty/eleventy/src/TemplateMap.js:410:22)
[11ty]     at async TemplateMap.cache ([...]/node_modules/@11ty/eleventy/src/TemplateMap.js:454:5)
[11ty]     at async TemplateWriter._createTemplateMap ([...]/node_modules/@11ty/eleventy/src/TemplateWriter.js:330:5)
[11ty]     at async TemplateWriter.generateTemplates ([...]/node_modules/@11ty/eleventy/src/TemplateWriter.js:360:5)

If I write it like this instead of the arrow function:

"permalink": function(data) { return toPermalink(data.page.fileSlug) }

I get a different error:

function(data) { return toPermalink(data.page.fileSlug) }
[11ty] ^^^^^^^^
[11ty] 
[11ty] SyntaxError: Function statements require a function name
[11ty]     at new Script (node:vm:100:7)
[11ty]     at createScript (node:vm:258:10)
[11ty]     at Object.runInNewContext (node:vm:299:10)
[11ty]     at ModuleScript.evaluateScript ([...]/node_modules/@11ty/webc/src/moduleScript.cjs:62:25)
[11ty]     at Object.<anonymous> ([...]/node_modules/@11ty/eleventy-plugin-webc/src/eleventyWebcTemplate.js:70:26)
[11ty]     at Template._renderFunction ([...]/node_modules/@11ty/eleventy/src/TemplateContent.js:398:27)
[11ty]     at Template.renderPermalink ([...]/node_modules/@11ty/eleventy/src/TemplateContent.js:447:19)
[11ty]     at async Template._getLink ([...]/node_modules/@11ty/eleventy/src/Template.js:252:24)
[11ty]     at async Template.getOutputLocations ([...]/node_modules/@11ty/eleventy/src/Template.js:302:16)
[11ty]     at async Template.addComputedData ([...]/node_modules/@11ty/eleventy/src/Template.js:614:28)

But still works with just .md files

zachleat commented 1 year ago

Related (and likely duplicate of): #47 #52 #32