120

I am new(ish) to the whole javascript full stack applications, and completely new to Angular, so I was hoping somebody can put the record straight for me here.

Why would I need to use a templating framework like Jade or Handlebars when writing client side apps using AngularJS.

I should say that I have never used any of these templating frameworks either. So I am not familiar with the advantages completely. But when I look at Handlebars for example, it does many of the same things as I would do in Angular, such as looping etc.

As far as I can tell, it would make most sense to create the templates in Angular using proper HTML and then do all templating client side, and combine this with an API first approach using node and mongo for example.

The reason for this confusion is that a lot of the examples I find on GitHub make use of Jade, and it seems counter intuitive for me.

Please enlighten me, and set me straight. I would love to learn some best practices from people who know much more than I do.

Thanks

Jay Pete
  • 3,697
  • 4
  • 31
  • 46

10 Answers10

63

I use Jade to generate templates consumed by AngularJS because I hate writing plain HTML. It looks something like:

.control-group(
  ng-form
  name='emailGroup'
  ng-class='{"ng-error": emailGroup.$invalid}'
)
  label.control-label Email
  .controls
    input(
      type='email'
      ng-model='user.email'
      required
      placeholder='you@example.com'
      focus-on='focusEmail'
    )

… which I think is a lot cleaner than plain HTML.

thatmarvin
  • 2,489
  • 2
  • 19
  • 31
  • 12
    OK, so you only use it because you don't like writing plain HTML? Is that the main benefit to Jade, are there other wins? Does Jade ever mess up the HTML in any way, so you have to tweak it to obtain a certain output? I see a danger of having added [another layer of indirection](http://en.wikipedia.org/wiki/David_Wheeler_(computer_scientist)) without an actual need. But then again, that's why I am asking. I want to understand the value here. – Jay Pete Aug 11 '13 at 20:05
  • 1
    I actually started with Jade before I went with Angular, so it was a habit that stuck rather than a conscious choice, but it has worked out well so far. The only issue I have with Jade is the way it handles white spaces (I use pretty=false) so I ended up with trailing whitespaces in the source files whenever I need to add a space between tags. I found features like includes and mixins very useful. – thatmarvin Aug 11 '13 at 23:16
  • Does `ng-inlude`, possibly used together with `ng-src`, differ much from Jades mixins and and includes? – Jay Pete Aug 12 '13 at 07:35
  • `ng-src` is just like src in `` that supports Angular expressions, so it's irrelevant here. I haven't used `ng-include` much, but on the surface it can replace includes, not mixins. You can generate HTML fragments using Jade and consume it via `ng-include`. – thatmarvin Aug 12 '13 at 16:11
  • how did you incorporate jade into your angular app? my question: http://stackoverflow.com/questions/20676198/how-do-i-write-jade-style-html-with-an-angular-app – Connor Leech Dec 19 '13 at 09:44
  • 2
    @JayPete Jade's layer of abstraction over HTML is *soooo* thin. It's one of the most intuitive translations between syntaxes I've ever used. Very little magic happens in Jade except where you start digging in with variables and conditional logic (as you would with any template engine). It's really not all that different. – Chev Jan 22 '14 at 05:23
  • 6
    Simple is subjective. – Chev Feb 18 '15 at 20:58
62

Those who unquestioningly favour Jade in an Angular environment fail to understand that view logic belongs on the client, and business logic on the server, just as the OP commented.

Don't do it unless you have a very good reason to do it. In engineering, a system with fewer moving parts is a more reliable system, and a system where interface boundaries (client/server) are respected is more maintainable over the long term, so default to the simplest architecture and clean division of labour if possible. If you have overriding reasons, do what you must, but caveat emptor.

Recently I reviewed some code where straight Angular templating would have done a far better job than mixing in Jade, just through maintaining simplicity.

Aside from template extension, Jade brings nothing worthwhile to the table that Angular doesn't already supply. Let's be honest: Using the sound principle of "favour composition over inheritance" (i.e. partials), you shouldn't ever need template extensibility. Jade is hardly "easier to parse" than HTML. They are but trivially different, while Jade adds another level of indirection - best avoided.

There is one valid, specialised case for server-side templating: Optimisation, remembering that premature optimisation is generally a Bad Thing. Where performance is truly at issue, and you have the server capacity to spare to handle this, server side templating can assist. This applies to products like Twitter and Basecamp, where the cost of doing a lot of server side work is offset by the gains of reduced requests to the server.

As for Handlebars, there is no need to replace AngularJS's (amazing) client-side templating.

Engineer
  • 7,543
  • 7
  • 57
  • 96
  • 4
    Hi Nick, that is the answer I reached as well. I didn't put it quite as bluntly, but I agree! – Jay Pete Nov 28 '13 at 19:51
  • 60
    @Nick, I haven't seen much people who enjoy writing/reading XML/HTML. You're possibly the rarest one I've ever seen who actually advocates that in favour of something much drier and cleaner like Jade. There are tons of libraries the whole purpose of which is to spare people from writing/reading XML/HTML. – Alex K Dec 15 '13 at 03:09
  • 12
    I don't introduce complexity where it isn't needed. Spend your days reading C code or worse, C++ templates, and you'll quickly realise that mentally parsing HTML is a very trivial matter _indeed_. – Engineer Feb 02 '14 at 12:05
  • 35
    "laughable for any professional to claim this.", "mentally parsing HTML is a very trivial matter indeed. ". I find these very degrading comments. Would you rather write assembly because it is so easy to parse? Jade is basically what YAML is for XML when you're using Angular with it. – Philipp Gayret Feb 05 '14 at 18:19
  • 2
    Agree with @Phillip - Jade is a beautiful templating language and i think when you pare away syntactic cruft its a lot easier to catch errors. Even for the He-Men amongst us who spend their days reading C/C++ code. I'd always favour something like HAML or Jade where available (barring some significant trade-off) but then i've never seen the need to mentally parse things I dont have to. – Hal Jul 08 '14 at 12:19
  • 7
    I agree with @NickWiggill. Mentally parsing a JADE template vs. raw HTML requires equal 'wetware' cpu time for me. I won't go so far as to say you're unprofessional if you disagree, but to me it's the same thing. @ Philipp, your analogy of parsing C/C++ to assembly being equal to parsing JADE to HTML is poor, there are few people, if any, who could even begin to parse assembly in near real-time, whereas, I feel, most web developers could parse HTML just as easily or very nearly as easy as JADE. – nomis Sep 29 '14 at 16:15
  • 1
    I can see a clear usefulness for Jade as imposing a clear, indented and structured view. As long as you don't exploit the possible logical parts of it, I'd give it a go. – Ricardo Pedroni Oct 02 '14 at 20:31
  • 1
    @nomis if you are proficient in assembly you can mentally parse it much, much faster than C and esp. C++ since, when you get used to mnemonics, ASM is a simple state-machine GOTO fest much like early BASIC interpreters and on Motorola/Rockwell you could have quickly learned to parse stack pushes, jumps and branches into logic structures they represent. Biggest advantage of HLs like C over that is terseness and enforced structure. Much like Jade over HTML. – Bojan Markovic Nov 27 '14 at 22:16
  • 2
    I prefer Jade, Haml, etc over raw HTML because it's easier to prevent errors. Yes, I've been writing HTML for 20 years, I can do it in my sleep, but I've also spent a day trying to find a missing tag. There are no missing closing tags in Jade. Also easier to parse visually - you CAN write your html code indented for readability, but you don't have to - Jade forces you to keep your DOM hierarchy readable. By the same token, why bother with coffeescript? – stephan.com Mar 26 '15 at 18:33
  • 1
    @ArcaneEngineer The argument that there are languages which are harder to read than HTML hardly seems like a good reason to avoid any effort to make HTML easier to read. I mean.. why are we still working to improve cars when they're already so much better than horses? – Dan Bechard Oct 03 '15 at 19:30
  • 1
    @ArcaneEngineer That definitely means that you are correct in anything you say, and that you are 100% not a troll. I boweth down to thee. http://michael.richter.name/blogs/awhy-i-no-longer-contribute-to-stackoverflow – Codebling Oct 29 '15 at 18:51
  • 1
    Anyway, you need some server-side templating for SEO. How have you managed to get around that? – Codebling Oct 29 '15 at 19:03
  • @CodeBling Did you read the word _in italics_ on the first line of my answer? Or did you read selectively? – Engineer Oct 29 '15 at 19:07
  • 2
    @ArcaneEngineer I did, and if you read _my_ comment, you would understand that I am asking whether or not you use templating for SEO, which has nothing to do with the original question and little to do with your answer. Feel free to answer or not, or to leave another snarky reply. – Codebling Oct 29 '15 at 19:23
  • @CodeBling Then you should have understood very clearly from the word go that the answer never once said _don't do it_. It suggests, _don't do it unless you have a very good reason to do it_. If you had spent many years in industry (as some of us have), you would already understand that a simpler system is a better system , and a system where interface boundaries are respected is one that is maintainable over the long term, so _always default to a simple architecture_ where possible. Maintainability is not a goal for you? – Engineer Oct 29 '15 at 19:30
46

I honestly don't understand why people care about the difference between this:

<html ng-app>
 <!-- Body tag augmented with ngController directive  -->
 <body ng-controller="MyController">
   <input ng-model="foo" value="bar">
   <!-- Button tag with ng-click directive, and string expression 'buttonText' wrapped in "{{ }}" markup -->
   <button ng-click="changeFoo()">{{buttonText}}</button>
   <script src="angular.js">
 </body>
</html>

and this:

html(ng-app="ng-app")
  // Body tag augmented with ngController directive  
  body(ng-controller="MyController")
    input(ng-model="foo", value="bar")
    // Button tag with ng-click directive, and string expression 'buttonText' wrapped in "{{ }}" markup
    button(ng-click="changeFoo()") {{buttonText}}
    script(src="angular.js")

Except that I find one slightly more human-readable. Slightly. I don't get why people are so fervent about the topic. It's all bikeshedding. The difference is negligible and any competent programmer could easily translate one into the other after five seconds on Google. Use what you want and let everyone else quarrel over nothing. Pick your battles and engage in debates about things that actually matter, like atomic reactors ;)

Chev
  • 54,842
  • 60
  • 203
  • 309
  • 2
    I agree, though if you just add 1 Jade `if` to the equation, everything suddenly changes. See above about "premium users". – TWiStErRob Feb 05 '14 at 09:58
  • 15
    I disagree, a 9 line html page is completely unrealistic. taking the source of the page I'm viewing now converts 2320 lines to 1580 ( Using [html2jade](http://html2jade.com/) ). Thats more than _700_ lines of time wasted for whoever wrote all the stackoverflow templates – Philipp Gayret Feb 05 '14 at 18:11
  • 2
    @TWiStErRob If you're going from jade to HTML all you'd need to do is render the template, lol. If you have `if`s in your jade markup then you already have a need for some kind of templating engine anyway and you'd have to convert it to whatever `if` syntax is used by that engine. I don't really understand your criticism. – Chev Feb 05 '14 at 21:09
  • If this whole debate is about where conditional logic belongs (server or client) then I think it's an even sillier debate than I did originally. There are cases for both and you use whichever one works or if they both would then whichever the individual prefers. I've spent more time having arguments like these than I've **ever** spent cursing a past decision to put some logic in a server-side view or vice versa. If we all want to argue about efficiency then we should discuss the merits of this entire conversation instead. – Chev Feb 05 '14 at 21:46
  • @AlexFord, I'm advocating for Jade, sorry if it wasn't clear. Jade is better because you need templating (a good one, server-side, which hides rendered html for hackers), not because it's shorter and _slightly_ more readable. – TWiStErRob Feb 05 '14 at 23:39
  • @user1066946, I think the point here is that Jade looks a little bit better. I'm also almost sure that with some clever formatting you can get rid of that 700 lines, let's not count `` as a line. – TWiStErRob Feb 05 '14 at 23:41
  • 3
    @Philipp, isn't it safe to assume most of the lines removed are just closing tags? Since most editors automatically add closing tags when you write an opening tag, I doubt it actually saved writing 700 lines. – Semicolon Jun 23 '14 at 14:07
  • Going to necro this a bit and add some insight for future viewers. This example does not take into account the reduction of space in assigning classes and IDs, which are very frequently used by various libs. Since liberally using classes is becoming quite normal in drying up your CSS, this benefit should not be understated. There is also the likeness of class and ID syntax to the CSS selectors. Any developer that's enjoyed developing in JS on both the front and back ends should be able to appreciate the value of using the same language/syntax in multiple places. – Rosseyn Jul 24 '15 at 05:15
  • *IF* you're dealing with inclusions and view logic in another layer (e.g. Angular), then the use of Jade is mostly just a preference. It will minify your HTML. – Codebling Oct 28 '15 at 19:23
  • Even on the server it's mostly just a preference. There are more templating engines than I can count, and they all have very similar feature sets. – Chev Oct 29 '15 at 15:26
14
  1. You don't need to use Handlebars with AngularJS since it has it's own template engine.
  2. The reason they use Jade, because it's just a server renderer which will be compiled to html and served by angularJS later on the frontend.

So TL;DR, on server, you can use whatever language [jade,haml,...] to generate just html structure for your application, it doesn't have anything to do with angularJS since it will render and work with HTML at runtime on frontend.

You don't have to use Jade on server, and I suggest not using since it will confuse new developers. In projects that you see they use Jade only because it's cleaner and they are used to it, and if it uses with angularJS, it's only job is to generate plain html without any logic.

Dzung Nguyen
  • 8,760
  • 13
  • 61
  • 98
  • 2
    Wouldn't it be cleaner to not use the server generated html, and completely separate the logic and the view? Or is there something I am missing? Why is Jade a good idea when writing an AngularJS app? – Jay Pete Aug 11 '13 at 18:49
  • I don't say is a good idea to use with angularJS. Jade doesn't have anything to do with angularJS. To make this clear, I will update my answer. – Dzung Nguyen Aug 11 '13 at 18:52
  • I understand that Jade doesn't have anything to do with Angular. I am just trying to figure out what the value of Jade is, over writing out the actual HTML in AngularJS partials. I see a lot of people using it, and want to understand why :-) – Jay Pete Aug 11 '13 at 19:56
  • 2
    Again, Jade has nothing to do with AngularJS. AngularJS comsumes HTML partials and is served from a HTML page. You can use whatever to make the HTML pages on the server side, including Jade or Haml. Jade/Haml aren't really templating frameworks. They are more preprocessors. The correct question would be "Handlebars or Moustache or other JavaScript templating languages" – Eddie Monge Jr Sep 13 '13 at 22:03
  • @JayPete The benefit of using Jade when developing angularJS maybe because of Jade syntax is cleaner. But still, due to my experience, it's not much help. So just do it with html :) – Dzung Nguyen Sep 15 '13 at 10:21
  • Just started using Jade, with, what happens to be an AngularJS app. Personally, I find writing and reading Jade quicker than HTML. Where AngularJS doesn't need to be involved, e.g. static content, I can use Jade features (loops and conditionals) to make my life easier, sometimes halving the HTML is pure lines of code terms. Also, I'm using gulp-jade to pre-render then compile the output into the template cache - no server-side. – glennanthonyb Mar 25 '15 at 11:42
8

The accepted answer is somewhat one-sided and neglects the fact that any setup of pre-compiler for HTML has a great use for ANY kind of HTML project: Composition and resulting markup flexibility.

Working alone on an angular app? Give Jade a try.

Jade improves your ability to modularize HTML, decreases the ammount of time you spent on debugging HTML and also encourages building markup inventories.

During design time there can be an awful amount of iteration on HTML parts. If HTML output is based on a set of jade files, it's easy for the team to act flexible on changing requirements. Also, changing the markup via re-composing jade includes is significantly more robust than re-writing pure HTML.

That being said, i recognize the general aversion towards mixing angular with jade in production or development stage. Introducing another required set of syntax knowledge is a bad idea for most teams and the use of jade might hide inefficient project management by abstracting away some work that would be prohibited by DRY principles (e.g. being lazy on markup preparation)

Mirko
  • 994
  • 8
  • 11
  • 2
    No idea why this had a -1, but I've countered it. – Mark K Cowan Nov 03 '14 at 10:44
  • It was downvoted becaues it's not completely true. Jade doesn't do anything to modularize HTML. You could literally say the same things about plain HTML if it's used in the right way with a pre-compiler. – Justin May 27 '15 at 19:45
  • 1
    You are right, the same can be said of all pre-compilers. For Jade, Mixins http://jade-lang.com/reference/mixins/ can improve modularization (especially compared to vanilla HTML). If you are interested in modularization of HTML you might also like https://www.polymer-project.org/. – Mirko May 30 '15 at 11:24
7

I've read all the answers above and was a bit surprised no one had mentioned one aspect which makes using jade over generating AngularJS templates a very useful thing.

As it already been told, in production, realistic scenarios difference between typing raw html and jade is actually notable, but the more important thing we should never forget is that sometimes we need dynamically changed and reinitialized angularjs templates.

To put it simple, sometimes we need to change html via innerHTML and then force AngularJS to recompile contents. And this is exactly the type of task when generating such views via jade can have it benefits.

Also, AngularJS works well with models, which structure is by definition well known. Actually, it happens that we actually don't know the exact structure (imagine, say, JSON renderer). AngularJS will be quite clumsy here (even if were are building an angular app), while jade will do the job.

Community
  • 1
  • 1
shabunc
  • 17,863
  • 15
  • 68
  • 96
2

You can include angular templates via Jade.

script(type="text/ng-template", id="admin")
  include partials/admin

For caching templates I perceive this as much less fragile than including the escaped templates in the javascript files.

See: https://docs.angularjs.org/api/ng/service/$templateCache

Austin Pray
  • 4,746
  • 2
  • 19
  • 30
2

Jade is definitely much more closer to html than say Haml. So the context switch is actually very minimal. Yet it is not completely absent. It may not matter to a developer at all. But when your designer comes and asks you how to get a nested tag to work properly, you are solving an unnecessary problem that you created in the first place.

HTML can still be written very legibly and partials can be used to make it more comprehensible. 500 lines of anything is hard to read - be it Jade or HTML.

Here is a Jade template

.product-container

    .input-group.msB.col-md-5.no-padding
        .fnt-light-navyblue.mtB(for='name')
            strong Name the sticker
        input.full-input(type='text', placeholder='Awesome Batman Sticker')
    .clear

    .form-group.mmT
        label.form-label.fnt-light-navyblue
            strong Choose size
        .selector-group(ng-repeat="size in sizes", ng-class="{ 'msT': !$first}")
            - raw
            span.radio
                input.radio(name='choose_sticker_size',
                            ng-model="selectedSize",
                            type='radio',
                            value='{{size}}',
                            id="sticker-{{size}}")
                span.fake-radio
            label(for='sticker-{{size}}') {{size}} inch
            - endraw
    // end form-group
    .clear

And the equivalent HTML

<div class="product-container">

    <div class="input-group msB col-md-5 no-padding">
        <div for="name" class="fnt-light-navyblue mtB">
            <strong>Name the product</strong>
        </div>
        <input type="text" placeholder="Awesome Batman Sticker" class="full-input" />
    </div>
    <div class="clear"></div>

    <div class="form-group mmT">
        <label class="form-label fnt-light-navyblue">
            <strong>Choose size</strong>
        </label>
        <div
            class="selector-group"
            ng-class="{ 'msT': !$first}"
            ng-repeat="size in sizes">
                {% raw %}
                <span class="radio">
                    <input
                        id="sticker-{{size}}"
                        class="radio"
                        name="choose_sticker_size"
                        ng-model="selectedSize"
                        type="radio"
                        value="{{ size }}" />
                    <span class="fake-radio"></span>
                </span>
                <label for="sticker-{{size}}">{{size}}</label>
                {% endraw %}
        </div>
    </div><!-- end form-group -->
    <div class="clear"></div>
</div>

When written legibly I dont see HTML to be very particularly disadvantaged so as to warrant a switch. Sure enough, the angular brackets are an eyesore. But I would rather have them, than having to deal with the designer's doubts whether the indirection I introduced is breaking the html. ( It may not. But proving it is not a worthy effort )

suryasankar
  • 4,303
  • 2
  • 12
  • 13
0

First of all, you always need some kind of server-side templating.

Pure client-side templating have huge disadvantages in a loading time, so it's often mitigated by rendering some static elements on the server. This way when user partially loads a page, he'll already see some elements on the page.

And well, templates are handy in this case, although people sometimes use static html generator like Jekyll instead.


There is another reason for using Jade that's not mentioned here before.

Whitespace.

If you're writing human-maintainable HTML with indentations and line-breaks, every single linebreak will result in a whitespace text node. It can pretty much screw formatting of inline elements in some cases, and make javascript code more weird.

You can read more details here: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Whitespace_in_the_DOM

If you're writing Jade code, it is compiled into one-line HTML that doesn't have this issue.

alex
  • 10,773
  • 2
  • 27
  • 41
  • >[FasteRender] (http://meteorhacks.com/fast-render/) is solution that doesn't involve server side rendering. It sends the data required to render your first page with the initial HTML loaded from Meteor, so the page is rendered just after the JavaScript is loaded to the client. It gives identical result as Server Side Rendering(SSR), but still sending data over the wire without breaking one of the Meteor’s core principles. – Max Hodges Mar 17 '14 at 22:32
0

When working in a team, front-end likely prefers designing their pages as static html. Translating that static html into dynamic templates is a source of errors, and adding jade adds such translation step.

As many others, I favour simplicity!

Arjan
  • 329
  • 3
  • 10