HAML <template> in .vue files



  • Hi,

    I am reposting my question here from the Vue forum where nobody could help me. (Tell me if it’s too off-topic)

    I wish to use HAML instead of HTML so I converted the <template> contents to HAML, installed hamljs and set the lang=haml attribute as I have seen it done for jade/pug.

    Here’s what I get with the Quasar boilerplate app:

    > node build/script.dev.js
    
     Starting dev server with "mat" theme...
     Will listen at http://localhost:8080
    Build completed in 22.525s
    
     ERROR  Failed to compile with 1 errors                                                                                                                                              3:25:33 PM
    
     error  in ./src/components/Index.vue
    
    Syntax Error:     at [...]/node_modules/hamljs/lib/haml.js:662:14
    
     @ ./src/components/Index.vue 9:2-238
     @ ./src/components async ^\.\/.*\.vue$
     @ ./src/router.js
     @ ./src/main.js
     @ multi ./build/hot-reload ./src/main.js
    

    The template code was converted using html2haml v.2.0.0 and looks just fine:

    <template lang='haml'>
    %q-layout
      .toolbar{:slot => "header"}
        %q-toolbar-title{":padding" => "0"}
          Quasar Framework v{{$q.version}}
      /
        Replace following "div" with
        "<router-view class="layout-view">" component
        if using subRoutes
      .layout-view
        .logo-container.non-selectable.no-pointer-events
          .logo{":style" => "position"}
            %img{:src => "~assets/quasar-logo.png"}/
            %p.caption.text-center
              %span.desktop-only Move your mouse.
              %span.touch-only Touch screen and move.
    </template>
    

    For what it is worth, location 662:14 of haml.js is this:

    fn = Function('locals, attrs, escape, HAML', parser.js)


  • So I finally made progress when I began doubting the HAML parser. It turns out that the package (hamljs) I blindly chose does not fully support the HAML syntax. Specifically it requires the {attribute: 'value'} syntax and chokes on {:attribute => "value"} or {"attribute" => "value"}.

    For some reason, the app still does not fully work, I will keep investigating and report when I figure out other limitations.



  • OK, the app was not working due to the shorthand syntax for v-bind used in the .logo{":style" => "position"} element. Not being familiar with it and coming from a Ruby background, I had translated it to the supposedly equivalent style: "position" thus unknowingly breaking the binding.



  • What is your question?

    Scott



  • @s.molinari It is probably “Why do I get this syntax error?”



  • And you found your problem too it seems?

    https://forum.vuejs.org/t/solved-haml-in-vue-files/8524

    Scott



  • Huh, yes as I said in my replies above. Are they not appearing on your side ? I even link back to here from the Vue forum in the hope of helping beginners who fall in the same traps.



  • Yes, they are. I just didn’t put 2 + 2 together. My bad. 😊

    Scott



  • hi Arnaud - does the haml in templates hold out for you?

    'cause I’m just dipping my toes into that pond 😃 and though I’ve yarn add --dev hamljs and I trust my HAML to be fairly straight

    <template lang="haml">
      %nav{ class: "white" }
        .nav-wrapper
          %base-hamburger
    </template>
    

    I get this kind of result from my “webpacker”

    webpacker | ERROR in ./app/javascript/components/_base-top_navigation.vue?vue&type=template&id=b470a524&lang=haml& (./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/components/_base-top_navigation.vue?vue&type=template&id=b470a524&lang=haml&)
    webpacker | Module Error (from ./node_modules/vue-loader/lib/loaders/templateLoader.js):
    webpacker | (Emitted value instead of an instance of Error) 
    webpacker | 
    webpacker |   Errors compiling template:
    webpacker | 
    webpacker |   Component template requires a root element, rather than just text.
    webpacker | 
    webpacker |   1  |  
    webpacker |      |   
    webpacker |   2  |  %nav{ class: "white" }
    webpacker |      |  ^^^^^^^^^^^^^^^^^^^^^^
    webpacker |   3  |    .nav-wrapper
    webpacker |      |  ^^^^^^^^^^^^^^
    webpacker |   4  |      %base-hamburger
    webpacker |      |  ^^^^^^^^^^^^^^^^^^^
    webpacker |   5  |  
    webpacker |      |  
    webpacker |   6  |  
    


  • Solved it myself - I’m happy to report 🙂

    First of all I had to add a loader with yarn add --dev haml-plain-loader and the mention it in config/webpack/loaders/haml.js like this

    module.exports = {
      test: /\.haml$/,
      use: [{
        loader: 'haml-plain-loader'
      }]
    }
    
    

    further I had to mention all of it in config/webpack/environment.js like this

    const haml = require('./loaders/haml')
    environment.loaders.prepend('haml', haml)
    

Log in to reply