11ty / eleventy

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

Eleventy v3.0 Template Syntax plugin: Pug #3081

Closed zachleat closed 2 months ago

zachleat commented 11 months ago

Discussion here: https://github.com/11ty/eleventy/pull/3074

This one is for @Aankhen

zachleat commented 11 months ago

(and @Zearin)

Zearin commented 9 months ago

I'd like to test @11ty/eleventy@canary in a project with Pug. Is there a pre-release version of the Pug plugin available?

Zearin commented 9 months ago

I’m trying to get a quick-and-dirty Pug plugin working for my project in Eleventy@3.0.0-alpha.4.

I cannot get my plugin to see the contents of my _data directory. eleventyConfig.addGlobalData() does not seem to be doing it.

@zachleat:

Other Eleventy + Pug users:


Additional Context

I asked @zachleat on Mastodon about using Eleventy v2’s class Pug extends TemplateEngine as the basis for a plugin in Eleventy v3, but he told me that wasn’t possible because it’s incompatible with the Plugin API.

I don’t know Eleventy’s internals enough to figure out how to recreate its operation piece-by-piece in a plugin.

Since a common feature of plugins is to add template engines to Eleventy v3, please consider this post an additional request for more details on what the plugin API can—and importantly, cannot—do.

I want to be clear: I’m all for Eleventy v3 becoming more lightweight! (The weight loss with the v2 launch was incredible!) And Pug is indeed a hefty dependency.

But it would be really unfortunate if the v3 plugin’s capabilities are incapable of, or inferior to, the capabilities of a subclass of TemplateEngine.

Is it possible to match (or perhaps exceed) the DX for Pug in the plugin for Eleventy v3?


EDIT: Trimmed some over-dramatic nonsense at the end of Additional Context. (Sorry about that!)

Zearin commented 8 months ago

(COPIED FROM #3124)


@uncenter @Denperidge @Aankhen:

Zach gave me the go-ahead to start on an officially supported Eleventy v3 plugin for Pug. Here it is:

https://github.com/Zearin/eleventy-plugin-pug

P.S. – I code weird. I hate semicolons. You have been warned. P.P.S. – I’m a much better editor than a writer—or whatever the equivalent is for coding. Wanna collaborate? :D P.P.P.S. – Ah, you’ll figure it out :P

uncenter commented 8 months ago

P.S. – I code weird. I hate semicolons. You have been warned.

Zach might make you use his Prettier configuration at some point! 😆

Zearin commented 8 months ago

Zach might make you use his Prettier configuration at some point! 😆

That’s okay, but I’m calling dibs until the plugin’s out of beta ;-)

Aankhen commented 5 months ago

@Zearin, I just migrated to Canary thanks to your plugin. (At least, everything looks okay so far.) Great job, and thank you.

grimsteel commented 3 months ago

I found a way to use subclasses of TemplateEngine in plugins, by "poisoning" the eleventy template engine cache in the eleventy.extensionmap event

import type { UserConfig } from "@11ty/eleventy";
import TemplateEngine from "@11ty/eleventy/src/Engines/TemplateEngine.js";

// can't be named CustomEngine
class MyCustomEngine extends TemplateEngine {
  async compile(src: string, inputPath: string) {
    // this is like the compile function in normal custom engines but you get access to so much more (as it's a TemplateEngine subclass)
    return async (data: Record<string, any>) => {
      return "content";
    }
  }
}

export default (eleventyConfig: UserConfig) => {
  eleventyConfig.addTemplateFormats("custom");

  eleventyConfig.addExtension("custom", {});

  eleventyConfig.on("eleventy.extensionmap", extensionMap => {
    const extensionManager = extensionMap.engineManager;
    extensionManager.importCache["custom"] = Promise.resolve(BlocksEngine);
  });
};

using Eleventy v2’s class Pug extends TemplateEngine as the basis for a plugin in Eleventy v3

@Zearin it seems like you might find this useful

noelforte commented 3 months ago

@grimsteel, woah, that's a cool workaround! Wanted to chime in that depending on how #3310 resolves itself, hacking on top of eleventy.extensionMap may not be necessary, especially if friction between the Plugin API and the Template Engine API can be reduced in some capacity.

zachleat commented 3 months ago

Ah, can y’all be super clear about what’s missing here that requires the TemplateEngine subclass? addExtension creates a new CustomEngine instance which extends does already extend from TemplateEngine so you should have most of that power already available.

grimsteel commented 3 months ago

@zachleat, what's missing is getting access to that CustomEngine/TemplateEngine instance in the compile function.

https://github.com/11ty/eleventy/blob/922d9418ce5ab166e9bc719eb2b24019d45ca3fc/src/Engines/Custom.js#L188-L194

As far as I can tell, there's no way to access that instance (this) from either what's bound to the this for compile or the arguments passed to it.

In my case, I wanted to make a custom engine that produces sends its own output through Nunjucks, so I needed access to the Nunjucks engine through engineManager. (Basically, what Eleventy does with Markdown/Liquid)

There's a lot of information accessible with this.config, but it's not everything. (For instance, this.config.extensionMap only includes custom engines)

zachleat commented 2 months ago

@Zearin can you make a PR to add your pug to this official repository? https://github.com/11ty/eleventy-plugin-template-languages

This is where I’d like to have these extended template languages live moving forward.

If you’re too busy I can do this work too I just want to make sure you get the credit.

I created the ejs variant that hopefully gives you a good starting point for the conventions here but I did re-use a lot of the conventions from your pug repo here too (including moving the tests to use Node test runner!)

zachleat commented 2 months ago

Started the pug port here: https://github.com/11ty/eleventy-plugin-template-languages/pull/13

zachleat commented 2 months ago

For the remaining tests, there isn’t much more left to port over—just the test cases from this file: https://github.com/11ty/eleventy/blob/v2.x/test/TemplateRenderPugTest.js

zachleat commented 2 months ago

The official pug plugin v1.0.0-alpha.1 is now available https://www.npmjs.com/package/@11ty/eleventy-plugin-pug

Thank you @Zearin for the contribution!!

zachleat commented 1 week ago

The official pug plugin v1.0.0 is now available https://www.npmjs.com/package/@11ty/eleventy-plugin-pug

Even more thanks to @Zearin for the contribution!!

Aankhen commented 1 week ago

All hail our saviour Zearin!