Multiple Lines for Long Attribute Value in Jade / Pug
Asked Answered
T

9

51

How do we write a long attribute value over multiple lines in Jade / Pug?

SVG paths tend to be really long. We want to write an attribute value over multiple lines to help with readability. For example, Mozilla's tutorial written in HTML is easy to read.

Any way to change this:

h3 Arcs
svg(width="320px", height="320px")
  path(d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10", 
    stroke="black", fill="green", 
    stroke-width="2", fill-opacity="0.5")

into something like this:

h3 Arcs
svg(width="320px", height="320px")
  path(d="M10 315 " +
    "L 110 215 " +
    "A 30 50 0 0 1 162.55 162.45 " +
    "L 172.55 152.45 " +
    "A 30 50 -45 0 1 215.1 109.9 " +
    "L 315 10", 
    stroke="black", fill="green", 
    stroke-width="2", fill-opacity="0.5")

without triggering an "Unexpected token" error.

Torgerson answered 26/7, 2013 at 3:44 Comment(0)
Y
45

I have this same problem but in a knockoutjs context. I used the backslash like so. Previously:

div(data-bind="template: {name: 'ingredient-template', data: $data}")

Now:

div(data-bind="template: {\
    name: 'ingredient-template',\
    data: $data}")

Note: The backslash must be followed immediately by a newline. I'm not sure if this is the 'official' way, I just did it and it seems to work. One downside of this method is the strings then get rendered with the white space intact. So the above example gets rendered as:

<div data-bind="template: {                    name: 'ingredient-template',                    data: $data}">

This might make it unusable for your example.

Edit Thanks Jon. The var idea from your comment is probably better though still not ideal. Something like:

-var arg  = "M10 315 "
-arg += "L 110 215 "
-arg += "A 30 50 0 0 1 162.55 162.45 "
-arg += "L 172.55 152.45 "
-arg += "A 30 50 -45 0 1 215.1 109.9 "
-arg += "L 315 10"
h3 Arcs
  svg(width="320px", height="320px")
    path(d=arg, 
    stroke="black", fill="green", 
    stroke-width="2", fill-opacity="0.5")

Not sure that the extra characters are worth the reduction in line length.

Younglove answered 27/7, 2013 at 5:8 Comment(2)
Do you think assigning the attribute to a variable will be better?Torgerson
E.g., - var data = "template: { " // so on... and then assign it later in the attribute.Torgerson
D
25

This is an old question but here is a newer answer.

In my case I am using PUG in vue templates in single file components. So the following works for me.

<template lang='pug'>
  .day(:class=`{
    'disabled': isDisabled,
    'selected': isSameDay,
    'in-range': isInRange,
    'today': isToday,
    'weekend': isWeekend,
    'outside-month': isOutsideMonth }`,
    @click='selectDay'
  ) {{label}}
</template>

i.e. using string interpolation ` instead of ' or "

Dottie answered 16/3, 2017 at 10:48 Comment(2)
Yeah, someone using VueJS! :DCarmeliacarmelina
Thanks! Also, as an alternative for VueJS people, you can use a computed property: :class="classes".Darwinism
B
19

I have been looking for an answer to this and I believe you can break jade attributes onto multiple lines by skipping the trailing commas.

Ex.

aside                                                                            
  a.my-link(                                                            
    href="https://foo.com"                                         
    data-widget-id="1234567abc")                                         
    | Tweets by @foobar

I found this commit message about it: https://github.com/visionmedia/jade/issues/65

Buke answered 25/12, 2013 at 18:2 Comment(2)
Hi @blischalk, we're trying to break a single attribute value into multiple lines e.g., d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10" into something more readable. Your example here can be easily broken up into a few lines because of short attributes. How about long ones?Torgerson
Thanks @Buke - this does not answer OP's question but was exactly what I needed and showed up first on Google.Aker
T
7

You can do it by closing the string at the line-break, adding a '+', and then opening a new string on the continuation line.

Here's an example:

path(d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55" +
       " 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10",
     foo="etc",
     ...
Tamarind answered 24/7, 2014 at 2:0 Comment(1)
Thanks for the answers guys. Both this and the accepted answer work great. The accepted answer has less characters to type, but this does not confuse my editor's jade plugin syntax highlighting. Too bad we can't use triple " like coffeescript.Falgoust
A
2

I also had a string as attribute value. I am using react

 input(
   ...props
   label="Contrary to popular belief, Lorem Ipsum is simply random text. \
      It has roots in a piece of classical Latin literature from 45 BC, \ 
      making it over 2000 years old."
)

in your case...

path(d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 \
    L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 \
    10",

Note that there is a space before the backslash

Ardithardme answered 9/6, 2018 at 9:30 Comment(0)
F
2

One solution not mentioned yet is to use an array and join its items with spaces:

h3 Arcs
svg(width="320px" height="320px")
  path(
    d=[
      'M10 315',
      'L 110 215',
      'A 30 50 0 0 1 162.55 162.45',
      'L 172.55 152.45',
      'A 30 50 -45 0 1 215.1 109.9',
      'L 315 10',
    ].join(' ')
    fill="green"
    fill-opacity="0.5"
    stroke="black"
    stroke-width="2"
  )

Output (using Pug 2.0.4):

<h3>Arcs</h3>
<svg width="320px" height="320px">
  <path
    d="M10 315 L 110 215 A 30 50 0 0 1 162.55 162.45 L 172.55 152.45 A 30 50 -45 0 1 215.1 109.9 L 315 10"
    fill="green"
    fill-opacity="0.5"
    stroke="black"
    stroke-width="2"
  ></path>
</svg>

You could also join the array items with something else than spaces, which could be handy in some cases.

Frayda answered 21/1, 2021 at 7:24 Comment(1)
Simple and readable!Crewelwork
D
0

Pug allows definition of js functions available within the template during rendering, so I have used this capability to define a function that removes unwanted white space from strings, then I apply that to a multiline attribute string to get rid of the unwanted white space in the generated html. Here is an example pug template:

-
    //- function to remove white space from strings, leaving a single space
    var rws_rex = /[\n\r\s\t]+/g
    function rws(ff){
        return ff.replace(rws_rex, ' ');
    }
span.clickable1( onclick=rws(` 
                      $('.selected').removeClass('selected'); 
                      $(this).addClass('selected'); 
                      SA_getPersonDetails('${psn1.personUID}'); 
                      return false; `)
             )  
    | Click for details

The result is

<span class="clickable1" onclick=" $('.selected').removeClass('selected'); $(this).addClass('selected'); SA_getPersonDetails('d1374ea2-2f35-4260-8332-abd7ec2d79b4'); return false; ">Click for details</span>

** Beware that this removes whitespace from inside any literal values in javascript code, so you would need to modify the regexp and function if you want to preserve those spaces. In my example above, if psn1.personUID contained multiple consecutive spaces, they would be reduced to a single space. But it works fine for most types of attribute.

Digression answered 1/8, 2020 at 10:55 Comment(0)
C
0

I found better way, which takes into account spaces in final html:

input(type='type' 
      class='block w-full'
      +' pr-12 border-gray-300'
      +' rounded-md focus:ring-indigo-500'
      +' focus:border-indigo-500 sm:text-sm')
Candytuft answered 16/3, 2021 at 15:11 Comment(0)
F
0

I know this tread old; Just want to let people searching for this in 2022 that now you can simple use ES6 multi-line strings in Pug.

html
  head
    meta(http-equiv='Content-Security-Policy' content=`
      default-src *  data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval' 'unsafe-dynamic';
      script-src * data: blob: 'unsafe-inline' 'unsafe-eval';
      connect-src * data: blob: 'unsafe-inline';
      img-src * data: blob: 'unsafe-inline';
      frame-src * data: blob: ;
      style-src * data: blob: 'unsafe-inline';
      font-src * data: blob: 'unsafe-inline';
      frame-ancestors * data: blob: 'unsafe-inline';
      `)
Finedraw answered 5/4, 2022 at 2:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.