cognitom/gulp-slim

[Question] How I can pass some data?

iserdmi opened this issue · 19 comments

Hello. How can I pass local variables to my haml file? For example with jade I can do something like this:

gulp.task('templates', function() {
  gulp.src('src/templates/**/*.jade')
    .pipe(jade({
      pretty: true,  // Feed the compiler
      data: {        // Feed the templates
        title: 'Hello World!'
      }
    }))
    .pipe(gulp.dest('build'));
});

Yeah, that's exactly what I want to know. As far as I know, there is no way to pass values to Slim.
It's the matter of Slim itself. If you find a way, pls let me know! ;-)

I know how do it, but it is a little bit dirty. Before piping, generate a part of haml file based on our data. Like this (Coffeescript):

data = {baba: 1, gaga: 2, bubu: {lala: 3, nana: 4}};
hack = ''
for key, value of data
    hack = "#{hack}\n- #{key}=" + magic(value) 
gulp
    .src 'src/**/*.slim'
    .pipe insert.prepend(hack)
    .pipe slim()
    .pipe gulp.dest('dist')

Where magic is function which convert js value to literal equivalent: [1,2,3] -> "[1,2,3]", and insert is this npm module.

What do you think about it?

@iserdmi Thanks!
It could be nice to implement it into gulp-slim :)

dmke commented

A cleaner solution would be a custom slimrb wrapper (or a PR on slim-template/slim) adding a command line option to interpret a JSON string as local data, like so:

$ cat foo.slim
p Hello #{name}!
$ slimrb-wrapper --data '{"name":"from Slim"}' foo.slim
<p>Hello from Slim!</p>

where the --data option could be added here (this code is executed when you run the slimrb binary):

def set_opts(opts)
  #...
  opts.on('-d', '--data JSON', 'Interpret a JSON string as local data') do |json|
    @options[:data] = JSON.parse json
  end
  #...
end

... and here:

def process
  # ...
  data = @options.delete(:data)
  result =
    if @options[:erb]
      # q: How to inject data here?
      require 'slim/erb_converter'
      ERBConverter.new(file: @options[:file]).call(@options[:input].read)
    elsif @options[:compile]
      # q: How to inject data here?
      Engine.new(file: @options[:file]).call(@options[:input].read)
    else
      # data can be injected into the render call here:
      Template.new(@options[:file]) { @options[:input].read }.render(Object.new, data)
    end
  #...
end

Finally, something like this

args.push "--data #{JSON.stringify options.data}" if options.data

could be added to the index.coffee.

What are your thoughts on this?

Happy Holidays,
Dominik

dmke commented

I've added a data option in dmke/gulp-slim@ed3637a. If slim-template/slim#572 gets accepted and released, I'll create a PR.

@dmke It's really great!
Looking forward to your PR ;-)

Seems it got accepted, when should we expect this feature to be available in gulp-slim too? Can't wait for it! ^_^

+1 on this.

dmke commented

I have no idea, when a new version is released.

In the meantime you can get the master version with some additional steps:

  1. create a file called Gemfile with this contents:

    source 'https://rubygems.org'
    gem 'slim', github: 'slim-template/slim', branch: 'master'
  2. install bundler and let it fetch the defined version:

    $ gem install bundler
    $ bundle
    
  3. set the bundler and data option in gulp:

    gulp.src("./src/slim/*.slim")
      .pipe(slim({
        bundler: true,
        data: { title: "Hello World!" }
      }))

Every now and then I recommend to run bundle update to... well... update your bundle ;-)

Thanks for @dmke , now gulp-slim v0.1.0 has been released! ;)
https://www.npmjs.com/package/gulp-slim

borm commented

I have installed ruby,gem, slim

gulp.src [Path.assets + o.dirName + '*.slim']
.pipe slim
                pretty  : true
                include : true                
                data    :
                    users: [
                        { name: "Fred" },
                        { name: "Bill" },
                        { name: "Harry" }
                    ]

have error

Error: Slim error in file (/Volumes/www/assets/slim/explore.slim):
NameError: undefined local variable or method `title' for nil:NilClass
  Use --trace for backtrace.

yozzh commented

@borm, i think that problem is in your explore.slim file - you use 'title' variable that not declared in 'data' option

borm commented

Oh, sorry

data    :
                    title: "Just a list of usernames",
                    users: [
                        { name: "Fred" },
                        { name: "Bill" },
                        { name: "Harry" }
                    ]
#players
          h1 = title
          ul
            - for u in users
              li = u.name
events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: Slim error in file (/Volumes/www/assets/slim/explore.slim):
NoMethodError: undefined method `name' for {"name"=>"Fred"}:Hash
  Use --trace for backtrace.

yozzh commented

can you show me your explore.slim file?

borm commented

Full explore.slim

doctype html
html
  head
    title TestSlim
    meta charset="utf-8"
    meta name="keywords" content="slim"
    meta name="viewport" content="width=device-width, initial-scale=1"
    link rel="stylesheet" href="public/css/style.css"
  body
    .wrapper
      .content
        // Header
        include ./header

        // Filter
        include ./filter

        // Users
        #users
          h1 = title
          - for u in users
            li = u.name
        // Need Help?
        include ./help?

      // Footer
      include ./footer

    script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"
    script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"
yozzh commented

Use this syntax to operate an object's properties:
u['name'] not u.name

borm commented

Yes, its work, thanks
but what trouble?
in docs says

Passing Data into the Template

slim({
  data: {
    title: "Just a list of usernames",
    users: [
      { name: "Fred" },
      { name: "Bill" },
      { name: "Harry" }
    ]
  }
})
doctype html
html
  head
    title = title
  body
    h1 = title
    ul
      - for u in users
        li = u.name
yozzh commented

I think that it is an error in gulp-slim documentation. Gulp-slim converts data object to Hash not to Object

borm commented

Okey, thanks again, my problem is resolved