11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
16.89k stars 491 forks source link

Permalink functions causing exceptions #838

Open justinfagnani opened 4 years ago

justinfagnani commented 4 years ago

Describe the bug A permalink function in a data object is never being called, but it's presence is causing an exception.

To Reproduce Steps to reproduce the behavior:

  1. Create a JavaScript template like so:

page.11ty.cjs:

module.exports = class {

  data() {
    return {
      dynamicPermalink: false,
      permalink(data) {
        const date = data.page.date;
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return `/${year}/${month}/${day}/${data.slug}/`;
      },
    }
  }

  render(data) {
    return `<body>${data.content}</body>`;
  }
};
  1. Create a document:
---
title: Permalink Functions
date: 2019-12-30 15:00:00
slug: permalink-functions
---
Permalink functions don't seem to work...
  1. Run eleventy
  2. See error

If dynamicPermalink is true, this error is thrown:

`TemplateContentCompileError` was thrown
> illegal input

`AssertionError` was thrown:
    AssertionError: illegal input
        at assert (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/liquidjs/dist/liquid.common.js:1062:11)
        at parse (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/liquidjs/dist/liquid.common.js:1426:3)
        at Object.parse$$1 [as parse] (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/liquidjs/dist/liquid.common.js:3419:18)
        at Liquid.compile (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Engines/Liquid.js:181:29)
        at Markdown.compile (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Engines/Markdown.js:63:25)
        at TemplateRender.getCompiledTemplate (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateRender.js:192:26)
        at Template.compile (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateContent.js:167:42)
        at async Template.render (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateContent.js:181:16)
        at async Template._getLink (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Template.js:102:26)
        at async Template.getOutputHref (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Template.js:137:16)

If dynamicPermalink is false, this error is thrown:

> link.substr is not a function

`TypeError` was thrown:
    TypeError: link.substr is not a function
        at TemplatePermalink._cleanLink (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplatePermalink.js:10:23)
        at new TemplatePermalink (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplatePermalink.js:5:20)
        at Template._getLink (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Template.js:112:18)
        at Template.getOutputHref (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Template.js:137:27)
        at Template.getTemplates (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Template.js:397:34)
        at TemplateMap.initDependencyMap (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateMap.js:246:41)
        at async TemplateMap.cache (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateMap.js:279:5)
        at async TemplateWriter._createTemplateMap (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateWriter.js:124:3)
        at async TemplateWriter.write (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/TemplateWriter.js:155:3)
        at async Eleventy.write (/Users/justinfagnani/Projects/Personal/justinfagnani-com/packages/client/node_modules/@11ty/eleventy/src/Eleventy.js:428:13)

It looks like the permalink function is always interpreted as a string, and never called.

Expected behavior The permalink function is called.

Environment:

oliverjam commented 4 years ago

I just hit this issue as well. I think this might be the problem:

These will be parsed with the current template’s rendering engine
Use Data Variables in Permalink

Since your template is markdown the permalink is parsed using Liquid (the default Markdown templating engine), even though the permalink itself is defined in a JS file.

I initially worked around this by specifying the permalink using a Liquid string (e.g. permalink: "{{page.filePath}}"), but this breaks the second you have a different template engine. I have mostly markdown in a directory, plus some 11ty.js templates. The JS templates appear to just output the permalink as a string literal, so I get files like _site/{{page.filePath}}/index.html