Template Plugin

I would like to ask the community about what they feel about what all toolbar icons should be present?

1 Like

I don’t think “save as template” is needed in the toolbar. A typical user will not create many templates or change them in a daily basis. So it’s not a tool used regular und just takes away space. (Besides that a Save-Icon could be misleading). From my point of view it can just be in the drop down menu.

9 Likes

I am already very excited about this plugin :slight_smile:

If I times my small wish list

  • It should be possible to use tags in the templates
  • I would love it if the templates can also be saved as a note in a notebook and not only in the template directory, so that they are syncronized across multiple devices and I don't have to maintain the templates over and over again on each device.
  • Variables and a Dialog for the variables when creating a note from the template
    • {{VARIABLENAME:TYPE:OPTIONS}}
    • Dropdown: {{room:dropdown:[Selection 1, Selection 2, Selection 3]}}
    • Select: {{dark:select:[Yes, No]}}
      ...
  • Multiple use of variables in the document, but fill only once
7 Likes

You mentioned default templates, which is cool. I like the idea of being able to assign a keyboard shortcut to different templates so that I can use them as snippets. I think if they appear in the menu they could be assigned a shortcut? Not sure if that is out of scope of this.

This is cool. I have a CLI tool I built to make daily notes that does this. Basically it's a form I fill out that creates a new note with the variables from the form that I add to throughout the day. Would be nice to have a built in solution!

Yup, the main idea was to have two default templates one for note and one for todo and assign a keyboard shortcut to each of them.

2 Likes

I was thinking about this, and yes maybe this is possible. Instead of storing the templates in a directory, they can be stored in a separate notebook.

The way this can be implemented is

  1. Register a new setting that stores the id of the notebook the templates are in.
  2. If the notebook doesn't exist we create one and update the setting.
  3. The notes in these notebooks would represent templates.
  4. This way tags can also be added to templates.

This all can be done using Joplin Data API and settings Plugin API. What do you guys think about it?

/cc @JackGruber @CalebJohn

5 Likes

In my opinion, what you may need is Snippet instead of File Template. The former is to enter some preset keywords in the notes, and then generate some template text. The latter is to generate fixed content when creating a file (notes in Joplin). The main difference between the two is that the former is much more than the latter.

I would recommend to implement Snippet support, and then it would be better for users to add them easily, refer to:

For this, here's an idea.

Initially, we allow two types of variables text and dropdown. The variables need to be first declared like for text {{ Variable Name: Text }} and for dropdown {{ Variable Name: dropdown: [ Selection1, Section 2, Selection 3 ] }}. And then the values can be simply used as {{ Variable Name }}.

Implementation

  1. We first scan the text using regex and find all variables, their types. And remove the declarations from the text.
  2. Display a popup for taking input from the user for the variables.
  3. Use the mustache library, to replace all the variables names from the resultant text from step 1 with their values.
  4. Render the final text.

The future scope of this project can also be then to use an advanced templating engine to allow boolean variables etc. and if, else logic within the template.

Thoughts?

1 Like

Are there any existing templating engine that support this kind of syntax? I think it would worth investigating a bit what's being done so that we don't reinvent the wheel.

I feel mixing type definition with variable names makes for a heavy syntax and it means you need to redefine the type every time you use the variable in the document. For example, The {{room:dropdown:[Selection 1, Selection 2, Selection 3]}} is {{dark:select:[Yes, No]}} and the sky is {{dark:select:[Yes, No]}}.

I wonder if it should be separated - on one side the placeholders, on the other side the type definition. For example like this (using R Markdown header):

---
room: enum(Selection 1, Selection 2, Selection 3)
dark: boolean
---

The {{room}} is {{dark}} and the sky is {{dark}}
1 Like

Yes, makes sense. I'll investigate a bit on this and get back.

Actually, my idea was to separately declare variables something like

{{room:dropdown:[Selection 1, Selection 2, Selection 3]}}
{{dark:select:[Yes, No]}}

The {{ room }} is {{ dark ]}} and the sky is {{dark }}.

This is kind of similar to your R Markdown header idea but the syntax you suggested looks better.

---
room: enum(Selection 1, Selection 2, Selection 3)
dark: boolean
---

The {{room}} is {{dark}} and the sky is {{dark}}

So, I did some research on templating systems and I couldn't find a templating system that lets to declare to declare the variables and their types in the template itself. So, I guess we'll have to do that ourselves. Here's an updated idea of the implementation.

We follow the template syntax @laurent suggested,

---
room: enum(Selection 1, Selection 2, Selection 3)
dark: boolean
---

The {{room}} is {{dark}} and the sky is {{dark}}
  1. We use a library like markdown-it-front-matter and extract the YAML headers and use a regex like /---(.|\n)*---/ to strip off the yaml headers. Now, we have the variables and we can parse their values.

  2. We display a dialog to collect the user input for the variables. And then render the template.

  3. Also, I propose that we switch from mustache to handlebars because it's more powerful and it supports logic like if-else.

Thoughts?

2 Likes

That makes sense. Is there any standard syntax you could use for the type definition? I kind of made that one up, and if you can it's best to use an existing one so that you don't need to needlessly develop a custom parser.

It's up to you. Handlebars is indeed a good library.

Hey,
This sounds great!
If I may suggest a feature I was hoping to see in the near future:

  • Allow scripts inside the templates

Let me make a small example:
When researching papers I often find my sources on arxiv. To keep an overview about all the papers I've read and how they are linked to each other, I create a note based on a 'paper' template which has the title, fields for the author, abstract, link and the pdf file itself. At the moment, I always have to copy and paste the needed information although it should be relatively easy to extract them from arxiv directly, given the specific url.
Maybe allowing scripts in or around templates could allow for an autofill feature of parts of the templates by using Regular Expressions (or any other functionality to keep it general) on websites/files/any other source by only passing the url/path/.. to the template.

I'm not sure if this is too much to ask for in this plugin, maybe it could be separated into another plugin or maybe there is already a solution to this that I haven't found so far.

Anyway, good luck with the plugin and thank you for all your efforts!

1 Like

Hmmm, I can't think of a good UX to implement this feature. Can you think of how this feature would look?

Good idea. But I did some research and couldn't find any such parser that we can use in this case. We need a parser that could output the variables and type declarations in a string. I couldn't find something of that sort. So, I guess we can enforce our custom syntax for now. For the start I guess three types text, boolean and enum would be good enough. And the syntax that you made up looks good enough for that.

Mh, good question. Maybe it is possible to keep the script language inside the template .md file, like the declared variables.

Something like this with pseudo code:

---
url: text
parse_url: function(input1, ...)->text{
    return regex_magic(input1)
}
---

The abstract of the paper is {{parse_url(url)}}

I guess that could be one way to include functions in the template, how exactly it is implemented in the end is up to you. Of course, only if you think it is actually possible (and in your time frame).

Another option which might be easier to implement but which is also less user friendly would be to give a path to a script as a variable. Your suggested pipeline would then look something like this:

  1. We first scan the text using regex and find all user-definable variables and a script path, their types. And remove the declarations from the text.
  2. Display a popup for taking input from the user for the user-definable variables.
  3. Run the script based on the script path giving the user defined variables as input.
  4. Set variables from inside the script (can also be different to the user defined variables!)
  5. Render the final text.

This would mean that there would be two different types of variables inside the template, some that will be input by the user and some that will be computed by some script.

Example:

---
user_variable1: string
user_variable2: string
script_path: script('/path/to/simple_addition_script.js')
---

Since you gave me variable 1: {{user_variable1}} and variable 2: {{user_variable2}} I conclude that the sum of both is {{script_variable1}}

In this case user_variable1 and user_variable2 will force a popup to the user while script_variable1 will be set by the script (That is loaded at some point and takes user_variable1 and user_variable2 as input, computes the sum of both and returns a dictionary with all variables to set, in this case script_variable1).

Handlebars supports custom functions so maybe we can support this without much trouble? Although if it gets too complicated it's probably best to keep that as a possible stretch goal.

2 Likes

In past discussions there was a lot of pushback from users about having a dedicated notebook for templates. Do you have any thoughts around declaring template notes instead of templates? Or perhaps another solution?

No rush, but could you create a mockup of how you expect this too look?

I absolutely love this idea! Dealing with raw markdown files in a hidden file system folder is weird. Making templates a notebook is brilliant!

I'm a programmer but my wife is not, and she's switching to Joplin and enjoying that! That's something that doesn't happen very often with my other open source choices and is a good indicator about the app quality. I'm sharing this because yes, you can have scripts, handlebars and all that stuff, but don't forget about normal users basic use cases. Just providing a simple, integrated, straightforward way to manage templates would be a huge win.

I think most users will just put some text to replace and will never write a real place holder (although I'm not saying they aren't important).

Now just a couple of aspects to please keep in mind.

First, please make sure that, if any templates are shipped by default, they are translated. English-only defaults look like junk for non-native speakers. When I showed her Joplin for the first time, she liked it and said: "So, it's like Notion but in Spanish", and that was a deal breaker.

Also it would be nice if there were some way to easily share and download templates. In notion, for example, you can google for recipes templates, land in Notion – The all-in-one workspace for your notes, tasks, wikis, and databases. and, with one click, use it. When she tried the same for Joplin, she ended up into some random github repo with markdown files. Maybe supporting some joplin:// protocol would help? At least, opening a markdown file in Joplin should allow to save as template.