Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
Advertisement Create a free account Compendium in Game, Join Today

Sheet Templating with Handlebars

1585877288

Edited 1586038144
Creating a separate topic so this doesn't get lost / bogged down in Cassie's&nbsp; Functions and Other Useful Tips from a Pro In that thread, Cassie suggested using Pug, but some concern was raised about the barrier of entry that might represent. I'd like to suggest&nbsp; Handlebars &nbsp;as an alternative for consideration. At the most basic level, the "each" block can help cut down on a sequence of essentially copy-paste code with minor changes. index.handlebars &lt;div class="list"&gt; {{#each items}} &lt;div class="item"&gt;{{this}}&lt;/div&gt; {{/each}} &lt;/div&gt; data.json ["item1","item2","item3"] Yields the complete HTML: &lt;div class="list"&gt; &lt;div class="item"&gt;item1&lt;/div&gt; &lt;div class="item"&gt;item2&lt;/div&gt; &lt;div class="item"&gt;item3&lt;/div&gt; &lt;/div&gt; I created a basic command line interface to be able to generate a file from templates and a data.json without having to get into any scripting. A complete example can be found here:&nbsp; <a href="https://github.com/PrimalZed/handlebars-poc" rel="nofollow">https://github.com/PrimalZed/handlebars-poc</a> UPDATE 2020-04-04: I created a GUI to generate a file from templates and a data.json without having to install anything or use a CLI:&nbsp; <a href="https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.1.0-beta" rel="nofollow">https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.1.0-beta</a> Pros: Looks like HTML (or whatever file type you're templating), with handlebars blocks added in Inject data values anywhere directly into the HTML Can yield benefit with little effort - sheet authors can use as much or as little as they want Handlebars blocks have opening and close tags similar to HTML Easy to add new templates for re-use and organization Cons: Involves new syntax to learn and helpers to understand Built-In Helpers For advanced use:&nbsp; Additional Helpers For advanced use:&nbsp; Repeat Helper Requires Node.js installation and some command lines &nbsp;(now with GUI) What do you guys think? Would this be worth pursuing? I can build a boilerplate example to help others start using this on their own sheets. If this catches on, I can help contribute to a wiki page with more examples and explanation (although I won't claim to be a good teacher).
It might be worth noting that the `package.json` file in the example isn't strictly necessary. The `handlebars-rev` command can be installed globally: npm install handlebars-rev --global Once that is done, then the command can be run from any location: hbs-rev --main main.handlebars --data data.json --output my-sheet.html
1585909541

Edited 1585909588
GiGs
Pro
Sheet Author
API Scripter
My comments here are specifically regarding the idea of targeting this at newbies. I'm sure its a useful approach more generally and one I'm keen to read on, and I don't want to sound like I'm criticising you for doing this work. That said, I'm against any such framework being recommended for reasons I described in that other thread. For instance: Requires Node.js installation and some command lines That right there makes it a non-starter for unskilled volunteers. The advantage of roll20 (one might also say its a disadvantage too!) is that anyone can start editing the html and css files, and they can do it in basic text files, or in the roll20 editor. Anything that requires users to fiddle with a command line interface, or requires learning extra programming on top of the basics of html and CSS, before they can even start to edit a file, is not to be encouraged IMO. I think its easy for people familiar with these tools to forget just how much of a struggle this kind of thing is for volunteers. Bear in mind the amateur volunteers who make sheets massively outnumber the pros or semi-pros, and new ones will be arriving all the time, and the roll20 library of sheets is only as strong as it is because of these people. Their needs should come first.
1585915478

Edited 1585915665
GiGs I appreciate the response. Without dismissing the concerns, I want to point out that the premise isn't exactly correct: The advantage of roll20 (one might also say its a disadvantage too!) is that anyone can start editing the html and css files, and they can do it in basic text files, or in the roll20 editor. This is missing the current biggest barrier: Git. A contributor will have to: Create a GitHub account Fork the Roll20 repository Install Git (which itself is kind of intimidating, with a gamut of questions in the Windows wizard of increasing technicality) Clone their forked repository to the local (Create a new branch, hopefully, but this isn't strictly necessary and I'm sure most people just work off the master branch) Stage and push commits Merge updates from the Roll20 repository (which can be painstaking even for a professional) Create a Pull Request back to the Roll20 repository All that without any guidance that I can find on the Roll20 documentation. That's not to say that what I'm suggesting here should be automatically accepted. It may not be as significant &nbsp;of a barrier, but it is still an additional &nbsp;barrier. But amateur contributors are already expected to have at least some capacity to do this kind of thing. It is certainly not as straightforward as downloading and editing HTML and CSS. For those with a Pro account that want to have their own custom character sheet, even if it's modified from what's on the Roll20 repository, they can still do that without messing with Handlebars. The repository will still include in the root sheet folder the complete HTML and CSS, and these users can safely ignore any templating that was previously used to generate that. I also fully expect that, in order to accept something like this or SCSS as a common practice for complex sheets, guidance should have to be created in the Roll20 documentation. This isn't something people should have to "figure out", there should be step-by-step walkthroughs and examples. edit: I'd expect the biggest barrier in this proposal is understanding how to use Handlebars: what's a partial, what's a block helper, and how to use them.
1585918072

Edited 1585918283
GiGs
Pro
Sheet Author
API Scripter
Actually you dont have to do most of that - you dont need to use git. Most amateur contributors use github desktop, which handles most of that. All you need to do is create a github account, press the button to fork the account, press the button to download the repo edit your files open github desktop, which detects the changed files and prompts you to upload press the button which appears automatically to sync back to your fork enter some descriptive text to describe the&nbsp; pull request press the button which then appears to make a pull request And thats it - its a really simple process (assuming nothing goes wrong), no command line needed. Notice how often i typed "press the button" - it walks you the process and does all the work for you. The trickiest parts are the keeping your fork updated (for which there's now and install-and-forget app called pull), and creating new branches - which in github desktop is simply a matter of rightclicking the "master" heading and selecting "create a new branch" IIRC. And I'd add that even if you did need to install git and go through those steps, that does not justify adding extra steps. They may do that grudgingly, and each extra step is a point at which many will say, "okay, I've had it, I'm quitting."
1585919801
Finderski
Pro
Sheet Author
GiGs said: And I'd add that even if you did need to install git and go through those steps, that does not justify adding extra steps. They may do that grudgingly, and each extra step is a point at which many will say, "okay, I've had it, I'm quitting." I use the git desktop app and, honestly, it has still almost caused me to throw my hands up and quit a few times... :-/
1585921640
GiGs
Pro
Sheet Author
API Scripter
Finderski said: GiGs said: And I'd add that even if you did need to install git and go through those steps, that does not justify adding extra steps. They may do that grudgingly, and each extra step is a point at which many will say, "okay, I've had it, I'm quitting." I use the git desktop app and, honestly, it has still almost caused me to throw my hands up and quit a few times... :-/ Would you be more or less likely to quit if you had to install git, and use the command line to do everything?
GiGs I'd say even Git Desktop can be a hassle, but that's getting beside the point. Would you feel differently if I can provide a GUI for it? It shouldn't be too difficult to set up, but I'd need somewhere to host the executable.
1585922544

Edited 1585922645
Finderski
Pro
Sheet Author
GiGs said: Finderski said: GiGs said: And I'd add that even if you did need to install git and go through those steps, that does not justify adding extra steps. They may do that grudgingly, and each extra step is a point at which many will say, "okay, I've had it, I'm quitting." I use the git desktop app and, honestly, it has still almost caused me to throw my hands up and quit a few times... :-/ Would you be more or less likely to quit if you had to install git, and use the command line to do everything? Probably, yes. I don't do enough with git to remember all the commands, etc. I've had to use the command line a couple of times and it took me a lot longer than I really had time to devote to it. If I had to use the command line every time, I don't think I'd do it. Primal Zed said: Would you feel differently if I can provide a GUI for it? It shouldn't be too difficult to set up, but I'd need somewhere to host the executable. I can't speak for GiGs, but for me...maybe...it all depends on how complex the language is to learn and and what trouble shooting looks like. Right now I have only a very basic example provided above, but the sheet I have helped maintain is a lot more complex than those few lines.&nbsp; As for a place to host it...I could maybe provide that space on my website. EDIT : Though hosting it on GitHub may make more sense, since I may decide to take down my website...
1585922846
Kraynic
Pro
Sheet Author
I am on linux and have access to a couple different desktop and command line ways to deal with git.&nbsp; I just don't anymore, because I don't think it is worth it unless you are working on multiple sheets.&nbsp; Which I am not.&nbsp; 1.&nbsp; Work on files locally without downloading a fork/branch of the repository. 2.&nbsp; When you have the files tested to where you are comfortable releasing them, go to github on your browser and fork the Roll20 repo. 3.&nbsp; Edit the files of the sheet you have been working on. 4.&nbsp; Submit a pull request. 5.&nbsp; After it has been accepted/merged, go back and delete your fork repo when you happen to think of it. It is a lot easier than messing with all that other stuff when changes are several weeks apart.
1585923467

Edited 1585923530
GiGs
Pro
Sheet Author
API Scripter
Primal Zed said: GiGs I'd say even Git Desktop can be a hassle, but that's getting beside the point. Would you feel differently if I can provide a GUI for it? It shouldn't be too difficult to set up, but I'd need somewhere to host the executable. For me, I could use the command line. I'm not concerned for myself. What really matters to me is that anyone can come to a character sheet, and edit it without needing to learn anything more.&nbsp; I dont know enough about how handlebars works, but i expect it works similarly to pug/scss as suggested in the other thread, and I'm actively opposed to their use on roll20. Not just because it requires users learn new skills, but because it locks in a sheet to using it from then on: you end up with two sets of designers who are actively in opposition: some people want to edit the sheet without using pug, and others want to edit with pug, and their work is incompatible with each other (because they will overwrite each others work, and make it harder for them to incorporate each others work). This is antithetical to the purpose of the roll20 repo, which - in laymans terms - means no-one has ownership over the sheets there, and anyone is free to edit them. Anything which creates obstacles to that process should really be avoided. All that said, thank you for being very reasonable in your responses to my posts. I dont want to derail this thread further, I do think you should have the opportunity to showcase your work and help people use this process if thats what they decide to do.
1585930467
Scott C.
Forum Champion
Sheet Author
API Scripter
I think the important thing to consider here is that both this thread and Cassie's thread are not suggesting that these tools become mandatory for sheet development. They're simply additional ways for those of us that are looking for ways to streamline our projects so that they can be completed more quickly and with less repetitive coding. The roll20 editor itself and the github repo should continue to be just a basic html/css editor/repo. Once I've got my current project finished, I'll probably look at handlebars to use instead of pug as it's scoping mechanic is far preferrable to me than PUG's use of indentation ( shudder ).
Scott C. To GiGs' point, an individual contributor who wants to submit changes to the Roll20 repository does not have to make the decision to use templating or SCSS to find it thrust upon them. If the Roll20 repository folder for a particular game's character sheet gets updated to start using one of these tools, then all subsequent contributors will have to similarly use those tools. They would not be able to simply modify the published html and css, because then it will become misaligned with the source files. The next time someone else generates the html and css from the source files, then it will replace any other changes made on the html and css files. I'm obviously of the opinion that bringing in these tools remains worthwhile, but also understand that it can and will create a new barrier to other contributors. That's why I'm willing to try to lower those barriers as much as I can, but even after that there's still the question of whether it will be "low enough" for these tools to be promoted as a common practice. I'm pretty sure Cassie has gotten away with using Pug and SCSS so far primarily out of respect for the historic and continued efforts from Cassie to create, update, and maintain those sheets.
1585931475

Edited 1585931817
ᐰndreas J.
Forum Champion
Sheet Author
Primal Zed said: All that without any guidance that I can find on the Roll20 documentation. There are two guides that are linked in the main " Building character sheets " article. You may call the guide incomplete, insufficient or whatever, but there absolutely exist documentation on how to do things. <a href="https://wiki.roll20.net/Beginner%27s_Guide_to_GitHub" rel="nofollow">https://wiki.roll20.net/Beginner%27s_Guide_to_GitHub</a> <a href="https://wiki.roll20.net/Short_Git_Guide" rel="nofollow">https://wiki.roll20.net/Short_Git_Guide</a>
1585933646
Scott C.
Forum Champion
Sheet Author
API Scripter
While that's true Zed, it doesn't add a barrier to making your own sheets which is the important piece to me. If you are joining the volunteers that work on a given sheet, then you should be discussing their code with them rather than simply diving in and doing what you please to their code (as evidenced by the several sheets that have been broken this way over the last couple years).
Scott C. said: you should be discussing their code with them rather than simply diving in If you could tell me how to get in touch with the people maintaining the Chronicles of Darkness sheet , I'd love to do so! Not just in regards to my current PR , but also to talk about further (not-templating-related) updates I'd like to make.
1585956148

Edited 1585957018
admiralnlson
Pro
Sheet Author
So long as both the Roll20 "Custom Sheet" panel in Game Settings and the "Custom Sheet Sandbox" game-type are updated to natively&nbsp;integrate the data.json file as an option (i.e. the script Zed mentions runs server side), asking for a max of 4 files instead of the current 3, like this: - HTML (mandatory) - CSS (very recommended) - translation.json (recommended) - data.json (optional) Then I'm all for it (data-driven solutions ftw). Since the current Roll20 HTML syntax is already very specific and not at all valid HTML (rolltemplate conditionals are much worse to understand than these handlebars), I don't see this new feature as making things much worse for newbies to be honest. They wouldn't have to use it for their own custom sheets, just like they don't have to use rolltemplate conditionals (or rolltemplates altogether for that matter). If this new mechanic is not natively&nbsp; integrated into the actual Roll20 offer however, and there is a requirement for anyone to install npm, use a script or whatever, then this introduces the same limitations as Pug does (as mentioned in the other thread). For that, the policy I would recommend is: if you used special tools to generate the html file which is used by Roll20, and someone decides to update this generated html directly, then tough luck: you have to edit the html directly too now or retrofit whatever changes were made to the pug code or original html with handlebars yourself.
1585957127

Edited 1585957214
Scott C.
Forum Champion
Sheet Author
API Scripter
admiralnlson said: For that, the policy I would recommend is: if you used special tools to generate the html file which is used by Roll20, and someone decides to update this generated html directly, then tough luck: you have to edit the html directly too now or retrofit whatever changes were made to the pug code or original html with handlebars yourself. We're getting off topic for the thread, but I disagree strongly with you here. If someone is actively developing/maintaining a sheet and someone else introduces changes, then my view is the person who introduced the changes is essentially proposing a new feature. The actual author of that sheet might disregard the proposal and do something else to implement the feature or ignore the feature all together. I can't emphasize this enough; although the sheets are public, the correct protocol for getting involved with a sheet is to contact the author(s) and ask to volunteer/join the team. For really simple sheets, this may seem like overkill. But for complex sheets or commissioned sheets, which is where tools like this are most likely to be used, simply jumping in on a sheet and making changes without proper communication is a recipe for that sheet to quickly become inoperable. This same protocol is how you should get involved with an API script as well. There have been a couple times where I have notified Roll20 that a PR should be refused as it caused changes to code I was responsible for. In about half those instances, the proposed code would have caused large issues with the sheet/script as it currently stood or with updates I had planned. Now, if a sheet or script hasn't been updated in something like a year or more, and the author doesn't respond to a direct message on Roll20 in a reasonable time frame? Then, yes, that project has probably been abandoned and can be taken over by someone in the community.
1585957574

Edited 1585957675
admiralnlson
Pro
Sheet Author
I was not aware of this protocol. Thanks for pointing it out to me, Scott. Then I yield on that last part. But I still like the idea of the Roll20 team providing the tool Zed is proposing as a native integration within the Roll20 offer.
1585957825
Scott C.
Forum Champion
Sheet Author
API Scripter
No worries Admiral, it's not explicitly spelled out anywhere, but is good manners. Zed, sorry I missed your question about the CoD sheet. Based on the authors, it looks like that's an official Roll20 sheet, so I'd recommend emailing <a href="mailto:team@roll20.net" rel="nofollow">team@roll20.net</a> with questions or comments. Bugs for it should be posted to the bugs forum.
1585970340
GiGs
Pro
Sheet Author
API Scripter
That protocol may be good manners, and I agree it should be done out of politeness, but it's not a requirement, and we have to accept that anyone can jump in and modify a sheet at any time. Not everyone who wants to modify a sheet is involved in the forums, and many people wont know of this 'protocol' - which is purely invented by users and isn't in any of the written rules. I repeat something I said earlier: we do not have ownership over these sheets. In fact there have been a couple of cases in the past where this has happened-&nbsp; they have been conflicts, someone has modified a sheet that someone else is maintaining, and the maintainer has objected, and the roll20 staff maintaining the github have not taken sides. they have urged the two to work things out, and tried to act as go between, but when this happens, they will not uphold one over the other. In fact its an implicit part of the license we agree to when we post sheets to roll20: we might maintain a sheet, but it's not ours, and we have no control over it. This is why roll20 sheets are so successful: they can survive a sheet maintainer abandoning their project and moving on, and that will happen with most sheets sooner or later.
I have a basic GUI app set up to generate an HTML file from Handlebars templates: <a href="https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.1.0-beta" rel="nofollow">https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.1.0-beta</a> To try to minimize the number of steps, after the user selects the sheet directory it automatically tries to guess on the remaining information: Template file (the primary handlebars entry point): the first file found of: (directory)/src/*.hbs (directory)/src/*.handlebars (directory)/*.hbs (directory)/*.handlebars Data file (the json file with the data reference): the first file found of: (directory)/src/*.json (directory)/*.json Partials directory: the first folder found of: (directory)/src/partials (directory)/partials Output file name (the file to be created or updated on generate): the first file found of: (directory)/*.html With that, it should just be three easy steps to generate the HTML file: 1. Launch the application character-sheet-generator.0.1.0.exe 2. Select the Sheet Directory 3. Click "Generate!"
As before, you can try this out with the files from&nbsp; <a href="https://github.com/PrimalZed/handlebars-poc" rel="nofollow">https://github.com/PrimalZed/handlebars-poc</a> Next steps would be: More documentation, including a template (hoping to get some community assistance on this) "Generate CSS" from .scss in the same application Maybe some UI updates? Make the Data file optional? Please share your thoughts on this utility generator, and the proposal of using it for sheets in the public Roll20 repository
1586039596
ᐰndreas J.
Forum Champion
Sheet Author
So, which part of this makes it easier? Seems like a pretty complex way you need to piece things together, and you still have to write the code itself. Or am I missing something big?
1586039975

Edited 1586040006
The primary concern so far has been having to install Node.js and run command lines to generate the file from the templates. No one's actually mentioned anything about writing (and reading!) the handlebars code.
1586040049
ᐰndreas J.
Forum Champion
Sheet Author
I meant that the three-folded GUI didn't seem to simplify anything.
If you already have Node.js and are used to running a CLI then it really isn't any simpler. The feedback I received was that running a CLI can be considered too esoteric, while a GUI could make it more accessible.
1586040554
ᐰndreas J.
Forum Champion
Sheet Author
Are the Pros you counted weighted against plain HTML or PUG?
I haven't been counting. I got the general sense that there's interest in a templating tool from some authors, but there's also concern about learning new syntax or functionality and how to generate files from the template (something that Cassie's post didn't really cover). I'm suggesting Handlebars over PUG because it's literally the HTML code with inline template or data injection, not a whole new syntax for HTML. I was hoping that would address the concerns of new syntax. Since feedback in this thread has been focused on the barrier of generating the HTML file from the template, I've shifted my attention to that. I'm still open to the possibility that&nbsp; any &nbsp;utilities for creating HTML and CSS would be ruled a step too much for the community. I thought there was more interest than it than not, especially considering there's already many sheets using PUG and SCSS. You may recall that my first post on the topic was whether the source files are expected to be committed along with the produced HTML and CSS, and I feel that the answer I got was a pretty emphatic "Yes". If the community prefers to stick to solely HTML and CSS for the public repository, that doesn't actually prevent the more technically adept authors from having templating tools for their own use. It just means that the source files don't actually get committed to the repository, and those authors are taking on the burden of updating their source files as other contributors make their own commits.
1586051896

Edited 1586052061
admiralnlson
Pro
Sheet Author
Completely agree with you, Zed. I do prefer handlebars to pug too for the same reasons you mention. Thanks for the work you've put into this. In the end though, whether one uses Pug, Handlebars, whatever other tool is going to be available next year, or just plain HTML is a matter of personal preference. There's no point in debating which approach is better. The better tool is the one each one of us feels more comfortable with.
1589286547
GiGs
Pro
Sheet Author
API Scripter
Primal Zed, if you're still checking here, I tried the handlebars GUI with your test data and when clicking generate, it did not create any html file. Here's a screenshot of the folder structure just in case.&nbsp;
1589289890

Edited 1589289908
Sorry for the difficulty :&lt; I tried it with downloading the release file and re-downloading the poc handlebars files, and it works on my end. The only way I was able to reproduce this is by modifying one of the handlebars files with template code that would create a failure to compile. Best I can offer is that I can update the generator GUI to display any error messages to the user, rather than display "Success" regardless of whether it succeeds or fails. (I had intent to do that at one point, but completely forgot about it.) (I was surprised that Windows launched a warning against running the generator .exe I downloaded from github. I'm not sure what I can do about that. This was my first experience in creating an Electron application.)
1589335087
GiGs
Pro
Sheet Author
API Scripter
I was also surprised at the windows warning. I have just used the files from the poc-handlebars repo, with no changes and it doesnt generate anything. They were created by going to the raw vew for each file and downloading that. I have checked the file contents match the files on github. Still not working. If it can be made to work, it does look pretty simple (aside from the writing the code, lol). Actually using it would be fairly straight forward.
If it can be made to work, it does look pretty simple (aside from the writing the code, lol). Actually using it would be fairly straight forward. Thank you for the kind words. I set up a new version:&nbsp; <a href="https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.2.0-beta" rel="nofollow">https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.2.0-beta</a> Hopefully displaying the error message also works for whatever you're running into, and then I can resolve that. Maybe there are file-write restrictions occurring? I might have to try to get it to launch a "save-as" rather than just writing a file on the user's machine. Please let me know if this new app also generates the Windows warning.
1589423544
GiGs
Pro
Sheet Author
API Scripter
I still get the windows warning. This is the error it shows:&nbsp; Failure: "Parse error on line 1128:\n...pan class=\"pl-c1\"&gt;{{&lt;/span&gt;&lt;span class=\"\n-----------------------^\nExpecting 'ID', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', got 'INVALID'" Which the roll20 forums wants to make really big, lol. I do think you should have a Save As option anyway. I spent some time unsure if the program had failed, or if it had saved it somewhere and i just didnt know where.
Well shoot, idk what's up with the windows warning. I'll see if I can find anything else. That partial HTML doesn't look like anything from my handlebars-poc files. If you're using the folder like in your previous screenshot, I'm not sure what else it would be picking up. It looks like you have a file with &lt;span class="p1-c1"&gt;{{&lt;/span&gt; Since the handlebars templates use `{{` as a delimiter, you'll have to escape it with `\{{`. Turns out the electron save dialog doesn't actually write the file itself, it just gets a file path. The guidance is to still write the file with fs.write, which is what it's doing, so it's likely not some security concern that's blocking fs.write from working. I think having the Failure message rather than always saying Success is a strong enough indicator that it didn't create the file.
1589425666
GiGs
Pro
Sheet Author
API Scripter
I have no idea where that is coming from. Here are all the file contents from that folder: data.json { &nbsp;&nbsp;"primaryAttributeCategories":&nbsp;[ &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"name":&nbsp;"mental", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"attributes":&nbsp;["intelligence",&nbsp;"wits",&nbsp;"resolve"] &nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"name":&nbsp;"physical", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"attributes":&nbsp;["strength",&nbsp;"dexterity",&nbsp;"stamina"] &nbsp;&nbsp;&nbsp;&nbsp;}, &nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"name":&nbsp;"social", &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"attributes":&nbsp;["presence",&nbsp;"manipulation",&nbsp;"composure"] &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;] } index.handlebars &lt;div&nbsp;class="columns"&gt; &nbsp;&nbsp;{{#each&nbsp;primaryAttributeCategories&nbsp;as&nbsp;|primaryAttributeCategory|&nbsp;}} &nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="primary-attribute-category"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{#each&nbsp;primaryAttributeCategory.attributes&nbsp;as&nbsp;|primaryAttribute|&nbsp;}} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="primary-attribute"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="subheader"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="hidden"&nbsp;class="flag"&nbsp;name="attr_{{primaryAttribute}}_flag"&nbsp;value="0"&nbsp;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="toggle"&nbsp;name="act_{{primaryAttribute}}"&nbsp;data-i18n="{{primaryAttribute}}"&gt;{{capitalize&nbsp;primaryAttribute}}&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{&gt;&nbsp;dots&nbsp;attr=primaryAttribute&nbsp;count=5}} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{#unless&nbsp;@last}} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div&nbsp;class="horizontal-spacer"&gt;&lt;/div&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{/unless}} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{/each}} &nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt; &nbsp;&nbsp;{{/each}} &lt;/div&gt; &lt;script&nbsp;type="text/worker"&gt; &nbsp;&nbsp;{{&gt;&nbsp;worker}} &lt;/script&gt; main.scss (it's empty, lol) partials/dots.handlebars &lt;div&nbsp;class="dots"&gt; &nbsp;&nbsp;&lt;input&nbsp;type="hidden"&nbsp;class="dot"&nbsp;name="attr_{{attr}}"&nbsp;value="1"&nbsp;/&gt; &nbsp;&nbsp;{{#repeat&nbsp;count&nbsp;start=1}} &nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot{{&gt;&nbsp;gt&nbsp;@index}}"&nbsp;name="act_{{../attr}}_{{@index}}"&gt;&lt;/button&gt; &nbsp;&nbsp;{{/repeat}} &nbsp;&nbsp;{{!--&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot"&nbsp;name="act_{{attr}}_1"&gt;&lt;/button&gt; &nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1"&nbsp;name="act_{{attr}}_2"&gt;&lt;/button&gt; &nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2"&nbsp;name="act_{{attr}}_3"&gt;&lt;/button&gt; &nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2&nbsp;gt-3"&nbsp;name="act_{{attr}}_4"&gt;&lt;/button&gt; &nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2&nbsp;gt-3&nbsp;gt-4"&nbsp;name="act_{{attr}}_5"&gt;&lt;/button&gt;&nbsp;--}} &lt;/div&gt; partials/gt.handlebars {{#repeat&nbsp;(subtract&nbsp;this&nbsp;1)&nbsp;start=1}}&nbsp;gt-{{@index}}{{/repeat}} partials/worker.handlebars const&nbsp;primaryAttributes&nbsp;=&nbsp;[ &nbsp;&nbsp;"intelligence",&nbsp;"wits",&nbsp;"resolve", &nbsp;&nbsp;"strength",&nbsp;"dexterity",&nbsp;"stamina", &nbsp;&nbsp;"presence",&nbsp;"manipulation",&nbsp;"composure" ]; const&nbsp;attributeValues&nbsp;=&nbsp;["1","2","3","4","5"]; primaryAttributes.forEach(function(attr)&nbsp;{ &nbsp;&nbsp;attributeValues.forEach(function(value)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;on(`clicked:${attr}_${value}`,&nbsp;function()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[attr]:&nbsp;value &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;}); }); There are no other files in the folder (I have show hidden files set).&nbsp;
:( that's pretty bizarre. i'll go over the file reading code again to see if i can find anything
1589426129

Edited 1589426191
GiGs
Pro
Sheet Author
API Scripter
Aha, success! I had three separate handlebars folders, as I tried to figure out the the problem was being caused by the file location. the program was indexed to a folder which had a faulty file download in it. I'd found this yesterday and fixed it, but hadnt realised I was still using a location that had the faulty file in it. So it works!
That's a relief! It's not picking up files outside of the folder you selected, is it?
1589426993
GiGs
Pro
Sheet Author
API Scripter
No, wqhen saving the hboc files, I'd used saveas to save one of them by habit, and saved it as a html file (with githubs html embedded), and saved the filename to a handlbars file, and didnt notice. When I looked over them yesterday, i noticed one of the files was 89kb, and opened it up and saw all of githubs html. So I deleted and redownloaded the file, but didnt update it in all 3 locations - and the one location I had the program set was the one location that still had that copy of the file. Naturally. I have another problem. Not with the program, but with your sample code. It looks like the dots.handlebars paryial isnt working as intended. This is the code that is generated for the attributes: &lt;div&nbsp;class="dots"&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;type="hidden"&nbsp;class="dot"&nbsp;name="attr_dexterity"&nbsp;value="1"&nbsp;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot"&nbsp;name="act__1"&gt;&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1"&nbsp;name="act__2"&gt;&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2"&nbsp;name="act__3"&gt;&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2&nbsp;gt-3"&nbsp;name="act__4"&gt;&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;button&nbsp;type="action"&nbsp;class="dot&nbsp;gt-1&nbsp;gt-2&nbsp;gt-3&nbsp;gt-4"&nbsp;name="act__5"&gt;&lt;/button&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt; Notice that the action buttons are missing the stat name. I cant figure out the dots.handlebars file, it seems to have multiple different approaches.
Turns out the Windows security thing is because I don't have my code signed. I don't really want to pay an annual fee to get a signing certificate :( <a href="https://www.electronjs.org/docs/tutorial/code-signing#signing-windows-builds" rel="nofollow">https://www.electronjs.org/docs/tutorial/code-signing#signing-windows-builds</a> Regarding the attribute name on dots, you're correct I screwed something up on that. It should be `{{attr}}`, not `{{../attr}}`. I probably changed my mind on how to pass in the data at some point, and forgot to update that line. I pushed a fix to it&nbsp; <a href="https://github.com/PrimalZed/handlebars-poc" rel="nofollow">https://github.com/PrimalZed/handlebars-poc</a>
1589428111
GiGs
Pro
Sheet Author
API Scripter
That fixed it. :) I'd suggest having a really simple example file that doesnt use partials, as well as the example using partials - people encountering this will likely never have used handlebars before, and it's a lot to take in.
1589428524

Edited 1589428678
I'll think about some other examples tomorrow. Any requests? The handlebars-poc wasn't really intended to be a reference for learning handlebars. I set it up for demonstrating the CLI and GUI that can run the template to generate a file. The official site will probably be way better for getting started on handlebars:&nbsp; <a href="https://handlebarsjs.com/guide/" rel="nofollow">https://handlebarsjs.com/guide/</a>
1589435328

Edited 1589435379
GiGs
Pro
Sheet Author
API Scripter
Something very simple, like: JSON: { &nbsp;&nbsp;&nbsp;&nbsp;"Attributes":&nbsp;["strength",&nbsp;"dexterity",&nbsp;"constitution",&nbsp;"intelligence",&nbsp;"wisdom",&nbsp;"charisma"] } HBARS: &lt;div&nbsp;class="stats"&gt; &nbsp;&nbsp;&nbsp;&nbsp;{{#each&nbsp;Attributes&nbsp;as&nbsp;|Attribute|&nbsp;}} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span&nbsp;class="stat-name"&nbsp;data-i18n="{{Attribute}}-u"&gt;{{capitalize&nbsp;Attribute}}&lt;/span&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input&nbsp;class="stat-value"&nbsp;name="attr_{{Attribute}}"&nbsp;value="0"&nbsp;/&gt; &nbsp;&nbsp;&nbsp;&nbsp;{{/each}} &lt;/div&gt; I have been getting to grips with it tonight. I've been trying to add a Helper. Is that possible with this app, and if so how to do it? This is the helper btw: Handlebars.registerHelper('upper',&nbsp;function&nbsp;(aString)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;aString.toUpperCase() });
I didn't set up a way to add helpers. Instead, the generator registers a lot of helpers from a couple additional libraries: Built-In Helpers Additional Helpers &nbsp;(except the fs, html, logging, and misc helpers) Repeat Helper I figured these helpers should cover any desired scenario. For your use case, there is the "uppercase" string helper. I'll add some documentation to the generator to inform users of this.
1589498326

Edited 1589498337
I created a new release of the generator app:&nbsp; <a href="https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.3.0-beta" rel="nofollow">https://github.com/PrimalZed/character-sheet-generator/releases/tag/v0.3.0-beta</a> The main difference is an "About" page to provide more information about what's going on. I also added some new examples to&nbsp; <a href="https://github.com/PrimalZed/handlebars-poc" rel="nofollow">https://github.com/PrimalZed/handlebars-poc</a> &nbsp;- the previous example became "example-3", with relatively simpler "example-1" and "example-2". These examples include comments describing what each helper / partial call is doing. I still hold by looking at the Handlebars guide for more info on learning how it works, though.
1589499571

Edited 1589499613
GiGs
Pro
Sheet Author
API Scripter
Thanks for the links to helpers. The new versions help is very handy. I found the official handlebars guide pretty horrible and confusing, and got a lot more help just googling for specific issues and avoiding that site. I'm sure for people who are already familiar with the techniques it uses, it's great, but for total newbies, not so much. Your comments on example 2 are very welcome. Nice work. One thing I love about your program is it makes it easy to whip up sections of a sheet with lots of duplicated areas (skill lists, etc), without having to use it for a full sheet design.&nbsp; My view on roll20 and templating programs is they should be used primarily for the initial design, but once the sheet is on roll20, the designers have to accept that most contributors wont use them and will edit the html/css files directly. This makes rendering template engines useless for subsequent upgrades. But they are great as a tool to get that initial first version up far more quickly than would normally be the case, or for adding new sections to a sheet if you can do it in parts. This program is really handy for that, with no additional setup required.
One thing I love about your program is it makes it easy to whip up sections of a sheet with lots of duplicated areas (skill lists, etc), without having to use it for a full sheet design.&nbsp; That's the principle reason I pitched using a templating language. I felt that Handlebars was nice because it's inline with familiar code, and can be used as much or as little as desired. I understand not wanting to add an additional barrier for others, too. The approach you describe seems like a good compromise: ad-hoc usage to more quickly generate a chunk of code, rather than trying to establish a "source" to be maintained along with the generated output. I'm glad you're finding this useful.
I hope I can be forgiven for bringing this thread back up, but I just learned something I wanted to share: It turns out, roll templates actually use Mustache, a predecessor of Handlebars! I hadn't previously looked at roll templates, or I probably would have realized this sooner. It's more than coincidence that both use the {{ }} delimiters. The conditional {{#&lt;property&gt;}} followed by {{/&lt;property&gt;}}, and the inverse {{^&lt;property&gt;}} followed by {{/&lt;property&gt;}}, and the way helper functions are invoked, are also from mustache/handlebars. Calling Mustache a predecessor is maybe unfair, because it's still been maintained and improved in parallel with Handlebars. Handlebars is slightly more robust, but if I had realized that roll templates use Mustache I probably would have pitched templating with that rather than with Handlebars. (Although those helpers are pretty, well, helpful.) (I'm pretty sure the ${template:x} stuff isn't &nbsp;Mustache, but just custom parsing set up by Roll20.) (Another possibly-interesting revelation is that roll templates go through a markdown parser after the mustache renderer.)
1593915047
GiGs
Pro
Sheet Author
API Scripter
Interesting! Would Mustache have been a better solution than Handlebars?