NotePlan Plugin Templating #89
Replies: 21 comments 27 replies
-
I would echo what @jgclark said before I got here…why not just mirror Templater (and use eta)? Then if people migrate over that have templates, they will just work. My only concern with using a library is speed and size. Every plugin that uses templates is going to get the whole ETA code, less any tree-shaking. My guess is this is why @nmn chose to write a small version of it. Whichever version you choose I hope it will provide for template function extension without requiring someone to edit core template files (which they do now)
…On Thu, Sep 16 2021 at 2:50 PM, Mike Erickson < ***@***.*** > wrote:
*******************
NotePlan Templating
*******************
--------
Overview
--------
There are a slew of templating libraries available in the JavaScript world
as it relates to templating and we could discuss the pros and cons ad
nauseum. Our aim is to implement a templating system that can be used
across all current and future NotePlan Plugins, paying close attention to
the common tasks such as conditionals, looping, method execution and data
pipe filter.
-----------------
Shared Templating
-----------------
Since most of the NotePlan users won’t have a programming background, I
think choosing a tool that is as user friendly as possible is important
and should be one of the primary factors that goes into our final
decision. On the other hand, we as plugin developers will be using the
templating tool the most, thus we need to make sure it supports all of our
current (and future) requirements.
-------------
Core Features
-------------
While we all have our own unique requirements, there are core features
which should be available in the library we settle on
* easy to read
* ability to execute javascript functions {{ myFunction() }} or <%
myFunction %>
* conditional branching ( if / else)
* looping
* pipe filter
* how well does it fit into NotePlan notes (make sure nothing breaks as a
markdown note)
-------------------------------
JavaScript Templating Libraries
-------------------------------
I have personally used handlebars a lot over the years, but I could just as
easily pick a tool such as nunjucks or eta as they have their own unique
set of features.
The following are some of the more popular templating libraries for
JavaScript and provide the most features to align with our current and
future templating needs.
There are obviously pros and cons to any templating library (this topic
could be discussed forever as I am sure everybody is going to have their
opinion).
>
>
> 📖 Refer to References at end of document for links to each library
>
>
* ejs (see comparisons with eta)
* eta (this is the one used by Obsidian Templater Plugin, perhaps a good
selection for attracting Obsidian user)
* handlebars (successor to mustache)
* swig (JavaScript port of Twig, a popular PHP templating tool used by
Symphony)
* squirrelly
>
>
> 💬 Jinja (popular in the Python world) has been mentioned on a github issues
> and there are two similar libraries for JavaScrip, see nunjucks or eta for
> more context.
>
>
Templating Libraries to Avoid
-----------------------------
One thing I would like to stress, there is a popular templating library
called pug (formerly jade) which should be avoided as the templates simply
will not work in NotePlan notes. They are dependent on indentation style
formatting (much like Python programming) and NotePlan notes fail in this
regard.
---------------
Templating Tags
---------------
If we ultimately decide to use nunjucks or eta , I feel we need to make
that decision sooner, rather than later, as it will require a shift from
current templating tags
Current Tags:
* {{ }}
Alternate Tags:
* <% %> used by eta
* {% %} used by nunchucks
----------
References
----------
eta ( https://eta.js.org/ )
handlebars ( https://handlebarsjs.com/ )
mustache ( https://mustache.github.io/ )
nunjucks ( https://mozilla.github.io/nunjucks/ )
pug ( https://pugjs.org/api/getting-started.html )
swig ( https://node-swig.github.io/swig-templates/ )
squirrelly ( https://squirrelly.js.org/ )
eta vs Ejs ( https://eta.js.org/docs/about/eta-vs-ejs )
templater ( https://github.com/SilentVoid13/Templater )
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub (
#89 ) , or unsubscribe (
https://github.com/notifications/unsubscribe-auth/ACEI6VAWIWFXKFBK7RP5VT3UCJRB7ANCNFSM5EFVWNNQ
).
|
Beta Was this translation helpful? Give feedback.
-
Thanks, @mikeerickson. I agree with all your requirements, and would add ... My original reason for raising the related issue (#11) was concern at the too-tight coupling between extension functions (my name for So I think there's a new requirement: the ability for a dev to write an extension function and be able to run it locally without having to submit it to 'the NotePlan team' for inclusion. I also wouldn't be surprised if a Template mechanism doesn't appear in the NotePlan app itself at some point. We're also actively discussing the plugin configuration mechanism getting direct support in the app. Therefore I think we should separate out these different concerns that the Template plugin currently handles in one place. So let's not forget that part of this is sorting out a more future-proof plugin framework, not just picking a templating language/library. I also wonder whether we have a requirement to be able to run (arbitrary?) JavaScript given as a parameter to future extension functions? On potential templating solutions, I have no experience to offer. And now I've just had a week off, I'm not going to be in a place for a while to go and do lots of research into the options. And, as you know, I'm still a JavaScript newbie, so I can't really evaluate that side of them anyway. |
Beta Was this translation helpful? Give feedback.
-
Sadly I am slammed with work and can’t spend enough time on this for a
bit. Also, I’m more of a hacker… :)
…On Thu, Sep 16 2021 at 6:18 PM, Mike Erickson ***@***.***> wrote:
@jgclark <https://github.com/jgclark> you are too modest my friend, you
are doing a fabulous job, even if it is a hobby.
@dwertheimer <https://github.com/dwertheimer> seeing as @jgclark
<https://github.com/jgclark> will be tight on time, let me know if you
want to tackle the initial tooling, or if you would like me to start. I
have plans this weekend to do some of my template required work, and I was
going to do a crude implementation, and will do so around eta regardless,
so just let me know.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VBG7GZ3MERMFDGI5U3UCKJPJANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
As a consumer rather than producer of templates, I would advocate for something that respects Postel's Law, and is generous with what it consumes. I have noticed already that constructs like this are very brittle with respect to white space:
Putting any space after the This hurts my brain because some of the syntax is for the template, and some of it is just Markdown within the template, and I can't tell which is which without staring at each character! I would hope for a solution that is more forgiving than this. Choosing a parameter syntax that doesn't look like Markdown will help. Another principle I tend to follow with templating is "less is more". As soon as your templating becomes an actual language, people will do crazy things with it. If it has anything more than rendering and formatting of values; branching; looping; inclusion/partials, then we are likely overthinking it IME. Finally, if there is a well-understood and well-respected templating/macro solution in the JS world that plays nice with Markdown (I don't know the state of the art enough to know) then I would advocate for that rather than reinventing any wheels. Thanks for listening! |
Beta Was this translation helpful? Give feedback.
-
@jgclark @dwertheimer |
Beta Was this translation helpful? Give feedback.
-
Some excellent input here. (I do love the way that as we inhabit different time zones I can always expect some useful progress happening while I'm hard at work ... sleeping!)
Sounds like we have agreement that this is our Plan A, and that we will:
Indeed, I suggest when the new And I'm very grateful to you, @mikeerickson, for being willing to get this new development underway. I stand ready to test, and to think ahead to future harder use cases. |
Beta Was this translation helpful? Give feedback.
-
@jgclark I feel the exact same about waking up in the morning (I usually get started around 5am) there will be meaningful notes, etc. from the other ends of timezones :-) However we can leverage I am eager to get this into your hands as quickly as possible so we fan start hammering on it and discover what changes will be necessary to support all the existing plugins, and what others will create in the coming weeks, months, years. And, I hope the code in this new project give inspiration to future plugin authors, as it will contain as much test case coverage as possible! |
Beta Was this translation helpful? Give feedback.
-
@dwertheimer so, i found your answer about speed
So, if we have a speed issue, it is not the library size 😀 |
Beta Was this translation helpful? Give feedback.
-
yeah, but I don't think we gzip and if (most) every single plugin has eta
bundled in, it that amount goes up geometrically. As you said, let's do
some tests. @EduardMe can run some profiles on the Swift side to see how
much time a plugin takes from load to finish. By the time we see it on our
side, it's already loaded.
…On Fri, Sep 17, 2021 at 3:06 PM, Mike Erickson ***@***.***> wrote:
@dwertheimer <https://github.com/dwertheimer> so, i found your answer
about speed
Eta's is weighing in at only 2.4KB gzipped!!
So, if we have a speed issue, it is not the library size [image: 😀]
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VA5Q6GXDVS2EIE32D3UCO3WVANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
@jgclark wanted to say thank you for sharing This is a nice little gem, I can already say it will replace my use of |
Beta Was this translation helpful? Give feedback.
-
yes. would be great if Noteplan could log to the console the elapsed time
of the plugin run --- from before you load it into memory, to when it
returns). We need to be able to test the overhead of loading the templating
library. We don't really need before/after if you give us elapsed time.
…On Sat, Sep 18, 2021 at 7:31 AM, Eduard Metzger ***@***.***> wrote:
You mean for executing a plugin? I can add time stamps before and after,
if it helps, which prints into the logs or console.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VHMC7VBFB3TGO2KIK3UCSPD5ANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
Of course. But we can't manipulate it if it's just output in the console,
so you'd have to pull out your calculator. that's why I thought it's better
if he just outputs the calculation (but it would be fine if he outputs
before/after/elapsed) — though you'd probably never use the before/after. :)
It will be interesting though to do a start/end/elapsed inside the
JS/plugin itself and compare it to the Noteplan timing.
…On Sat, Sep 18, 2021 at 7:40 AM, Mike Erickson ***@***.***> wrote:
If @EduardMe <https://github.com/EduardMe> does time before and after
plugin execution, we can do the math as well. I think it would be a “nice
to have” for any plugin command.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VHX2PFAXIBWWRSS5M3UCSQGNANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
np.Templating Status Update
Performance
|
Beta Was this translation helpful? Give feedback.
-
Mike you are amazing!
…On Sat, Sep 18, 2021 at 4:19 PM, Mike Erickson ***@***.***> wrote:
np.Templating Status Update
- Implement eta library
- Support global and namespace (template objects begin with np)
- Support Variables
- Support Custom Methods
- Support standard and extended mode (extended allows using all array
methods - .forEach, etc)
- All tests are passing
- All date utility functions accounted for (matching Templater)
- All note utility functions accounted for (matching Templater)
*[pending]*
- Support custom tags (plan to support {{ and }} provide testing is
favorable) *[pending]*
- Interface with NotePlan notes
- Migrate nmn.Templates utility methods used in other NotePlan Plugins
- applyNamedTemplate
- insertNamedTemplate
- getStructuredConfiguration
- getOrMakeConfigurationSection
- Custom Error Handler
Performance
- Speed is pretty awesome so far (see testing times, and this includes
test runner overhead)
[image: CleanShot 2021-09-18 at 16 13 57]
<https://user-images.githubusercontent.com/183153/133910834-fdef2400-1cc4-4b2e-a459-e7afd7289a7f.png>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VCOCRAVMPLVI2ASRTTUCUNABANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
For some Readwise improvements I wanted to make (getting a backup of all my highlights into Obsidian), I've needed to learn bits of the jinja2 templating system. It seems quite a close (python-based) parallel to eta. And in case it's that close, the one annoyance I've found is how it handles white space. It turned out to be much harder than expected to get spaces where I wanted them between multiple variables in output. It's just a little thing that we'll need to make sure we test ... |
Beta Was this translation helpful? Give feedback.
-
I would agree that using the default tags is preferred, and the only reason this item is there as it is an option for Eta natively, not something I am doing "custom". Implementation took all of 15 minutes (including creating all the tests).
No pressure there :-) Documenting this capability is something that may not even be exposed to public documentation, thus meaning that More to come... |
Beta Was this translation helpful? Give feedback.
-
@jgclark @dwertheimer @tastapod @EduardMe I have nested templates working! The following template produces data: const data = {
displayBooks: (config = {}) => {
let result = ''
config.books.forEach((book) => {
let row =
book?.TITLE?.length > 0
? config.full.replace('|AUTHOR|', book.AUTHOR).replace('|TITLE|', book.TITLE)
: config.partial.replace('|AUTHOR|', book.AUTHOR)
result += row + '\n'
})
return result
},
books: [
{ TITLE: 'The Sobbing School: Poems', AUTHOR: 'Joshua Bennett' },
{ TITLE: `Ain't No Mo'`, AUTHOR: 'Jordan E. Cooper' },
{ TITLE: 'A Particular Kind of Black Man', AUTHOR: 'Tope Folarin' },
{ TITLE: 'Where We Stand', AUTHOR: 'Donnetta Lavinia Grays' },
{ TITLE: 'Invasive species', AUTHOR: 'Marwa Helal' },
{ TITLE: 'The Sirens of Mars', AUTHOR: 'Sarah Stewart Johnson' },
{ TITLE: null, AUTHOR: 'Mike Erickson' },
],
} template:
output:
|
Beta Was this translation helpful? Give feedback.
-
OK, with some small adjustments to the template markup, I have gotten this working as well modified template:
output:
On this line, the following adjustments have been made:
But, other than these minor adjustments to the markup, the logic could be performed in the template, thus reducing need to call out to a magic method If you have a full template which you are currently using to produce something similar in complete, I will create appropriate tests to make sure it works. |
Beta Was this translation helpful? Give feedback.
-
So cool, Mike. Nice work!
…On Tue, Sep 21, 2021 at 4:39 PM, Mike Erickson ***@***.***> wrote:
@jgclark <https://github.com/jgclark> that will be the next major
development push.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#89 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ACEI6VDFVXADM5DBUSULTNTUDEJUFANCNFSM5EFVWNNQ>
.
|
Beta Was this translation helpful? Give feedback.
-
I remembered what seems like a significant detail that we've not yet discussed at all so far: how many different ways should there to to trigger these templates? In our architecture so far, the only way to trigger one of the plugin-defined I think adding this to our new framework would add flexibility and the ability to more easily use the power of the new framework. |
Beta Was this translation helpful? Give feedback.
-
I’m not sure I’m a fan of this. How does that work? If I type {{…}} in a note does it immediately get evaluated? Does it re-evaluate each time I open the note, or is it a one-off, in which case it can be inserted as a /-expression (eg. /date)?
This is different from eg. Hugo templates, where the template generates the static page so the page can contain partials and references to other templates, because NP doesn’t have a “build” as such; it’s just notes that you write. So NP “templates” are more like macros that you invoke on demand.
|
Beta Was this translation helpful? Give feedback.
-
NotePlan Templating
Overview
There are a slew of templating libraries available in the JavaScript world as it relates to templating and we could discuss the pros and cons ad nauseum. Our aim is to implement a templating system that can be used across all current and future NotePlan Plugins, paying close attention to the common tasks such as conditionals, looping, method execution and data pipe filter.
Shared Templating
Since most of the NotePlan users won’t have a programming background, I think choosing a tool that is as user friendly as possible is important and should be one of the primary factors that goes into our final decision. On the other hand, we as plugin developers will be using the templating tool the most, thus we need to make sure it supports all of our current (and future) requirements.
Core Features
While we all have our own unique requirements, there are core features which should be available in the library we settle on
{{ myFunction() }}
or<% myFunction %>
JavaScript Templating Libraries
I have personally used
handlebars
a lot over the years, but I could just as easily pick a tool such asnunjucks
oreta
as they have their own unique set of features.The following are some of the more popular templating libraries for JavaScript and provide the most features to align with our current and future templating needs.
There are obviously pros and cons to any templating library (this topic could be discussed forever as I am sure everybody is going to have their opinion).
Templating Libraries to Avoid
One thing I would like to stress, there is a popular templating library called pug (formerly jade) which should be avoided as the templates simply will not work in NotePlan notes. They are dependent on indentation style formatting (much like Python programming) and NotePlan notes fail in this regard.
Templating Tags
If we ultimately decide to use
nunjucks
oreta
, I feel we need to make that decision sooner, rather than later, as it will require a shift from current templating tagsCurrent Tags:
{{ }}
Alternate Tags:
<% %>
used byeta
{% %}
used bynunchucks
References
eta
handlebars
mustache
nunjucks
pug
swig
squirrelly
eta vs Ejs
templater
Beta Was this translation helpful? Give feedback.
All reactions