Skip to content

Commit

Permalink
Add support for slim
Browse files Browse the repository at this point in the history
Note: have to use slim >= 2.0.0.pre.9
spree#65 (comment)
  • Loading branch information
doabit authored and BDQ committed May 29, 2013
1 parent 51bc5f7 commit 067a4a0
Show file tree
Hide file tree
Showing 17 changed files with 170 additions and 21 deletions.
1 change: 1 addition & 0 deletions deface.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Gem::Specification.new do |s|

s.add_development_dependency('rspec', '>= 2.11.0')
s.add_development_dependency('haml', '>= 3.1.4')
s.add_development_dependency('slim', '>= 2.0.0.pre.9')
s.add_development_dependency('simplecov', '>= 0.6.4')
s.add_development_dependency('generator_spec', '~> 0.8.5')
end
3 changes: 2 additions & 1 deletion lib/deface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require "deface/sources/text"
require "deface/sources/erb"
require "deface/sources/haml"
require "deface/sources/slim"
require "deface/sources/partial"
require "deface/sources/template"
require "deface/sources/copy"
Expand Down Expand Up @@ -46,5 +47,5 @@ module Deface
class DefaceError < StandardError; end

class NotSupportedError < DefaceError; end

end
8 changes: 5 additions & 3 deletions lib/deface/action_view_extensions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
def initialize(source, identifier, handler, details)
if Rails.application.config.deface.enabled && should_be_defaced?(handler)
haml = handler.to_s == "Haml::Plugin"
slim = handler.class.to_s == "Slim::RailsTemplate"

processed_source = Deface::Override.apply(source, details, true, haml )
processed_source = Deface::Override.apply(source, details, true, haml, slim)

if haml && processed_source != source
if haml && processed_source != source || slim && processed_source != source
handler = ActionView::Template::Handlers::ERB
end
else
Expand Down Expand Up @@ -54,7 +55,8 @@ def method_name
private

def should_be_defaced?(handler)
handler.to_s.demodulize == "ERB" || handler.class.to_s.demodulize == "ERB" || handler.to_s == "Haml::Plugin"
handler.to_s.demodulize == "ERB" || handler.class.to_s.demodulize == "ERB" ||
handler.to_s == "Haml::Plugin" || handler.class.to_s == 'Slim::RailsTemplate'
end
end

Expand Down
6 changes: 5 additions & 1 deletion lib/deface/applicator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module Applicator
module ClassMethods
# applies all applicable overrides to given source
#
def apply(source, details, log=true, haml=false)
def apply(source, details, log=true, haml=false, slim=false)
overrides = find(details)

if log && overrides.size > 0
Expand All @@ -16,6 +16,10 @@ def apply(source, details, log=true, haml=false)
source = Deface::HamlConverter.new(source).result
end

if slim
source = Slim::ERBConverter.new.call(source)
end

doc = Deface::Parser.convert(source)

overrides.each do |override|
Expand Down
22 changes: 18 additions & 4 deletions lib/deface/dsl/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ module Deface
module DSL
class Loader
def self.load(filename, options = nil, &block)
unless File.basename(filename) =~ /^[^\.]+(.html.(erb|haml)){0,1}.deface$/
raise "Deface::DSL does not know how to read '#{filename}'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface"
unless File.basename(filename) =~ /^[^\.]+(.html.(erb|haml|slim)){0,1}.deface$/
raise "Deface::DSL does not know how to read '#{filename}'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface"
end

unless file_in_dir_below_overrides?(filename)
Expand Down Expand Up @@ -37,6 +37,15 @@ def self.load(filename, options = nil, &block)
context.instance_eval(dsl_commands)
context.haml(the_rest)
context.create_override
elsif context_name.end_with?('.html.slim')
dsl_commands, the_rest = extract_dsl_commands_from_slim(file_contents)

context_name = context_name.gsub('.html.slim', '')
context = Context.new(context_name)
context.virtual_path(determine_virtual_path(filename))
context.instance_eval(dsl_commands)
context.slim(the_rest)
context.create_override
else
context = Context.new(context_name)
context.virtual_path(determine_virtual_path(filename))
Expand Down Expand Up @@ -99,7 +108,12 @@ def self.extract_dsl_commands_from_haml(file_contents)
[dsl_commands, file_contents]
end

private
class << self
alias_method :extract_dsl_commands_from_slim, :extract_dsl_commands_from_haml
end


private

def self.starts_with_html_comment?(line)
line.lstrip.index('<!--') == 0
Expand All @@ -126,4 +140,4 @@ def self.determine_virtual_path(filename)
end
end
end
end
end
5 changes: 3 additions & 2 deletions lib/deface/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ module Deface
Actions::SurroundContents, Actions::InsertBefore, Actions::InsertAfter, Actions::InsertTop,
Actions::InsertBottom, Actions::SetAttributes, Actions::AddToAttributes, Actions::RemoveFromAttributes ]

DEFAULT_SOURCES = [ Sources::Text, Sources::Erb, Sources::Haml, Sources::Partial, Sources::Template, Sources::Cut, Sources::Copy]
DEFAULT_SOURCES = [ Sources::Text, Sources::Erb, Sources::Haml, Sources::Slim, Sources::Partial, Sources::Template, Sources::Cut, Sources::Copy]

class Environment
attr_accessor :overrides, :enabled, :haml_support, :namespaced
attr_accessor :overrides, :enabled, :haml_support, :namespaced, :slim_support
def initialize
@overrides = Overrides.new
@enabled = true
@haml_support = false
@slim_support = false
@actions = []
@sources = []
@namespaced = false
Expand Down
5 changes: 5 additions & 0 deletions lib/deface/railtie.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ def self.activate
require 'deface/haml_converter'
end

if defined?(Slim)
app.config.deface.slim_support = true
require 'slim/erb_converter'
end

# catchs any overrides that we required manually
app.config.deface.overrides.early_check

Expand Down
13 changes: 13 additions & 0 deletions lib/deface/sources/slim.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Deface
module Sources
class Slim < Source
def self.execute(override)
if Rails.application.config.deface.slim_support
::Slim::ERBConverter.new.call(override.args[:slim])
else
raise Deface::NotSupportedError, "`#{override.name}` supplies :slim source, but slim_support is not detected."
end
end
end
end
end
2 changes: 2 additions & 0 deletions lib/deface/template_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ def load_template_source(virtual_path, partial, apply_overrides=true)

if view.handler.to_s == "Haml::Plugin"
Deface::HamlConverter.new(view.source).result
elsif view.handler.class.to_s == "Slim::RailsTemplate"
Slim::ERBConverter.new.call(view.source)
else
view.source
end
Expand Down
3 changes: 3 additions & 0 deletions lib/generators/deface/templates/override.html.slim.deface
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/
insert_after 'h1'
h2 These robots are awesome.
1 change: 1 addition & 0 deletions spec/assets/shared/_hi.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
div class="some" id="message"= "Hi, World!"
5 changes: 5 additions & 0 deletions spec/assets/shared/public.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#content
.left
p= print_information
.right(id=@right)
= render :partial => "sidebar"
65 changes: 60 additions & 5 deletions spec/deface/dsl/loader_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,47 @@
filename = 'app/overrides/example_name.deface'

lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
"Deface::DSL does not know how to read 'app/overrides/example_name.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
"Deface::DSL does not know how to read 'app/overrides/example_name.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end

it 'should succeed if file ends with .html.erb.deface' do
file = mock('deface file')
filename = 'app/overrides/example_name.html.erb.deface'

lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
"Deface::DSL does not know how to read 'app/overrides/example_name.html.erb.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
"Deface::DSL does not know how to read 'app/overrides/example_name.html.erb.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end

it 'should succeed if file ends with .html.haml.deface' do
file = mock('deface file')
filename = 'app/overrides/example_name.html.haml.deface'

lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
"Deface::DSL does not know how to read 'app/overrides/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
"Deface::DSL does not know how to read 'app/overrides/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end

it 'should succeed if file ends with .html.slim.deface' do
file = mock('deface file')
filename = 'app/overrides/example_name.html.slim.deface'

lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
"Deface::DSL does not know how to read 'app/overrides/example_name.html.slim.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end

it 'should fail if file ends with .blargh.deface' do
file = mock('deface file')
filename = 'app/overrides/example_name.blargh.deface'

lambda { Deface::DSL::Loader.load(filename) }.should raise_error(
"Deface::DSL does not know how to read 'app/overrides/example_name.blargh.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
"Deface::DSL does not know how to read 'app/overrides/example_name.blargh.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end

it "should suceed if parent directory has a dot(.) in it's name" do
file = mock('deface file')
filename = 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'

lambda { Deface::DSL::Loader.load(filename) }.should_not raise_error(
"Deface::DSL does not know how to read 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, or .html.haml.deface")
"Deface::DSL does not know how to read 'app/overrides/parent.dir.with.dot/example_name.html.haml.deface'. Override files should end with just .deface, .html.erb.deface, .html.haml.deface or .html.slim.deface")
end
end

Expand Down Expand Up @@ -124,6 +132,31 @@
Deface::DSL::Loader.load(filename)
end

it 'should set the virtual_path for a .html.slim.deface file in a directory below overrides' do
file = mock('html/slim/deface file')
filename = 'app/overrides/path/to/view/example_name.html.slim.deface'
File.should_receive(:open).with(filename).and_yield(file)

override_name = 'example_name'
context = mock('dsl context')
Deface::DSL::Context.should_receive(:new).with(override_name).
and_return(context)

file_contents = mock('file contents')
file.should_receive(:read).and_return(file_contents)

Deface::DSL::Loader.should_receive(:extract_dsl_commands_from_slim).
with(file_contents).
and_return(['dsl commands', 'slim'])

context.should_receive(:virtual_path).with('path/to/view').ordered
context.should_receive(:instance_eval).with('dsl commands').ordered
context.should_receive(:slim).with('slim').ordered
context.should_receive(:create_override).ordered

Deface::DSL::Loader.load(filename)
end

end

context '.register' do
Expand Down Expand Up @@ -220,6 +253,28 @@
dsl_commands.should == ""
the_rest.should == example
end
end

context '.extract_dsl_commands_from_slim' do
it 'should work in the simplest case' do
example = "/ test 'command'\n/ another 'command'\nh1 Wow!"
dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_slim(example)
dsl_commands.should == "test 'command'\nanother 'command'\n"
the_rest.should == "h1 Wow!"
end

it 'should work with a block style comment using spaces' do
example = "/\n test 'command'\n another 'command'\nh1 Wow!"
dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_slim(example)
dsl_commands.should == "\ntest 'command'\nanother 'command'\n"
the_rest.should == "h1 Wow!"
end

it 'should leave internal comments alone' do
example = "br\n/ test 'command'\n/ another 'command'\nh1 Wow!"
dsl_commands, the_rest = Deface::DSL::Loader.extract_dsl_commands_from_erb(example)
dsl_commands.should == ""
the_rest.should == example
end
end
end
20 changes: 17 additions & 3 deletions spec/deface/override_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,20 @@ module Deface
end
end

describe "with :slim" do

before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :replace => "h1",
:slim => %q{strong class="code" id="message"= 'Hello, World!'})
end

it "should return erb converted from slim as source" do
@override.source.should == "<strong class=\"code\" id=\"message\"><%= ::Temple::Utils.escape_html_safe(('Hello, World!')) %><%\n%></strong>"

@override.source_argument.should == :slim
end
end


describe "with :partial containing erb" do

Expand Down Expand Up @@ -200,7 +214,7 @@ module Deface
let(:parsed) { Deface::Parser.convert("<h1>World</h1><% if true %><p>True that!</p><% end %><p>Hello</p>") }

before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
:copy => {:start => "code:contains('if true')", :end => "code:contains('end')"})

@override.stub(:parsed_document).and_return(parsed)
Expand Down Expand Up @@ -259,14 +273,14 @@ module Deface
let(:parsed) { Deface::Parser.convert("<h1>World</h1><% if true %><p>True that!</p><% end %><%= hello %>") }

before(:each) do
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
@override = Deface::Override.new(:virtual_path => "posts/index", :name => "Posts#index", :insert_after => "h1",
:cut => {:start => "code:contains('if true')", :end => "code:contains('end')"})

@override.stub(:parsed_document).and_return(parsed)
end

it "should remove cut element from original parsed source" do
@override.source
@override.source
if RUBY_PLATFORM == 'java'
parsed.to_s.gsub(/\n/,'').should == "<h1>World</h1><code erb-loud=\"\"> hello </code>"
else
Expand Down
22 changes: 20 additions & 2 deletions spec/deface/template_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ module Deface
end

it "should return converted source for partial containing haml" do
load_template_source("shared/hello", true).should =="<div class='<%= @some %>' id='message'><%= 'Hello, World!' %>\n</div>\n"
load_template_source("shared/hello", true).should == "<div class='<%= @some %>' id='message'><%= 'Hello, World!' %>\n</div>\n"
end

it "should return converted source for partial containing slim" do
load_template_source("shared/hi", true).should == "<div class=\"some\" id=\"message\"><%= ::Temple::Utils.escape_html_safe((\"Hi, World!\")) %><%\n%></div>"
end

it "should return source for template" do
Expand All @@ -28,6 +32,11 @@ module Deface
load_template_source("shared/pirate", false).gsub(/\s/, '').should == "<divid='content'><divclass='left'><p><%=print_information%></p></div><divclass='right'id='<%=@right%>'><%=render:partial=>\"sidebar\"%></div></div>"
end

it "should return converted source for template containing slim" do
result = "<divid=\"content\"><%%><divclass=\"left\"><%%><p><%=::Temple::Utils.escape_html_safe((print_information))%><%%></p></div><divclass=\"right\"<%_slim_codeattributes1=@right;case(_slim_codeattributes1);whentrue%>id=\"id\"<%whenfalse,nil;else%>id=\"<%=::Temple::Utils.escape_html_safe((_slim_codeattributes1))%>\"<%end%>><%%><%=::Temple::Utils.escape_html_safe((render:partial=>\"sidebar\"))%><%%></div></div>"
load_template_source("shared/public", false).gsub(/\s/, '').should == result
end

it "should return source for namespaced template" do
load_template_source("admin/posts/index", false).should == "<h1>Manage Posts</h1>\n"
end
Expand All @@ -54,7 +63,11 @@ module Deface
end

it "should return converted and overridden source for partial containing haml" do
load_template_source("shared/hello", true).should =="<div class=\"<%= @some %>\" id=\"message\"><%= 'Goodbye World!' %></div>"
load_template_source("shared/hello", true).should == "<div class=\"<%= @some %>\" id=\"message\"><%= 'Goodbye World!' %></div>"
end

it "should return converted and overridden source for partial containing slim" do
load_template_source("shared/hi", true).should == "<div class=\"some\" id=\"message\"><%= ::Temple::Utils.escape_html_safe((\"Hi, World!\")) %><%\n%></div>"
end

it "should return overridden source for partial excluding overrides" do
Expand All @@ -69,6 +82,11 @@ module Deface
load_template_source("shared/pirate", false).gsub(/\s/, '').should == "<divid=\"content\"><divclass=\"left\"><h1>Argh!</h1></div><divclass=\"right\"id=\"<%=@right%>\"><%=render:partial=>\"sidebar\"%></div></div>"
end

it "should return converted and overridden source for template containing slim" do
result = "<divid=\"content\"><%%><divclass=\"left\"><%%><p><%=::Temple::Utils.escape_html_safe((print_information))%><%%></p></div><divclass=\"right\"<%_slim_codeattributes1=@right;case(_slim_codeattributes1);whentrue%>id=\"id\"<%whenfalse,nil;else%>id=\"<%=::Temple::Utils.escape_html_safe((_slim_codeattributes1))%>\"<%end%>><%%><%=::Temple::Utils.escape_html_safe((render:partial=>\"sidebar\"))%><%%></div></div>"
load_template_source("shared/public", false).gsub(/\s/, '').should == result
end

it "should return source for namespaced template including overrides" do
load_template_source("admin/posts/index", false).should == "<h1>Argh!</h1>"
end
Expand Down
Loading

0 comments on commit 067a4a0

Please sign in to comment.