A question is striking my mind right now.
If we say we go with your choice but notice in the long term, that it could be a dead end, how easily could we migrate to another generator?
A question is striking my mind right now.
If we say we go with your choice but notice in the long term, that it could be a dead end, how easily could we migrate to another generator?
This is a good question, and I think it's easy to switch between generators. Although other generators might be using a different templating language, we can migrate them in a short time as long as they are based on HTML. We only need to replace the way variables are present in different templates. For example some templates use {{{var}}} while others use {{var}}.
The only thing that can be tricky that I can think of is routing. Dynamic routing is implemented in different ways in different generators. But that is still doable. And if we switch a generator support dynamic routing to the one don't, then we'll have to fill in that part ourselves.
Can we use either Mustache or Handlebar for templating? This is what we use at the moment, and I'd rather not introduce yet another templating language in the code base.
In fact, what does a website builder like Astro help with? As an example, we'll need separate pages for each plugin and for that we'll need some custom scripting to parse manifests.json, inject variables into templates, etc. How would Astro make that easier?
Then for the front page, it's the same - mostly one static template with some injected variables. All that seems like a simple call to mustache.render('template.mustache', { ...variables })
. I'm just wondering what benefit we get with these website builders. It's still scripting, except with another layer of complexity.
@Retr0ve could you try to build it in Mustache or Handlebar and to a compare?
Hi laurent,
It can actually make the process easier. As your example, when separating pages for each plugin with Astro, we only need to use fetch()
to get the data from Github and feed it to a function Astro provides and Astro will take care of the rest. The point is, it reduce the complexity by hiding all the details and let me only focus on the website itself. And more, if we want to make the website can explore things other than plugins (such as templates) in the future, we only need to write a new template.
And also, Astro did a lot of things in the front end. For example, Astro can divide the page into components, allowing to reuse a HTML fragment on different pages. I use this feature to separate the navbar header and plugin card from the main layout to make the main layout easier to read in the demo. Usually, this requires additional js, and now it can be only a tag such as <PluginCard></PluginCard>
.
Of course, we can generate sites without the features I mentioned above, but why do the same work again when there is already a well-documented and tested framework?
Yes, it did add another layer of complexity, but I believe the convinence it brought outweigh the complexity. I am not advertising for Astro or any other frameworks, but I have to say that after two weeks with Astro, it did make the process easier than native HTML + js.
I understand that we don't want to introduce another templating language. But astro actually is easy and intuitive with nearly no learning cost. In Astro, variables are {var}
and that's it. Other logics are written in js in the head.
If you insist on not using this, then we have the alternative choice 11ty as I mentioned earlier. It supports Mustache, but missing a few features Astro has.
Mustache and Handlebar are for templating, and sadly Astro don't support them. If we want to use them, we have to switch to another generator.
fetch() to get the data from Github and feed it to a function Astro provides and Astro will take care of the rest.
In native JS it would be something like this:
const manifest = await fetch('...json');
const html = mustache.render('template.mustache', await manifest.json());
allowing to reuse a HTML fragment on different pages
That's a feature of the template system though, and Mustache, handlebar and just about any template system support fragments.
So I think there's two things:
The website builder - what specifically does it do and why do we need it? The fetch example is not very good since you can easily fetch data with plain Node.
The template system - apparently Astro only supports one such system. If it was somehow very useful perhaps it would make sense to switch to that system, but it's not clear (to me at least) that it is.
Thanks for your quick response!
The point about this example is not fetch()
, it is the function getStaticPaths()
Astro provides to render the pages. The difference between this function and mustache.render('template.mustache', await manifest.json());
is that mustache.render();
can only generate inside the template while getStaticPaths()
generates pages in bunch. We'll have to write code to generate individual page for each plugin under www.joplinapp.org/plugin/[pluginName]
if we are not using website builder. BTW, this is the dynamic routing I mentioned before.
As for templating, the functionality of this astro templating language is similar to others. Maybe a little difference is that it separate the components into files. And moreover, for future maintenance, it is easy to learn since there are no new things such as the code below and everything is in js.
Template:
{{#wrapped}}
{{name}} is awesome.
{{/wrapped}}
Hash:
{
"name": "Willy",
"wrapped": function() {
return function(text, render) {
return "<b>" + render(text) + "</b>"
}
}
}
If this is in Astro, then it will be like this.
---
function wrapped(){
return "Willy";
}
---
<b>{wrapped()} is awsome</b>
I can't say which one is better, Astro is just easier for me to get started. If you don't like it, we can switch to 11ty which supports Mustache.
Could you provide a complete example with getStaticPaths
? I think that will help seeing how it can help. Because for me if you need to generate multiple files, you can simply write a loop, but that's probably not what you mean.
Sure, this is the code I used in the demo.
export async function getStaticPaths() {
const pluginsRaw = await fetch('https://raw.githubusercontent.com/joplin/plugins/master/manifests.json').then(res => res.json());
return Object.values(pluginsRaw).map((plugin) => {
return {
params: { id: plugin.id },
props: { plugin },
};
});
}
The id is used to generate the path /plugin/[id]
Yes, but it provides a standard way to do this isn't it? Maybe later we want to add other things into this website, then we'll have to write another loop ourselves. And with the documents it provides, we can better maintain this code.
Sorry still not seeing what's the deal with this. It's just a plain JS function and, indeed, a loop, and it has nothing to do with the framework you're using.
As far as I can tell from this thread and your pull request, Astro is simply a template system. However we prefer to use Mustache for the reasons mentioned earlier.
could you go with Mustache and, if time allows, show what could be done easier with Astro?
I'm afraid this is not just a random function. This function is provided by Astro, inside this loop, I only convert this JSON to an array and nothing more. Astro did the rest in the backend including writing them into files, compacting static resources, etc.
Anyway, what should we do next? Do we switch to 11ty which support Mustache or you decided not to use a builder? I prefer to have a builder as the reasons above, but I'm fine if you wish there is none.
I think maybe let's go with Mustache first and leave the Astro version for now. The outcome of whether Mustache or Astro should be the same, the only difference is the dev process. If Laurent don't see anything special about Astro, I agreed it's better not to introduce new stuff into the code base of Joplin.
What I've been trying to understand is how different this builder is from a simple script that does the same job, and it's not clear from this thread. I assume we'll have the same problem with 11ty.
Again if you provide a complete example it might help seeing why you want to use a website builder so much. For example, a builder that takes the manifests as input and output a page for each plugin.
I pushed my demo code here. Hope it might be helpful.
In the code, things related to 'Dynamic Routing' are:
pages/plugin/[id].astro
. It tells Astro to generate a page with id
param under baseurl/plugin/[id]
.getStaticPath()
. It returns the pararms id
, then Astro knows how many pages to generate.yarn build
, it generate HTML files in dist folder.Hi, I just want to post a quick update here to let you know that I wrote a customized script to replace the original Astro or 11ty. It's small yet works better than any of those generators, you can see it in my PR. (The repo is private, so you might not be able to see it now.)