jadelet icon indicating copy to clipboard operation
jadelet copied to clipboard

Ideas

Open zdenko opened this issue 6 years ago • 14 comments

I have few proposals related to the great news :smile: Jadelet, because of its simplicity and aesthetics, is also my favorite choice whenever possible. So, I would like to see it moving forward and am ready to help. I already made some "improvements" (not published yet), i.e., upgrade to CoffeeScript 2, replaced deprecated packages (wrench => through2). And, last but not least, #21 and #6. I also started playing with adding support for template compiling (similar to #18) to different bundlers. I began with Parcel, which is my preferred choice.

Example:

  • main.coffee
import jadelet from "jadelet"
import Tmpl from "./templates/intro.jadelet"

main = 
  name: "Joe"

document.getElementById("app").appendChild Tmpl main
  • template (templates/intro.jadelet)
h1 Hello #{@name}

Plugins for other bundlers (Webpack, Rollup) could be prepared as well. I think this would make an easier start for new users.

Let me know.

zdenko avatar Jun 28 '18 10:06 zdenko

Hi zdenko,

Sorry I haven't been very responsive on this. I've taking some time to update Jadelet again and welcome any contributions along these lines.

I've also got some ideas for an even simpler version that could remove the dependence on CoffeeScript completely by removing code in the templates. In my more recent work I've noticed that I generally avoid logic and iteration in the templates themselves. As the most active member of the Jadelet community I'd love to hear your feedback sometime.

Thanks!

STRd6 avatar Jul 03 '19 23:07 STRd6

Nice having you back 😄 Lately, I hadn't had much chance to use Jadelet as much as I would like to. Due to the current hype around existing frameworks and libraries, and for the sake of the rest of the team, I have to give in and try not to react in the wrong way (pun intended). But, whenever I can, I come back to the lightness of Jadelet.

By removing the code from the templates you mean remove logic completely, or get rid of Coffeescript? Avoiding logic and iterations in templates is also my preference in any templating/rendering solution. The outcome of this is short and light template files. More often then not you end with just a line or two of the template code. A while ago I was playing with the idea of having the code in a single file, e.g. like this:

<template>
div
  button(click=@increment) Increment
  label= @count
</template>

self =
  count: Observable(0)
  increment: -> @count.increment()

This is similar approach as in Vue.js, Riot.js, or Svelte

But, I feel that such simplicity can increase organizational efforts. By breaking the code into "reusable components," you need to think ahead what to put where, and how to efficiently nest components. I guess there's no clear winner, as in the end, it all depends on the task one tries to solve.

Can you share details of some of your ideas if possible? Is observable still in your path?

zdenko avatar Jul 13 '19 09:07 zdenko

I know this is old... but better late than never :P

What I've been doing recently is using template strings in JS or multiline strings in CoffeeScript like this:

Template = Jadelet.exec """
app
  .toolbar
    button(click=@save) Save
  @content
"""

document.body.appendChild Template
  save: -> alert "pretend this saved"
  content: contentElement

It works pretty well for my use cases and is nice and simple and doesn't require any additional build processes or tools.

Good luck!

STRd6 avatar Sep 02 '21 19:09 STRd6

This looks cool, but I can't figure out where Jadelet.exec, and contentElement come from. Could you elaborate on this example?

zdenko avatar Sep 04 '21 02:09 zdenko

I think in this version it's actually Jadelet.compile. contentElement is just a placeholder for any arbitrary element to insert into the template demonstrating adding more than just a button to the template.

I may have Jadelet v2 ready sometime soon. It's quite a bit smaller and faster.

STRd6 avatar Sep 04 '21 06:09 STRd6

it's actually Jadelet.compile

Ah, that makes sense. But in that case, you have to set the compiler property, which is Coffeescript, if I'm not mistaken. That's quite heavy for browser use. Or, is there some other alternative to CS?

I may have Jadelet v2 ready sometime soon

😮 Who do I have to bribe to get access to it? 🙏

zdenko avatar Sep 04 '21 09:09 zdenko

which is Coffeescript, if I'm not mistaken. That's quite heavy for browser use. Or, is there some other alternative to CS?

I think I got this. 😄 CS is required to compile the source in the compile. If I convert a few lines in the compiler.coffee from CS source to JS, then CS is not needed anymore. And, in jadelet template strings, I just use JS. For example:

h1= this.title

zdenko avatar Sep 04 '21 12:09 zdenko

@zdenko that's pretty much it 🎊 I'll see if I can update this repo with a copy of Jadelet v2. I've been doing most of my development in whimsy.space so I don't use GitHub much anymore.

STRd6 avatar Sep 04 '21 14:09 STRd6

Just pushed a preview of Jadelet2 to dist/jadelet2.js and updated the changelog. It's usable in the browser but I'll need to make a legitimate branch and actually set up the project to use it as a npm package.

1st third of the file is Observable dependency. 2nd third is the parser built with hera https://danielx.net/hera/docs/README.html last third is Jadelet runtime, very similar to previous version.

It's definitely not "ready" as a package, lots of chores and setup to do but I'm out of time for today. If there's excitement I'll get it finalized sometime soon.

STRd6 avatar Sep 04 '21 17:09 STRd6

If there's excitement

Oh, there is excitement for sure :) Hera looks pretty amazing. I noticed you also creted a repo here. I hope you'll be also able to share the source soon. And, if not, maybe some private repo for a start?

I tried to wrap my head around the new Jadelet grammar and parser. But, if I'm not mistaken, only simple rules work for now (i.e., p(title=@attr) @value). So far, I couldn't embed any logic in the template (e.g., iteration, condition). To render the following example,

ul @list.map( @item )

I tried this object

{
  list: [1, 2, 3, 4],
  itemTpl: Jadelet2.exec("li @item"),
  item: function (item) { return this.itemTpl({item}) }
}

but, I couldn't get it to work.

In the end, I came up with this solution ul @lineItems

{
  items: [1, 2, 3, 4],
  itemTpl: Jadelet2.exec("li @item"),
  get lineItems() { return this.items.map( item => this.itemTpl({item}) ) } 
}

Is there a better way?

zdenko avatar Sep 05 '21 11:09 zdenko

@zdenko your ul @lineItems solution is how I've been doing things since removing the logic from templates in v2.

I just published the hera repo https://github.com/STRd6/hera and tried to get the readme somewhat more informative. I'll get a v2 branch going on Jadelet while I'm on a roll.

STRd6 avatar Sep 05 '21 20:09 STRd6

@STRd6 I've been playing with the v2, and I love it. I'm trying to convert some existing code from React for a test drive, and it's working great. The only part I encountered obstacles was the indention of the templates. If I use CS, the transpiler will take care of tagged templates, and the content will be correctly aligned. For example, all CS examples below

Template = Jadelet2.exec """
div
  .toolbar
    button(click=@save) Save
  @content
"""
Template = Jadelet2.exec """div
                              .toolbar
                                button(click=@save) Save
                              @content"""```
Template = Jadelet2.exec """
                         div
                           .toolbar
                             button(click=@save) Save
                           @content
                         """

will be transpiled into

Template = Jadelet2.exec(`div
  .toolbar
    button(click=@save) Save 
  @content`);

But, when I'm working in JS, I have to be very careful about the indent. This is especially annoying when the function where I'm creating the template is already indented.

(function(self) {
  ...
  function foo() {
    ...
    myTemplate = (props) => {
      if (props.value === 42) {
        return `div
  .toolbar
    button(click=@save) Save
  @content`;
      } else {
        return `div
  .toolbar
    button(click=@cancel) Cancel
  @content`;
      }
      ...
    };
   ... 
  };
  ...
})(global);

To solve this and have nicer formatting of the templates, I came up with the idea to store the first indent level in the parser and then deduct this value from the indentions. So, I've added a few lines to the reduceLines function in the grammar:

  function reduceLines(lines) {
    var depth = 0;
    var stack = [[]];
+   var firstIndent = 0;
    lines.forEach( ([indent, line]) => {
+     if (firstIndent === 0 && indent > depth + 1) {
+       firstIndent = indent - 1;
+     }
+     indent = indent > firstIndent ? indent - firstIndent : indent;

This change enables me to write more "freely":

(function(self) {
  ...
  function foo() {
    ...
    myTemplate = (props) => {
      if (props.value === 42) {
        return `div
                  .toolbar
                    button(click=@save) Save
                  @content`;
      } else {
        return `div
                  .toolbar
                    button(click=@cancel) Cancel
                  @content`;
      }
      ...
    };
   ... 
  };
  ...
})(global);

Of course, I didn't run any proper tests, so I'm not sure if this is bulletproof.

And I think I've probably found a minor issue in the Òbservable module. This code gives an error.

o = Jadelet2.observable
foo = o 42
foo()

# Uncaught TypeError: array is undefined

I think that in lines https://github.com/STRd6/jadelet/blob/ccc73dc1f756d3f7178018861ae71397418611bd/dist/jadelet2.js#L155 and https://github.com/STRd6/jadelet/blob/ccc73dc1f756d3f7178018861ae71397418611bd/dist/jadelet2.js#L159, self should be replaced with global.

After the change, the example above works.

zdenko avatar Sep 08 '21 11:09 zdenko

Thanks @zdenko!

I've updated the v2 branch with this fix as well as some more dependency cleanup and updates to CHANGELOG.md and README.md as well. It's published to npm as 2.0.0-pre.0. Just about ready for the official 2.0.0 release.

Let me know if there are any other issues that you encounter.

STRd6 avatar Sep 09 '21 14:09 STRd6

@STRd6 I just found a bug in my solution for indent. I'll prepare a fix and make a pull request.

zdenko avatar Sep 10 '21 11:09 zdenko