开发者

Proper procedure for tag helpers in moustache

开发者 https://www.devze.com 2023-01-26 09:55 出处:网络
I\'ve been reading over the moustache documentation, and it looks cool: https://github.com/defunkt/mustache

I've been reading over the moustache documentation, and it looks cool: https://github.com/defunkt/mustache

There is a clear separation between ruby code and html markup. Having not started a moustache project, my confusion is this: how should ruby that generates markup be handled? Obvious examples would be form helpers and link_to, not to mention any custom me开发者_开发问答thods. Would it be proper (or possible) to do {{link_to ...}}? -- having code in the markup. Or to define a custom method in the view ruby: {{whatever_link}}? -- this seems non-DRY and equally undesirable. Where's the win?

Thanks!

--Peter


Mustache is very simple by design. Templates are supposed to be renderable in many languages (see https://github.com/defunkt/mustache/wiki/Other-Mustache-implementations). Many web applications chose mustache because templates can be shared by client code (javascript) and server code (whatever language).

The win is not to go against that fact, even if it may look inconvenient at first sight.

Investigate the {{whatever_link}} solution, and keep your code as DRY as you can.


Here is what I do in mustache.java:

import java.util.Collection;
import java.util.Map;
import java.util.Set;

public class UrlHelper implements Map<String, String> {

    public static final UrlHelper instance = new UrlHelper();
    private static final String NORMAL_PREFIX = "url";
    private final String virtualHost;

    // configure virtualhost here
    private UrlHelper() {           
        virtualHost = "/";
    }

    public boolean containsKey(Object key) {
        return key.toString().indexOf(':') != -1;
    }

    public String get(Object key) {
        String k = key.toString();
        String prefix = k.substring(0, k.indexOf(':'));
        String url = k.substring(k.indexOf(":") + 1);
        if (prefix.equals(NORMAL_PREFIX))
            return virtualHost + url;
        return virtualHost + "static/" + prefix + "/" + url + "." + prefix;
    }
    // Default implementation for the other 'Map' methods
}

When rendering I do this:

mustache.execute(writer,new Object[] { model, UrlHelper.instance }).flush();

You can use like this(assume your app is hosted at /app):

{{js:lib/jquery}} {{! /app/static/js/lib/jquery.js }}
{{css:site}} {{! /app/static/css/site.css }}  
{{url:users/edit/1}} {{! /app/users/edit/1 }}

It is also possible to have a single prefix for all static resources(eg: static), but you can't use dots to specify the file extension, so you must use some other character to represent dots and replace in your processing code.

You can probably adapt this technique to your web framework/language.


I agree with Gwendal that a goal of Mustache is to be able to share views between your backend and frontend, though that is not the only goal -- you might use Mustache if you just want to clean up things in your views. In that light, another way to think about Mustache is that it pushes the logic to the layer behind the immediate frontend (i.e. Ruby code). So in this middle layer you can do anything you want. I would recommend using the stache gem because it fills in the gap between Mustache-land and Rails-land by making a connection between your Mustache view class and the underlying Rails view class. So this way, you could use, for instance, link_to in this middle layer. You'd have to make a view method that wrapped a call to link_to for a particular object, since you can't call methods in a Mustache template and pass it arguments, but I think that is okay.

0

精彩评论

暂无评论...
验证码 换一张
取 消