3

I would like to create a basic ruby script that renders Slim templates into html (This would eventually be part of a larger project). Ideally I would like to use the HTML produced within the script.

I understand this is possible using TILT (as shown in the SLIM README) where it says the following:


Slim uses Tilt to compile the generated code. If you want to use the Slim template directly, you can use the Tilt interface.

 Tilt.new['template.slim'].render(scope)
 Slim::Template.new('template.slim', optional_option_hash).render(scope)
 Slim::Template.new(optional_option_hash) { source }.render(scope)

The optional option hash can have to options which were documented in the section above. The scope is the object in which the template code is executed.


However, I'm still unable to successfully run this. Therefore, I was wondering if someone could help me by producing a working example.

EDIT (this has recently been edited further ):

I have played about with the code quite a bit but I keep on getting the following error:

 undefined local variable or method `source' for main:Object (NameError)

This is what i'm running:

require 'slim'

# I'm not sure about the next two lines...
optional_option_hash = {}
scope = Object.new    

Tilt.new('template.slim').render(scope)
Slim::Template.new('template.slim', optional_option_hash).render(scope)
Slim::Template.new(optional_option_hash) { source }.render(scope)    

Many Thanks for all your help.

Ismail Moghul
  • 2,864
  • 2
  • 22
  • 28
  • 2
    "Unable to sucessfully run this" is not an adequate description of the problem. – David Grayson Nov 19 '14 at 15:25
  • @DavidGrayson I have now edited the post to show details of what I had done so far – Ismail Moghul Nov 19 '14 at 17:00
  • 1
    Clicking through to the page for [Tilt](https://github.com/rtomayko/tilt), it looks like the current 2.0 release has different syntax. In particular it should be `Tilt.new('template.slim')`, which is why you're getting the `ArgumentError`. – Max Nov 19 '14 at 17:58
  • @Max, Many Thanks, that solved that error, I now get uninitialised method or variable for scope and if I made scope = Object.new then I get uninsitialised method or variable for source... – Ismail Moghul Nov 20 '14 at 15:14
  • 1
    @IsmailM I think you need to stop blindly copy-pasting code and read about how to use these libararies. And that new error message _clearly_ tells you what's wrong: `source` is not defined. – Max Nov 20 '14 at 15:31
  • @Max the problem is that I'm not sure what `source` and `scope` should be... Are they variables (containing exactly what) or are they Objects (of what).. – Ismail Moghul Nov 20 '14 at 15:33
  • It sounds like you basically want someone to explain how to use these libraries. That isn't exactly what Stack Overflow is about. I don't know how to use them. I could read the documentation and make a small example for you, but it's not clear that that would actually answer your question. – Max Nov 20 '14 at 15:39
  • @Max I can use this library (with Sinatra or other) but cannot use it directly in ruby... I have looked at the Docs and only found a few lines showing that it was possible (but they seemed to be incomplete)... I looked elsewhere and could not find an example... I have spent a few hours trying to play with the code and did not get anywhere... So I wen to StackOverFlow to see if someone else has done this before and could provide be with a working example... – Ismail Moghul Nov 20 '14 at 15:43
  • @Max just found [this](http://stackoverflow.com/questions/7058993/specifying-a-layout-and-a-template-in-a-standalone-not-rails-ruby-app-using-s) which does what I want – Ismail Moghul Nov 20 '14 at 15:46

2 Answers2

10

See Specifying a layout and a template in a standalone (not rails) ruby app, using slim or haml

This is what I ended up using:

require 'slim'

# Simple class to represent an environment
class Env
  attr_accessor :name
end

scope = Env.new
scope.name = "test this layout"

layout =<<EOS
h1 Hello
.content
  = yield
EOS

contents =<<EOS
  = name
EOS

layout = Slim::Template.new { layout }
content = Slim::Template.new { contents }.render(scope)

puts layout.render{ content }

For the scope, you can put in modules/classes or even self.

Community
  • 1
  • 1
Ismail Moghul
  • 2,864
  • 2
  • 22
  • 28
2

Quick essentials of

  module SlimRender

    def slim(template, variables = {})
      template = template.to_s
      template += '.slim' unless template.end_with? '.slim'
      template = File.read("#{ROOT}/app/views/#{template}", encoding: 'UTF-8')
      Slim::Template.new { template }.render OpenStruct.new(variables)
    end

  end

Include SlimRender to your class and:

  def render_something
    slim 'streams/scoreboard', scores: '1-2'
  end
Daniel Garmoshka
  • 5,849
  • 39
  • 40