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

Eleventy v3.0 Template Syntax plugin: Pug #3081

Closed
zachleat opened this issue Oct 27, 2023 · 17 comments
Closed

Eleventy v3.0 Template Syntax plugin: Pug #3081

zachleat opened this issue Oct 27, 2023 · 17 comments

Comments

@zachleat
Copy link
Member

Discussion here: #3074

This one is for @Aankhen

@zachleat
Copy link
Member Author

(and @Zearin)

@zachleat zachleat changed the title 3.0 template syntax plugin: Pug Eleventy v3.0 Template Syntax plugin: Pug Dec 18, 2023
@Zearin
Copy link
Contributor

Zearin commented Dec 30, 2023

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
Copy link
Contributor

Zearin commented Jan 6, 2024

I’m trying to get a quick-and-dirty Pug plugin working for my project in [email protected].

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

@zachleat:

  • How can I access the contents of my _data dir from a plugin?

Other Eleventy + Pug users:

  • Anyone else trying Pug on Eleventy v3?
  • What works?
  • What doesn’t?

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
Copy link
Contributor

Zearin commented Jan 18, 2024

(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
Copy link
Contributor

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

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

@Zearin
Copy link
Contributor

Zearin commented Jan 18, 2024

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
Copy link

Aankhen commented Apr 24, 2024

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

@grimsteel
Copy link

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
Copy link
Contributor

@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
Copy link
Member Author

zachleat commented Jul 5, 2024

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
Copy link

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

let fn = this.entry.compile.bind({
config: this.config,
addDependencies: (from, toArray = []) => {
this.config.uses.addDependency(from, toArray);
},
defaultRenderer: defaultCompilationFn, // bind defaultRenderer to compile function
})(str, inputPath);

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
Copy link
Member Author

zachleat commented Jul 9, 2024

@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
Copy link
Member Author

Started the pug port here: 11ty/eleventy-plugin-template-languages#13

@zachleat
Copy link
Member Author

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
Copy link
Member Author

zachleat commented Jul 24, 2024

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 zachleat added the needs-documentation Documentation for this issue/feature is pending! label Jul 24, 2024
@zachleat
Copy link
Member Author

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!!

zachleat added a commit to 11ty/11ty-website that referenced this issue Sep 26, 2024
@zachleat zachleat removed the needs-documentation Documentation for this issue/feature is pending! label Sep 26, 2024
@Aankhen
Copy link

Aankhen commented Sep 26, 2024

All hail our saviour Zearin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants