theCrag / website

theCrag.com: Add your voice and help guide the development of the world's largest collaborative rock climbing & bouldering platform
https://www.thecrag.com/
111 stars 8 forks source link

Choose and start using a client side template system (solves language issues) #2363

Open brendanheywood opened 8 years ago

brendanheywood commented 8 years ago

This is to partially enable easier internationalization of stuff which is generated on the client side, like some context menus, and also means we can re-use a bit more code, but importantly means we can define all html output wether mason or js in one place to help keep it consistent.

So first we have to choose a template language. Mustache is pretty lightweight and we can call it from perl if we really wanted to. I kinda prefer a little bit of logic expression so handlbars is a bit nicer. Some others to consider are jquerty templates, and underscore which would be smaller and leverage code we already use. Another cool contender is dotJS which is tiny.

http://handlebarsjs.com/

http://mustache.github.io/

http://olado.github.io/doT/index.html

http://codepb.github.io/jquery-template/

http://underscorejs.org/#template

So regardless of which one we choose, the way I see this working is that in a mason template we call declare somehow that we need to use template X, maybe something like:

<% requireJsTemplate('minor/listview/contextmenu') %>

This in turn renders at that point in the output an inline template like:

<script id="minor-listview-contextmenu" type="text/x-handlebars-template">
<div class="entry"><div class="actionarea"><div class="edit"><div class="btn-group open">
<a class="editlink btn btn-mini" href="{{bulkediturl}}}"><i class="icon-pencil"></i> Edit</a>
<a class="btn btn-mini dropdown-toggle" data-toggle="dropdown"><i class="icon-caret-down"></i></a>
<ul class="dropdown-menu pull-right">
  <li><a href="{{editurl}}">Edit route</a></li>
  <li><a href="{{addrouteaboveurl}}">Add route above</a></li>
  <li><a href="{{addannoturl}}">Add annotation above</a></li>
  <li class="divider"></li>
  <li class="disabled"><a>Merge routes</a></li>
  <li class="divider"></li>
  <li><a href="">Log ascent</a></li>
  <li class="disabled"><a>Your ascent history</a></li>
  <li><a href="/ascents/at//">All ascent history</a></li>
</ul>
</div></div></div></div>
</script>

Because this js template is rendered server side we have full access to the perl language stuff so we don't need to port it to js land. Because it is inline we don't need to worry about having different static versions of each js file for each language. The amount of data we are talking about is very small so we are not too worried about caching issues. If this pageNeedsTemplate is called more than once with the same template name subsequent template are ignored as we only ever need 1 per page.

Because we'd call requireJsTemplate only inside the mason template which needed it, then each page has the exact js templates it needs and we don't worry at all about JS bloat in any shared files.

These template files I'd store in the same directory structure as the mason template but with a different extension so we can edit them all in unison.

Then we bundle the template language of choose into common.js, then when the js kicks off, everything it needs ie the template and the data and the template library are all ready and it can do the magic. All the stuff like wether a context menu item would not be visible, or have a special class attached is all js template data and handled in the template rather than the way it is now inside the JS script.

At this stage my preference is leaning towards dotJS because it pretty powerful and crazily one of the smallest, minifed comes in at 1.5kb

http://olado.github.io/doT/

Only downside is we can't use from perl, but I don't see this as a major requirement.

scd commented 8 years ago

I think this seems pretty solid.

If I understand the use case correctly for a facet row menu we render a template once in the html code then the js code clones and reuses when needed.

The templates also change a fair bit depending on the conditions of how many rows are selected (eg Merge becomes active when two rows are selected). Whatever templating we use needs to be rich enough to support this.

Only downside is we can't use from perl, but I don't see this as a major requirement

Do we need node.js?

I am not so sure of technology selection yet, but the general direction seems solid. When I get time I will look in more depth.

brendanheywood commented 8 years ago

Yes all of the above has the expressive ability to filter or change the menu depending on context or user capability etc

Node isn't needed but almost all of those Libs above work with node if we needed that at some later point.

scd commented 8 years ago

I won't implement the menu translation until we work out exactly what we are doing here.

brendanheywood commented 8 years ago

Given that all of the template Libs are fairly similar, migrating from one to another layer wouldn't be a massive amount of work. So how about we just go with dotjs and implement the context menu for list view. I can do this Monday night and then we can make a call wether dotjs is expressive enough.

scd commented 8 years ago

Put it on your list.

We need both list view and ascent facet menus and stream menus.

I will not be in a position to help jump in for a while as I don't want to be distracted from my core tasks.

I really want to be part of the design with this so maybe do it on a separate branch and treat any work you do as exploratory for the moment.

Also I think the solution should be in a stand alone js file. Eventually we need a pipeline to combine in common.js, but for now I think just combining it using the footer will be fine.

BTW, an urgent task for me is to finish off what we promised for bergfreund. This is integrating their images on the home page. I am going to use this to get the ip address country into the template. I am not going to do much rework of the template itself, just get the image in and remove some of our copy. But maybe you want to get excited about this as well and do a better job than me if I can get it ready to handover in time.

Mdemaillard commented 4 years ago

please confirm, i believe that has been implemented since now we have localization ?

scd commented 4 years ago

No we have not got the front end templates going.