HAML support #399

Closed
nicolai86 opened this Issue Sep 11, 2012 · 21 comments

Projects

None yet
@nicolai86

Any thoughs on supporting HAML so we don't have to write raw HTML?

I'd love this and it would make a great addition.

Anyways, cheers for the release!

@addyosmani
Member

Just leaving this here for later https://github.com/andrewrjones/grunt-haml

@nicolai86

Thanks for the heads up, @addyosmani . Turns out using HAML is as easy as this:

 $ npm install grunt-haml

Then, just below 'use strict'; add grunt.loadNpmTasks('grunt-haml'); to your Gruntfile.js.

Also add

 haml: {
  index: {
    src: "app/index.haml",
    dest: "app/index.html"
  }
},

and , inside of the watch key

haml: {
    files: [
      'app/*.haml'
    ],
    tasks: 'haml'
  },

.

yeoman server and your done, assuming you have an index.haml file inside of app/

Works great, all you have to do is port the original index.html - or remove it entirely.

I don't know if this will work on every case, like build processes or tests, but it works with the live-reload feature.

@addyosmani
Member

Thanks for the write-up :) Until we decide to support something like this, im sure it will help others also wondering how to get it in there!

@paulirish paulirish closed this Sep 12, 2012
@vlad
vlad commented Oct 8, 2012

@nicolai86, thanks for posting this! I notice the reload section should also be changed to look something like this:

      reload: {
        files: [
          'app/*.haml',
          'app/*.html',
          'app/styles/**/*.css',
          'app/scripts/**/*.js',
          'app/views/**/*.haml',
          'app/views/**/*.html',
          'app/images/**/*'
        ],
        tasks: 'reload'
      }

In case this helps others, I converted the html files that yeoman init angular generates to HAML, and put them up in a repo along with a new Gruntfile.js:

https://github.com/vlad/yeoman-angularjs-haml

@phedinkus

@vlad, I've tried adding this to my yeoman project and get a fatal error:

Task "haml" not found.

I followed your config exactly and I've tried it in the past and it worked just fine. Any pointers for where I'm going wrong? Here's the gist:

https://gist.github.com/d297b6d156f37cb60506

ps: I installed grunt-haml with npm.

@PaBLoX-CL

Sorry, I don't understand something. Is haml working with yeoman or not? O_o. I've read that solution is using haml.js which it isn't the "real" implementation (ruby). Is really an issue?

@rhacker
rhacker commented Feb 18, 2013

@PaBLoX-CL since yeoman depends on grunt. The gruntfile contains all the tasks that will be run or reload when you run yeoman server.

it's not officially pronounced but actually you can make it work. Read the comments above. Hope someone have time to gather everything in one post :)

@amboy00
amboy00 commented Apr 21, 2013

How much has changes to the js file since Yeoman update? I'm not having much luck. Would really like HAML a part of this.

@kayjtea
kayjtea commented Jun 9, 2013

I've created an up-to-date (as of early June 2013) sample/seed project, https://github.com/tuyen/yeoman-angular-haml

@tomlane
Contributor
tomlane commented Jun 9, 2013

Hey @tuyen might be better adding this to the wiki page for projects

@simeonwillbanks

@tuyen @tomlane I updated the wiki projects page with a link to a gist. I used yeoman-angular-haml as a guide, but refactored to include the app's index.haml, not just it's views.

@metalshark

Using HAML/SASS/CoffeeScript, based on the latest yo webapp for all files (replacing index.html, main.js, etc) required a bit of work to the Gruntfile. It became easier to keep track of locations using:

        # configurable paths
        yeoman:
            app: 'app'
            dist: 'dist'
            temp: '.tmp'
            test: 'test'

and then referring to <%= yeoman.* %>.

You will need to use gem install haml, npm install grunt-contrib-haml --save-dev (yup it uses the ruby version of HAML), npm install grunt-contrib-coffee --save-dev and npm install grunt-contrib-coffeelint --save-dev.

The biggest change was getting usemin/requirejs to look in <%= yeoman.temp %> instead of <%= yeoman.app %> and also rigging up grunt test so that it renders haml files first.

grunt build still isn't how I want it, as it repeats certain tasks and requires a separate copy step for requirejs (copying to temp):

# Generated on 2013-10-24 using generator-webapp 0.4.3
'use strict'

# # Globbing
# for performance reasons we're only matching one level down:
# 'test/spec/{,*/}*.js'
# use this if you want to recursively match all subfolders:
# 'test/spec/**/*.js'
module.exports = (grunt) ->

    # show elapsed time at the end
    require('time-grunt') grunt

    # load all grunt tasks
    require('load-grunt-tasks') grunt
    grunt.initConfig

        # configurable paths
        yeoman:
            app: 'app'
            dist: 'dist'
            temp: '.tmp'
            test: 'test'

        watch:
            haml:
                files: ['<%= yeoman.app %>/{,*/}*.haml']
                tasks: ['haml:dist']

            coffee:
                files: ['<%= yeoman.app %>/scripts/{,*/}*.coffee']
                tasks: ['coffee:dist']

            coffeeTest:
                files: ['<%= yeoman.test %>/spec/{,*/}*.coffee']
                tasks: ['coffee:test']

            compass:
                files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}']
                tasks: ['compass:server', 'autoprefixer']

            styles:
                files: ['<%= yeoman.app %>/styles/{,*/}*.css']
                tasks: ['copy:styles', 'autoprefixer']

            livereload:
                options:
                    livereload: '<%= connect.options.livereload %>'

                files: [
                    '<%= yeoman.temp %>/styles/{,*/}*.css',
                    '{<%= yeoman.temp %>,<%= yeoman.app %>}/{,*/}*.html',
                    '{<%= yeoman.temp %>,<%= yeoman.app %>}/scripts/{,*/}*.js',
                    '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
                ]

        connect:
            options:
                port: 9000
                livereload: 35729

                # change this to '0.0.0.0' to access the server from outside
                hostname: 'localhost'

            livereload:
                options:
                    open: true
                    base: [
                        '<%= yeoman.temp %>'
                        '<%= yeoman.app %>'
                    ]

            test:
                options:
                    base: [
                        '<%= yeoman.temp %>'
                        '<%= yeoman.test %>'
                        '<%= yeoman.app %>'
                    ]

            dist:
                options:
                    open: true
                    base: '<%= yeoman.dist %>'

        clean:
            dist:
                files: [
                    dot: true
                    src: [
                        '<%= yeoman.temp %>'
                        '<%= yeoman.dist %>/*'
                        '!<%= yeoman.dist %>/.git*'
                    ]
                ]

            server: '<%= yeoman.temp %>'

        jshint:
            options:
                jshintrc: '.jshintrc'

            all: [
                'Gruntfile.js'
                '<%= yeoman.app %>/scripts/{,*/}*.js'
                '!<%= yeoman.app %>/scripts/vendor/*'
                '<%= yeoman.test %>/spec/{,*/}*.js'
            ]

        mocha:
            all:
                options:
                    run: true
                    urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html']

        coffee:
            dist:
                files: [
                    expand: true
                    cwd: '<%= yeoman.app %>/scripts'
                    src: '{,*/}*.coffee'
                    dest: '<%= yeoman.temp %>/scripts'
                    ext: '.js'
                ]

            test:
                files: [
                    expand: true
                    cwd: '<%= yeoman.test %>/spec'
                    src: '{,*/}*.coffee'
                    dest: '<%= yeoman.temp %>/spec'
                    ext: '.js'
                ]

        coffeelint:
            options:
                indentation:
                    value: 4
                max_line_length:
                    value: 120
            all: [
                'Gruntfile.coffee'
                '<%= yeoman.app %>/scripts/**.coffee'
                '!<%= yeoman.app %>/scripts/vendor/*'
                '<%= yeoman.test %>/spec/**.coffee'
            ]

        haml:
            options:
                doubleQuoteAttributes: true
                escapeHtml: true
                unixNewlines: true

            dist:
                files: [
                    expand: true
                    cwd: '<%= yeoman.app %>'
                    src: '{,*/}*.haml'
                    dest: '<%= yeoman.temp %>'
                    ext: '.html'
                ]

            test:
                files: [
                    expand: true
                    cwd: '<%= yeoman.test %>'
                    src: '{,*/}*.haml'
                    dest: '<%= yeoman.temp %>'
                    ext: '.html'
                ]

        compass:
            options:
                sassDir: '<%= yeoman.app %>/styles'
                cssDir: '<%= yeoman.temp %>/styles'
                generatedImagesDir: '<%= yeoman.temp %>/images/generated'
                imagesDir: '<%= yeoman.app %>/images'
                javascriptsDir: '<%= yeoman.app %>/scripts'
                fontsDir: '<%= yeoman.app %>/styles/fonts'
                importPath: '<%= yeoman.app %>/bower_components'
                httpImagesPath: '/images'
                httpGeneratedImagesPath: '/images/generated'
                httpFontsPath: '/styles/fonts'
                relativeAssets: false
                assetCacheBuster: false

            dist:
                options:
                    generatedImagesDir: '<%= yeoman.dist %>/images/generated'

            server:
                options:
                    debugInfo: true

        autoprefixer:
            options:
                browsers: ['last 1 version']

            dist:
                files: [
                    expand: true
                    cwd: '<%= yeoman.temp %>/styles/'
                    src: '{,*/}*.css'
                    dest: '<%= yeoman.temp %>/styles/'
                ]

        # not used since Uglify task does concat,
        # but still available if needed
        #concat:
        #    dist:
        requirejs:
            dist:

                # Options: https://github.com/jrburke/r.js/blob/master/build/example.build.js
                options:

                    # `name` and `out` is set by grunt-usemin
                    baseUrl: '<%= yeoman.temp %>/scripts'
                    optimize: 'none'

                    # TODO: Figure out how to make sourcemaps work with grunt-usemin
                    # https://github.com/yeoman/grunt-usemin/issues/30
                    #generateSourceMaps: true,
                    # required to support SourceMaps
                    # http://requirejs.org/docs/errors.html#sourcemapcomments
                    preserveLicenseComments: false
                    useStrict: true
                    wrap: true


        #uglify2: {} // https://github.com/mishoo/UglifyJS2
        rev:
            dist:
                files:
                    src: [
                        '<%= yeoman.dist %>/scripts/{,*/}*.js'
                        '<%= yeoman.dist %>/styles/{,*/}*.css'
                        '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp}'
                        '<%= yeoman.dist %>/styles/fonts/{,*/}*.*'
                    ]

        useminPrepare:
            options:
                dest: '<%= yeoman.dist %>'

            html: '<%= yeoman.temp %>/index.html'

        usemin:
            options:
                dirs: ['<%= yeoman.dist %>']

            html: ['<%= yeoman.dist %>/{,*/}*.html']
            css: ['<%= yeoman.dist %>/styles/{,*/}*.css']

        imagemin:
            dist:
                files: [
                    expand: true
                    cwd: '<%= yeoman.app %>/images'
                    src: '**/*.{png,jpg,jpeg}'
                    dest: '<%= yeoman.dist %>/images'
                ]

        svgmin:
            dist:
                files: [
                    expand: true
                    cwd: '<%= yeoman.app %>/images'
                    src: '{,*/}*.svg'
                    dest: '<%= yeoman.dist %>/images'
                ]

        cssmin: {}

        # This task is pre-configured if you do not wish to use Usemin
        # blocks for your CSS. By default, the Usemin block from your
        # `index.html` will take care of minification, e.g.
        #
        # <!-- build:css({<%= yeoman.temp %>,app}) styles/main.css -->
        #
        # dist:
        #     files:
        #         '<%= yeoman.dist %>/styles/main.css': [
        #             '<%= yeoman.temp %>/styles/{,*/}*.css'
        #             '<%= yeoman.app %>/styles/{,*/}*.css'
        #         ]
        htmlmin:
            dist:
                options: {}
                #removeCommentsFromCDATA: true,
                #https://github.com/yeoman/grunt-usemin/issues/44
                #collapseWhitespace: true,
                #collapseBooleanAttributes: true,
                #removeAttributeQuotes: true,
                #removeRedundantAttributes: true,
                #useShortDoctype: true,
                #removeEmptyAttributes: true,
                #removeOptionalTags: true
                files: [
                    expand: true
                    cwd: '<%= yeoman.temp %>'
                    src: '*.html'
                    dest: '<%= yeoman.dist %>'
                ]


        # Put files not handled in other tasks here
        copy:
            dist:
                files: [
                    expand: true
                    dot: true
                    cwd: '<%= yeoman.app %>'
                    dest: '<%= yeoman.dist %>'
                    src: [
                        '*.{ico,png,txt}'
                        '.htaccess'
                        'images/**/*.{webp,gif}'
                        'styles/fonts/{,*/}*.*'
                        'bower_components/sass-bootstrap/fonts/*.*'
                    ]
                ]

            temp:
                files: [
                    expand: true
                    dot: true
                    cwd: '<%= yeoman.app %>'
                    dest: '<%= yeoman.temp %>'
                    src: [
                        'bower_components/**/*.js'
                        'scripts/**/*.js'
                    ]
                ]

            styles:
                expand: true
                dot: true
                cwd: '<%= yeoman.app %>/styles'
                dest: '<%= yeoman.temp %>/styles/'
                src: '{,*/}*.css'

        modernizr:
            devFile: '<%= yeoman.app %>/bower_components/modernizr/modernizr.js'
            outputFile: '<%= yeoman.dist %>/bower_components/modernizr/modernizr.js'
            files: [
                '<%= yeoman.dist %>/scripts/{,*/}*.js'
                '<%= yeoman.dist %>/styles/{,*/}*.css'
                '!<%= yeoman.dist %>/scripts/vendor/*'
            ]
            uglify: true

        concurrent:
            server: [
                'haml:dist'
                'compass'
                'coffee:dist'
                'copy:styles'
            ]
            test: [
                'haml:test'
                'coffee:test'
                'copy:styles'
            ]
            dist: [
                'haml:dist'
                'compass'
                'coffee:dist'
                'copy:styles'
                'imagemin'
                'svgmin'
                'htmlmin'
            ]

        bower:
            options:
                exclude: ['modernizr']

            all:
                rjsConfig: '<%= yeoman.temp %>/scripts/main.js'

    grunt.registerTask 'server', (target) ->
        return grunt.task.run([
            'build'
            'connect:dist:keepalive'
        ]) if target is 'dist'
        grunt.task.run [
            'clean:server'
            'concurrent:server'
            'autoprefixer'
            'connect:livereload'
            'watch'
        ]

    grunt.registerTask 'test', [
        'clean:server'
        'concurrent:test'
        'autoprefixer'
        'connect:test'
        'mocha'
    ]
    grunt.registerTask 'build', [
        'clean:dist'
        'haml:dist'       # usemin needs index.html
        'useminPrepare'
        'concurrent:dist'
        'autoprefixer'
        'coffee:dist'     # requirejs needs scripts/main.js
        'copy:temp'       # and other javascript libraries
        'requirejs'
        'concat'
        'cssmin'
        'uglify'
        'modernizr'
        'copy:dist'
        'rev'
        'usemin'
    ]
    grunt.registerTask 'default', [
        'coffeelint'
        'jshint'
        'test'
        'build'
    ]
@decklord
decklord commented Mar 4, 2014

Is there any way to make render partials work in Yeoman using HAML? It would be great to import template files instead of copying everything on index.haml.

@pmackay
pmackay commented Apr 19, 2014

Is it possible this might be integrated directly into Yeoman? So a choice to use HAML would be part of the setup wizard?

@kayjtea
kayjtea commented Apr 19, 2014

It's unlikely yeoman will get direct integrated HAML support. The plugin works pretty well though and is seamless once set up. I really need to update this project for latest libs.

Sent from my iPhone

On Apr 19, 2014, at 2:25 PM, Paul Mackay notifications@github.com wrote:

Is it possible this might be integrated directly into Yeoman? So a choice to use HAML would be part of the setup wizard?


Reply to this email directly or view it on GitHub.

@PavelDemyanenko

@decklord well, you can check jade instead. It uses include.

@antonmaximus

Why can't HAML be directly integrated with Yeoman by default (i.e., without any hackery)?

@SBoudrias
Member

@antonmaximus Just write a generator creating HAML stuff. Yeoman just provide a scaffolding system; it's the community job to create generators fitting their needs.

@antonmaximus

@SBoudrias, I can't seem to find any HAML generator on the site http://yeoman.io/generators/.

@SBoudrias
Member

@antonmaximus That's because you haven't create yours yet 🌻

@antonmaximus

ah, of course!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment