-
-
Notifications
You must be signed in to change notification settings - Fork 495
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
Shortcodes #13
Comments
Very interesting! I like this idea. Are you tied to any specific templating engine? Looks like it’d be pretty easy to make some minor modifications here to get something working in Nunjucks using function calls and/or macros. I could get data imports working with https://mozilla.github.io/nunjucks/templating.html#macro
which works well with import for namespacing:
Lemme think about how to do this a little bit more. |
No, not tied to anything really! Just like the concept. The basic function call/macro mechanism sounds like the right base. NB Hugo also allows this kind of form, where the inline content can be processed as a further argument to the shortcode function/template:
|
Also considering something more future-compatible with some form of (no JS at runtime) web components. I think it’s very important to maintain a 0-JS output by default here. I don’t want this to turn into a JS framework. Discussion here https://twitter.com/zachleat/status/947206049228083201 Highlights |
Sorry to bikeshed in public but this looks very interesting. I’m leaning towards postHTML here, especially if I can post-process templates and keep this layer rendering engine agnostic: https://github.com/posthtml/posthtml-custom-elements A combination of custom elements and this would be quite interesting, I think: |
Boo to private bikesheds. Bike storage for the people! So, if I get the implication correctly, one could use this to create custom elements, that could be inserted into the markdown (or HTML) and expanded as a shortcode might be. Sounds good to me.
Right, I was only interested in JS running on the server (a node script) per shortcode / custom element, as required. Nothing on the client. |
One area where Hugo falls flat that I think would be a big win if you can swing it: Hugo has partials and shortcodes, and they're two separate things. You can reference a partial in a shortcode but not vice-versa, and partials can't accept arguments or variables. Being able to use repeatable code (with some conditional information) in both content and templates would be huge. I have a lot of content on my site that's similar but with small variations, and shortcodes help me keep the whole thing a lot more DRY and manageable. |
@cferdinandi |
@Heydon That looks awesome! Do you mind sharing the code behind that shortcode? (If its on that page, I'm sorry, but I can't find it.) |
@cferdinandi It's in the Cupper repo. It's really simple: https://github.com/ThePacielloGroup/cupper/blob/master/themes/cupper/layouts/shortcodes/snippet.html |
Thanks @Heydon ! |
Starting to look at this closer @cferdinandi, can you elaborate on a use case where you’d want to pass data from the shortcode to the partial? Trying to wrap my head around that. |
@zachleat For me, personally, it's less about passing info from a shortcode to a partial and more that I don't understand why Hugo treats them as two separate entities. This is perhaps a bias from my WordPress background, but I use repeatable content in both theme/template files and content. For example, I use an encoded version of my email address to minimize spammer harvesting. Sometimes that's embedded in content itself (like on my about page), while other times I use it in a template or theme file (hypothetically, like my footer). Today in Hugo, that's a shortcode and a partial, because you need both for both use cases. They each return a link element with the encoded email address as both the The shortcode version also allows me to pass in an optional query string to autopopulate a subject and body to the In an ideal world, there would be just one shortcode/partial type that would work everywhere and allow variables to get passed in. Did I explain that well? If I did a bad job explaining anything, please ask away! |
Just wanted to pop in here and say I had a brief discussion with @philhawksworth about this issue at VueConf a week+ ago and he opined that this kind of functionality might be best left to the templating engines. I think the example he used was Nunjucks macros? https://mozilla.github.io/nunjucks/templating.html#macro EDIT: doh Zach said the same thing above back in December. |
@zachleat @cferdinandi I've done this in Hugo, for Cloudinary support. I created a series of Hugo partials that generated the Cloudinary URLs and handled transforms. The shortcodes then just specified their shortcode logic (params, etc) and then passed the logic to the partials. This is necessary in Hugo, because you need to have a template file that encapsulates the shortcode logic. I don't think making shortcodes === partials would ever make sense in Hugo, as it would create a really ugly interface. However, in Eleventy you could have that all encapsulated in the plugin/config file, and just have a template that takes the standard data. |
Anyways, this should already be handled by Engine & Universal Filters, provided we build wider support for all engines. |
This all sounds great! FYI to consider: an alternative to postHTML is Reshape. I too am a fan of Hugo snippets but feel like they missed an opportunity to combine them with partials. You have to have code in 2 places if you want a partial and a snippet that outputs the same thing, or as mentioned a snippet that just then uses a partial internally and passes along the props. |
After reading all of the feedback about what y’all would like shortcodes to do (and making a working demo in Liquid), I think the best implementation here is going to wrap a nicer API around template engine Custom Tags. This should give you full access to template engine features (local variables, full tag access inside the shortcode, scoping, etc). While it isn’t template engine agnostic, I think it’ll be far more useful. |
Adds support for Shortcodes (supported in Nunjucks and LiquidJS). Fixes #13
v0.5.0 is out, with Shortcodes! |
I’m currently writing a shortcode for post excerpts/summaries: {%- for post in posts -%}
<article>
{% excerpt post %}
</article>
{%- endfor -%} Something along the lines of this: module.exports = function (eleventyConfig) {
eleventyConfig.addLiquidShortcode('excerpt', post => {
if (!post.templateContent) {
return;
}
const content = post.templateContent;
const excerptEnd = content.includes('<!--more-->')
? content.indexOf('<!--more-->')
: content.indexOf('\n\n');
return content.substring(0, excerptEnd).trim();
});
// …
}; Now, it seems like |
@kleinfreund can you open a new issue with this comment? Thanks! |
@zachleat Thanks, now using them in anger! |
@Heydon 👍 but oh no, why anger?? |
@zachleat LOL Actually, I'm having a bit of trouble with strings. In the following, just 'foo' would work, but 'foo bar' makes the template renderer crash? {% note 'Foo bar' %}
Hello world!
Bye.
{% endnote %} Here's the shortcode def (I had to put all the code on one line or it gets escaped): eleventyConfig.addPairedShortcode('note', function (content, title) {
return `<aside><h4>${title}</h4>${content}</aside>`;
}); |
@zachleat Fixed already? How can I complain? Cheers |
I'm wondering how shortcodes might be handled. I really like how Hugo uses shortcodes (https://gohugo.io/content-management/shortcodes/) but they would be even better if they could be run through node scripts (Hugo is written in Golang and has no support for this currently).
Essentially, I'd expect to be able to write little snippets that take arguments, referencing a script that outputs markup and injects it back as part of the processed template. E.g.
would run a script called
shortcodeName.js
that takes "foo" and "bar" then exports/returns markup with those values processed somehow.The text was updated successfully, but these errors were encountered: