mynyml-merb-in-file-templates 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README +151 -0
- data/Rakefile +54 -0
- data/TODO +10 -0
- data/lib/merb-in-file-templates.rb +23 -0
- data/lib/merb-in-file-templates/cache.rb +45 -0
- data/lib/merb-in-file-templates/in_file_templates_mixin.rb +416 -0
- data/lib/merb-in-file-templates/merbtasks.rb +18 -0
- data/spec/controller3.rb +15 -0
- data/spec/merb-in-file-templates_spec.rb +336 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +13 -0
- metadata +75 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Martin Aumont
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
merb-in-file-templates *ALPHA*
|
2
|
+
==============================
|
3
|
+
WARNING: This plugin isn't stable yet! Feel free to try it out and send patches
|
4
|
+
though.
|
5
|
+
|
6
|
+
A plugin for the Merb framework that allows templates (views) to be defined in
|
7
|
+
the same file as the controller (Sinatra style). Especially useful for
|
8
|
+
--very-flat apps (making them truly flat), apps that have litle/small view
|
9
|
+
code, and for rapid prototyping.
|
10
|
+
|
11
|
+
==== Features
|
12
|
+
* Seamless integration with #render, #display
|
13
|
+
* Respects template reloading
|
14
|
+
* Very simple to use
|
15
|
+
* Flexible
|
16
|
+
|
17
|
+
==== Dependencies
|
18
|
+
* Merb > 0.9.4 (?)
|
19
|
+
* Rspec to run the specs
|
20
|
+
|
21
|
+
==== Examples
|
22
|
+
#example for --very-flat app (single file app)
|
23
|
+
|
24
|
+
#...
|
25
|
+
class Application < Merb::Controller; end
|
26
|
+
class Products < Application
|
27
|
+
def index
|
28
|
+
@products = Product.all
|
29
|
+
render
|
30
|
+
end
|
31
|
+
def show
|
32
|
+
@product = Product[params[:id]]
|
33
|
+
render
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
__END__
|
38
|
+
@@ index.html.erb
|
39
|
+
<h1>Product List</h1>
|
40
|
+
<ul>
|
41
|
+
<% for product in @products -%>
|
42
|
+
<li><%= product.name %></li>
|
43
|
+
<% end -%>
|
44
|
+
</ul>
|
45
|
+
|
46
|
+
@@ show.html.erb
|
47
|
+
<h1><%= @product.name %></h1>
|
48
|
+
|
49
|
+
In-file templates cohabit peacefully with regular external templates. So in the
|
50
|
+
above example, show.html.erb could be defined in views/products/show.html.erb
|
51
|
+
and both templates will still be picked up normally. In case of a name conflict
|
52
|
+
between an in-file and an external template, the external one will take
|
53
|
+
precedence and won't be overwritten, keeping it safe from data loss.
|
54
|
+
|
55
|
+
Template names follow the same rules as regular templates (usually
|
56
|
+
action.mime_type.templating_engine).
|
57
|
+
|
58
|
+
Layouts, stylesheets and javascript can also be placed in in-file templates.
|
59
|
+
|
60
|
+
#...
|
61
|
+
|
62
|
+
__END__
|
63
|
+
@@ layout/application.css
|
64
|
+
#...
|
65
|
+
|
66
|
+
@@ layout/products.css
|
67
|
+
#...
|
68
|
+
|
69
|
+
@@ stylesheets/application.css
|
70
|
+
#...
|
71
|
+
|
72
|
+
@@ javascripts/jquery.js
|
73
|
+
#...
|
74
|
+
|
75
|
+
==== Tweaking
|
76
|
+
In order to be fed into merb's templating system, in-file templates need to be
|
77
|
+
written to external files. This means you will see dynamically created view
|
78
|
+
files inside your Merb.dir_for(:view) directory/subdirectories.
|
79
|
+
|
80
|
+
The directory in which files are stored is chosen based on the templating
|
81
|
+
system's native mechanisms, and so merb-in-file-templates will respect any
|
82
|
+
changes to it. Therefore if you want to change where template files are stored,
|
83
|
+
you can play with Merb.push_path(:view, ...) and the controller's
|
84
|
+
#_template_location method.
|
85
|
+
|
86
|
+
Merb.push_path(:view, Merb.root / 'views')
|
87
|
+
class Application
|
88
|
+
def _template_location(context, type=nil, controller = controller_name)
|
89
|
+
"#{controller}.#{action_name}.#{type}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
This will tell Merb to look under the /views directory, for a template named
|
94
|
+
products.index.html.erb.
|
95
|
+
|
96
|
+
want even flatter?
|
97
|
+
|
98
|
+
Merb.push_path(:view, Merb.root)
|
99
|
+
class Application
|
100
|
+
def _template_location(context, type=nil, controller=controller_name)
|
101
|
+
"view.#{controller}.#{action_name}.#{type}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
will give you a template under the root dir called view.products.index.html.erb
|
106
|
+
(adding a common prefix, 'view.' in the example above, causes template files to
|
107
|
+
show up nicely grouped with ls, file managers, etc, so they look organized even
|
108
|
+
without being placed in a subdirectory).
|
109
|
+
|
110
|
+
If you mix in-file and external templates and you don't want them to be mixed
|
111
|
+
in the same directories, you can tell merb-in-file-templates to store its
|
112
|
+
templates somewhere else. This is done through the config hash:
|
113
|
+
|
114
|
+
Merb::Plugins.config[:in_file_templates] = {
|
115
|
+
:view_root => '...',
|
116
|
+
:stylesheets_root => '...',
|
117
|
+
:javascripts_root => '...',
|
118
|
+
}
|
119
|
+
|
120
|
+
For example, you could set
|
121
|
+
|
122
|
+
:view_root => Merb.root / 'tmp' / 'ift_views'
|
123
|
+
|
124
|
+
to store your files in merb-root/tmp/ift_views, or
|
125
|
+
|
126
|
+
:view_root => '/tmp'
|
127
|
+
|
128
|
+
to store files in your system's tmp directory.
|
129
|
+
|
130
|
+
Same goes for stylesheets and javascripts, but remember that those need to be
|
131
|
+
placed in a public directory, and that they need to be referenced properly from
|
132
|
+
within your html header. You can use the controller's
|
133
|
+
#ift_dir_for(:stylesheets) and #ift_dir_for(:javascripts) methods to find their
|
134
|
+
locations.
|
135
|
+
|
136
|
+
==== Rake Task
|
137
|
+
TODO
|
138
|
+
(cleanup rake task before deployment..)
|
139
|
+
|
140
|
+
==== Installation
|
141
|
+
TODO
|
142
|
+
|
143
|
+
==== Contact
|
144
|
+
If you have suggestions, comments, a patch, a git pull request, rants, doc
|
145
|
+
fixes/improvements, etc., feel free to contact me: mynyml at gmail,
|
146
|
+
irc.freenode.net #rubyonrails, #merb
|
147
|
+
|
148
|
+
Happy Hacking!
|
149
|
+
|
150
|
+
-------------------------------------------------------------------------
|
151
|
+
Copyright (c) 2008 Martin Aumont (mynyml), released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
|
6
|
+
PLUGIN = "merb-in-file-templates"
|
7
|
+
NAME = "merb-in-file-templates"
|
8
|
+
GEM_VERSION = "0.3.1"
|
9
|
+
AUTHOR = "Martin Aumont"
|
10
|
+
EMAIL = "mynyml@gmail.com"
|
11
|
+
HOMEPAGE = "http://github.com/mynyml/"
|
12
|
+
SUMMARY = "Merb plugin that allows templates (views, css, js) to be defined in the same file as the controller"
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = NAME
|
16
|
+
s.version = GEM_VERSION
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.has_rdoc = true
|
19
|
+
s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
|
20
|
+
s.summary = SUMMARY
|
21
|
+
s.description = s.summary
|
22
|
+
s.author = AUTHOR
|
23
|
+
s.email = EMAIL
|
24
|
+
s.homepage = HOMEPAGE
|
25
|
+
s.add_dependency('merb', '>= 0.9.4')
|
26
|
+
s.require_path = 'lib'
|
27
|
+
#s.autorequire = PLUGIN
|
28
|
+
s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
29
|
+
end
|
30
|
+
|
31
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
32
|
+
pkg.gem_spec = spec
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "install the plugin locally"
|
36
|
+
task :install => [:package] do
|
37
|
+
sh %{sudo gem install pkg/#{NAME}-#{GEM_VERSION} --no-update-sources}
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "create a gemspec file"
|
41
|
+
task :make_spec do
|
42
|
+
File.open("#{NAME}.gemspec", "w") do |file|
|
43
|
+
file.puts spec.to_ruby
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
namespace :jruby do
|
48
|
+
|
49
|
+
desc "Run :package and install the resulting .gem with jruby"
|
50
|
+
task :install => :package do
|
51
|
+
sh %{#{SUDO} jruby -S gem install pkg/#{NAME}-#{Merb::VERSION}.gem --no-rdoc --no-ri}
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
TODO:
|
2
|
+
* stylesheets/javascripts need to be cached as well
|
3
|
+
* fix caching hierarchy (e.g. layout should not be under a controller in
|
4
|
+
ift.cache)
|
5
|
+
* improve README
|
6
|
+
* test with haml/sass
|
7
|
+
* ensure compatibility with merb-parts and merb-slices
|
8
|
+
* see if there is an alternative to alias_method_chain'ing #render and #display
|
9
|
+
* ift_ namespace is kinda lame - alternative?
|
10
|
+
* fix or find workaround for autotest infinite loops on first pass
|
@@ -0,0 +1,23 @@
|
|
1
|
+
if defined?(Merb::Plugins)
|
2
|
+
|
3
|
+
require 'merb-in-file-templates/cache'
|
4
|
+
require 'merb-in-file-templates/in_file_templates_mixin'
|
5
|
+
|
6
|
+
# Config options
|
7
|
+
# This plugin will respect Merb::Config[:reload_templates]. This means that
|
8
|
+
# if set to true, templates will be rebuilt every time #render is called.
|
9
|
+
Merb::Plugins.config[:in_file_templates] = {
|
10
|
+
:view_root => nil,
|
11
|
+
:stylesheets_root => nil,
|
12
|
+
:javascripts_root => nil,
|
13
|
+
:garbage_collect => true #unused
|
14
|
+
}
|
15
|
+
|
16
|
+
Merb::BootLoader.after_app_loads do
|
17
|
+
Merb::Controller.class_eval do
|
18
|
+
include InFileTemplatesMixin
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Merb::Plugins.add_rakefiles "merb-in-file-templates/merbtasks"
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module InFileTemplatesMixin
|
4
|
+
class Cache #:nodoc:
|
5
|
+
attr_accessor :controller
|
6
|
+
def self.path
|
7
|
+
Merb.dir_for(:config) / 'ift.cache'
|
8
|
+
end
|
9
|
+
def initialize(controller_name)
|
10
|
+
self.controller = controller_name.to_s
|
11
|
+
end
|
12
|
+
def store(tpl_path)
|
13
|
+
self.cache[self.controller] ||= []
|
14
|
+
self.cache[self.controller] << tpl_path
|
15
|
+
self.flush
|
16
|
+
end
|
17
|
+
alias :<< :store
|
18
|
+
def files
|
19
|
+
self.cache[self.controller]
|
20
|
+
end
|
21
|
+
def reset!
|
22
|
+
self.cache.delete(self.controller)
|
23
|
+
self.flush
|
24
|
+
end
|
25
|
+
def exists?
|
26
|
+
!self.cache[self.controller].nil?
|
27
|
+
end
|
28
|
+
protected
|
29
|
+
def cache
|
30
|
+
@cache ||= self.load
|
31
|
+
end
|
32
|
+
def reload!
|
33
|
+
@cache = nil
|
34
|
+
end
|
35
|
+
def load
|
36
|
+
YAML::load_file(self.class.path) || {} rescue {}
|
37
|
+
end
|
38
|
+
def dump
|
39
|
+
open(self.class.path,'w+') do |file|
|
40
|
+
YAML::dump(self.cache,file)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias :flush :dump
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,416 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
# The in-file-templates mixin allows defining view templates inside controller
|
4
|
+
# files. Especially useful for --very-flat apps that have few/small view code,
|
5
|
+
# and for rapid prototyping.
|
6
|
+
#
|
7
|
+
# Templates are defined at the end of the controller file, following the
|
8
|
+
# __END__ keyword (__END__ must be placed at the very beginning of the line,
|
9
|
+
# with nothing following it). Each template is consists of its name, marked by
|
10
|
+
# @@ (@@ must also be placed at the very beginning of the line), followed be
|
11
|
+
# the template's content.
|
12
|
+
#
|
13
|
+
# Template names follow the same rules as regular merb templates:
|
14
|
+
#
|
15
|
+
# name.mime_type.templating_engine:
|
16
|
+
# index.html.erb, edit.html.haml, show.xml.bilder, etc
|
17
|
+
#
|
18
|
+
# ==== Examples
|
19
|
+
# class Application < Merb::Controller; end
|
20
|
+
# class Products < Application
|
21
|
+
# def index
|
22
|
+
# @products = Product.all
|
23
|
+
# render
|
24
|
+
# end
|
25
|
+
# def show
|
26
|
+
# @product = Product[params[:id]]
|
27
|
+
# render
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# __END__
|
32
|
+
# @@ index.html.erb
|
33
|
+
# <h1>Product List</h1>
|
34
|
+
# <ul>
|
35
|
+
# <% for product in @products -%>
|
36
|
+
# <li><%= product.name %></li>
|
37
|
+
# <% end -%>
|
38
|
+
# </ul>
|
39
|
+
#
|
40
|
+
# @@ show.html.erb
|
41
|
+
# <h1><%= @product.name %></h1>
|
42
|
+
#
|
43
|
+
# ==== Notes
|
44
|
+
# Most methods are prefixed with ift_ (In File Templates). This is simply to
|
45
|
+
# avoid naming conflicts with controller methods.
|
46
|
+
module InFileTemplatesMixin
|
47
|
+
|
48
|
+
# When mixin is included in controller, define aliases to wrap #render and
|
49
|
+
# #display
|
50
|
+
#
|
51
|
+
# ==== Parameters
|
52
|
+
# base<Module>:: Module that is including InFileTemplatesMixin (probably a controller)
|
53
|
+
#
|
54
|
+
# ==== Notes
|
55
|
+
# http://yehudakatz.com/2008/05/22/the-greatest-thing-since-sliced-merb/
|
56
|
+
# "We consider cases of people using alias_method_chain on Merb to be a bug in
|
57
|
+
# Merb, and try to find ways to expose enough functionality so it will not be
|
58
|
+
# required."
|
59
|
+
# So could this code be written otherwise, or is it an exception to the above
|
60
|
+
# rule? what are the alternatives?
|
61
|
+
#_
|
62
|
+
# @public
|
63
|
+
def self.included(base)
|
64
|
+
base.send(:alias_method, :render_without_in_file_templates, :render)
|
65
|
+
base.send(:alias_method, :render, :render_with_in_file_templates)
|
66
|
+
base.send(:alias_method, :display_without_in_file_templates, :display)
|
67
|
+
base.send(:alias_method, :display, :display_with_in_file_templates)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Wrap #render to gather template data from caller's file and trigger
|
71
|
+
# template build process.
|
72
|
+
#
|
73
|
+
# ==== Parameters
|
74
|
+
# Same as Merb::RenderMixin#render
|
75
|
+
#
|
76
|
+
# ==== Returns
|
77
|
+
# Same as Merb::RenderMixin#render
|
78
|
+
#
|
79
|
+
# ==== Raises
|
80
|
+
# Same as Merb::RenderMixin#render
|
81
|
+
#
|
82
|
+
# ==== Alternatives
|
83
|
+
# Same as Merb::RenderMixin#render
|
84
|
+
#_
|
85
|
+
# @public
|
86
|
+
def render_with_in_file_templates(*args) #:nodoc:
|
87
|
+
ift_build!((@ift_caller ||= caller).first.split(':').first)
|
88
|
+
render_without_in_file_templates(*args)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Overwrite display and set caller so that #render (called internally by
|
92
|
+
# #display) knows what file to fetch template data from.
|
93
|
+
#
|
94
|
+
# ==== Parameters
|
95
|
+
# Same as Merb::RenderMixin#display
|
96
|
+
#
|
97
|
+
# ==== Returns
|
98
|
+
# Same as Merb::RenderMixin#display
|
99
|
+
#
|
100
|
+
# ==== Raises
|
101
|
+
# Same as Merb::RenderMixin#display
|
102
|
+
#
|
103
|
+
# ==== Alternatives
|
104
|
+
# Same as Merb::RenderMixin#display
|
105
|
+
# -----
|
106
|
+
# @public
|
107
|
+
def display_with_in_file_templates(*args) #:nodoc:
|
108
|
+
@ift_caller = caller
|
109
|
+
display_without_in_file_templates(*args)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Render in-file template in a very basic fashion; only fetches the template
|
113
|
+
# as a string, without having it go through the templating system (which
|
114
|
+
# includes the templating engines). The method then is equivalent to directly
|
115
|
+
# returning a string from the action method.
|
116
|
+
#
|
117
|
+
# ==== Examples
|
118
|
+
# def index
|
119
|
+
# 'hello world'
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# is equivalent to:
|
123
|
+
#
|
124
|
+
# def index
|
125
|
+
# render_from_file(:index)
|
126
|
+
# end
|
127
|
+
# #...
|
128
|
+
# __END__
|
129
|
+
# @@ index
|
130
|
+
# hello world
|
131
|
+
#
|
132
|
+
# You can also use a templating engine manually:
|
133
|
+
#
|
134
|
+
# def index
|
135
|
+
# @name = 'world'
|
136
|
+
# Erubis::Eruby.new(render_from_file(:new)).result(binding)
|
137
|
+
# end
|
138
|
+
# #...
|
139
|
+
# __END__
|
140
|
+
# @@ index
|
141
|
+
# hello <%= @name %>
|
142
|
+
#
|
143
|
+
# ==== Parameters
|
144
|
+
# context<~to_s, nil>::
|
145
|
+
# Name of the template to fetch. Defaults to action name
|
146
|
+
# file<String, nil>::
|
147
|
+
# Path to a file in which to fetch the template data. Default is file this
|
148
|
+
# method has been called from
|
149
|
+
#
|
150
|
+
# ==== Returns
|
151
|
+
# String:: Raw template
|
152
|
+
#
|
153
|
+
# ==== Raises
|
154
|
+
# TemplateNotFound:: There is no template in the specified file.
|
155
|
+
#_
|
156
|
+
# @public
|
157
|
+
def render_from_file(context=action_name, file=nil)
|
158
|
+
file ||= caller.first.split(':').first
|
159
|
+
data = IO.read(file).split('__END__').last
|
160
|
+
ift_parse(data)[context.to_s] or raise(Merb::Controller::TemplateNotFound, "Template #{context} not found in #{File.expand_path(file)}")
|
161
|
+
end
|
162
|
+
|
163
|
+
# Builds templates from in-file data so that they can be picked up by merb's
|
164
|
+
# templating system. Building includes parsing the data to extract the
|
165
|
+
# templates and then writing them to files.
|
166
|
+
#
|
167
|
+
# Will skip rebuilding process if Merb::Config[:reload_templates] is false
|
168
|
+
#
|
169
|
+
# ==== Parameters
|
170
|
+
# file<String>::
|
171
|
+
# Path to a file in which to fetch the template data.
|
172
|
+
#_
|
173
|
+
# @semipublic
|
174
|
+
def ift_build!(file)
|
175
|
+
# write templates to view files if they haven't been already been
|
176
|
+
# written, or always if :reload_templates config option is true
|
177
|
+
return unless !ift_built? || Merb::Config[:reload_templates]
|
178
|
+
|
179
|
+
data = IO.read(file).split('__END__').last
|
180
|
+
templates = ift_parse(data)
|
181
|
+
|
182
|
+
self.ift_set_template_roots!
|
183
|
+
self.ift_garbage_collect!
|
184
|
+
|
185
|
+
templates.each do |name,data|
|
186
|
+
path = ift_path_for(name)
|
187
|
+
unless File.exist?(path) #don't overwrite externaly defined templates
|
188
|
+
self.ift_write_template(path, data)
|
189
|
+
@cache << path
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# Construct path (including filename) for given template name.
|
195
|
+
# Template can be a view, stylesheet or javascript file.
|
196
|
+
#
|
197
|
+
# ==== Parameters
|
198
|
+
# name<String>:: Template name
|
199
|
+
#
|
200
|
+
# ==== Returns
|
201
|
+
# String:: Path to template
|
202
|
+
#
|
203
|
+
# ==== Examples
|
204
|
+
# # given @@ products/foo.html.erb
|
205
|
+
# ift_path_for('foo.html.erb') #=> /merb.root/views/products/foo.html.erb
|
206
|
+
#
|
207
|
+
# # given @@ bar.html.erb
|
208
|
+
# # and current controller is Products
|
209
|
+
# ift_path_for('bar.html.erb') #=> /merb.root/views/products/bar.html.erb
|
210
|
+
#
|
211
|
+
# # given @@ public/stylesheet/app.css
|
212
|
+
# ift_path_for('app.css') #=> /merb.root/public/stylesheets/app.css
|
213
|
+
#_
|
214
|
+
# @semipublic
|
215
|
+
def ift_path_for(name)
|
216
|
+
name =
|
217
|
+
if ift_stylesheet?(name)
|
218
|
+
self.ift_dir_for(:stylesheets) / File.basename(name)
|
219
|
+
elsif ift_javascript?(name)
|
220
|
+
self.ift_dir_for(:javascripts) / File.basename(name)
|
221
|
+
else
|
222
|
+
name = ift_template_dir / name unless name.include?('/') #add path prefix if omitted
|
223
|
+
self.ift_dir_for(:view) / name
|
224
|
+
end
|
225
|
+
File.expand_path(name)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Get in-file template directory for a type. Equivalent to Merb.dir_for,
|
229
|
+
# but taking config options for template paths into consideration.
|
230
|
+
#
|
231
|
+
# ==== Parameters
|
232
|
+
# type<Symbol>::
|
233
|
+
# The type of path to retrieve directory for, e.g. :view. Accepted types
|
234
|
+
# are :view, :stylesheets and :javascripts
|
235
|
+
#
|
236
|
+
# ==== Returns
|
237
|
+
# String:: Path to the type directory
|
238
|
+
#_
|
239
|
+
# @public
|
240
|
+
def ift_dir_for(type)
|
241
|
+
case type
|
242
|
+
when :view
|
243
|
+
Merb::Plugins.config[:in_file_templates][:view_root] ||
|
244
|
+
self._template_root
|
245
|
+
when :stylesheets
|
246
|
+
Merb::Plugins.config[:in_file_templates][:stylesheets_root] ||
|
247
|
+
Merb.dir_for(:stylesheets)
|
248
|
+
when :javascripts
|
249
|
+
Merb::Plugins.config[:in_file_templates][:javascripts_root] ||
|
250
|
+
Merb.dir_for(:javascripts)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# Find out if template defines a stylesheet, based on template's name.
|
255
|
+
#
|
256
|
+
# ==== Parameters
|
257
|
+
# name<String>:: Template name
|
258
|
+
#
|
259
|
+
# ==== Returns
|
260
|
+
# Boolean:: True if stylesheet, false otherwise
|
261
|
+
#
|
262
|
+
# ==== Examples
|
263
|
+
# # given Merb.dir_for(:stylesheets) #=> '/merb.root/public/stylesheets'
|
264
|
+
# ift_stylesheet?('public/stylesheets/app.css') #=> true
|
265
|
+
# ift_stylesheet?('stylesheets/app.css') #=> true
|
266
|
+
# ift_stylesheet?('index.html.erb') #=> false
|
267
|
+
#_
|
268
|
+
# @semipublic
|
269
|
+
def ift_stylesheet?(name)
|
270
|
+
dir = File.dirname(name).chomp('.')
|
271
|
+
dir.empty? ? false : !!(Merb.dir_for(:stylesheet) =~ /#{dir}$/)
|
272
|
+
end
|
273
|
+
|
274
|
+
# Find out if template defines a javascript, based on template's name.
|
275
|
+
#
|
276
|
+
# ==== Parameters
|
277
|
+
# name<String>:: Template name
|
278
|
+
#
|
279
|
+
# ==== Returns
|
280
|
+
# Boolean:: True if javascript, false otherwise
|
281
|
+
#
|
282
|
+
# ==== Examples
|
283
|
+
# # given Merb.dir_for(:javascript) #=> '/merb.root/public/javascripts'
|
284
|
+
# ift_javascript?('public/javascripts/app.js') #=> true
|
285
|
+
# ift_javascript?('javascripts/app.js') #=> true
|
286
|
+
# ift_javascript?('index.html.erb') #=> false
|
287
|
+
# ift_javascript?('app.js') #=> false
|
288
|
+
#_
|
289
|
+
# @semipublic
|
290
|
+
def ift_javascript?(name)
|
291
|
+
dir = File.dirname(name).chomp('.')
|
292
|
+
dir.empty? ? false : !!(Merb.dir_for(:javascript) =~ /#{dir}$/)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Get path to current controller's template location, relative to template
|
296
|
+
# root (not view root).
|
297
|
+
#
|
298
|
+
# ==== Returns
|
299
|
+
# String:: relative path to template location
|
300
|
+
#_
|
301
|
+
# @semipublic
|
302
|
+
def ift_template_dir
|
303
|
+
File.dirname(
|
304
|
+
self._template_location("im in ur gems, playin' wif ur templetz")
|
305
|
+
)
|
306
|
+
end
|
307
|
+
|
308
|
+
# Parse given data and extract individual templates and their names.
|
309
|
+
#
|
310
|
+
# ==== Parameters
|
311
|
+
# data<String>:: Raw templates data
|
312
|
+
#
|
313
|
+
# ==== Returns
|
314
|
+
# Hash:: Template names (keys) and their raw content (values)
|
315
|
+
#
|
316
|
+
# ==== Examples
|
317
|
+
# @@ template_name
|
318
|
+
# content here
|
319
|
+
#
|
320
|
+
# @@ index.html.erb
|
321
|
+
# the two @ signs must be at the beginning of the line
|
322
|
+
#
|
323
|
+
# @@ template names can even include spaces
|
324
|
+
# pretty unconventional though
|
325
|
+
#_
|
326
|
+
# @semipublic
|
327
|
+
def ift_parse(data)
|
328
|
+
templates, current, ignore = {}, nil, false
|
329
|
+
data.each_line do |line|
|
330
|
+
#(templates[current = $2], ignore = '', $1=='#') and next if line =~ /^(\#)*@@\s*(.*)/
|
331
|
+
#templates[current] << line if current unless ignore
|
332
|
+
if line =~ /^(\#)*@@\s*(.*)/
|
333
|
+
#ignore = ($1 == '#') #skip commented out templates
|
334
|
+
#next if ignore
|
335
|
+
#current = $2
|
336
|
+
#templates[current] = ''
|
337
|
+
ignore = ($1 == '#') and next #skip commented out templates
|
338
|
+
templates[current = $2] = ''
|
339
|
+
elsif ignore
|
340
|
+
next
|
341
|
+
elsif current
|
342
|
+
templates[current] << line
|
343
|
+
end
|
344
|
+
end
|
345
|
+
templates
|
346
|
+
end
|
347
|
+
|
348
|
+
# Rid template directory of all dynamically created files (those created
|
349
|
+
# through #ift_build!).
|
350
|
+
#_
|
351
|
+
# @semipublic
|
352
|
+
def ift_garbage_collect!
|
353
|
+
ift_init_cache
|
354
|
+
if @cache.exists?
|
355
|
+
@cache.files.each do |file|
|
356
|
+
file.chomp!
|
357
|
+
FileUtils.rm(file) if File.exist?(file)
|
358
|
+
end
|
359
|
+
@cache.reset!
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
protected
|
364
|
+
|
365
|
+
# Add custom template root to controller's #_template_roots, based on config
|
366
|
+
# option. If option isn't set, template_roots stay unchanged.
|
367
|
+
#_
|
368
|
+
# @private
|
369
|
+
def ift_set_template_roots!
|
370
|
+
if root = Merb::Plugins.config[:in_file_templates][:view_root]
|
371
|
+
self.class._template_roots.unshift([root, :_template_location])
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# Write template data to a file.
|
376
|
+
#
|
377
|
+
# ==== Parameters
|
378
|
+
# file<String>:: Path name to file in which to store template data.
|
379
|
+
# data<String>:: Template data
|
380
|
+
#_
|
381
|
+
# @private
|
382
|
+
def ift_write_template(file, data)
|
383
|
+
dir = File.dirname(file)
|
384
|
+
FileUtils.mkdir_p(dir) unless File.directory?(dir)
|
385
|
+
open(file, 'w+') {|f| f.write(data) }
|
386
|
+
end
|
387
|
+
|
388
|
+
# Determine whether templates have already been built.
|
389
|
+
#
|
390
|
+
# ==== Returns
|
391
|
+
# Boolean::
|
392
|
+
# True if templates have been built for this controller, false otherwise
|
393
|
+
#_
|
394
|
+
# @private
|
395
|
+
def ift_built?
|
396
|
+
ift_init_cache
|
397
|
+
@cache.exists?
|
398
|
+
end
|
399
|
+
|
400
|
+
# Initialize cache.
|
401
|
+
# Because the cache depends on controller specific information, it has to be
|
402
|
+
# set while execution is in actual controller (as opposed to parent).
|
403
|
+
#_
|
404
|
+
# @private
|
405
|
+
def ift_init_cache
|
406
|
+
#@cache ||= Cache.new(self.controller_name)
|
407
|
+
@cache = Cache.new(self.controller_name)
|
408
|
+
end
|
409
|
+
|
410
|
+
# unused; optional garbage collection not yet implemented.
|
411
|
+
#_
|
412
|
+
# @private
|
413
|
+
def ift_garbage_collect?
|
414
|
+
!!Merb::Plugins.config[:in_file_templates][:garbage_collect]
|
415
|
+
end
|
416
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
namespace :in_file_templates do
|
2
|
+
desc "Remove all generated template files"
|
3
|
+
task :clean do
|
4
|
+
require 'fileutils'
|
5
|
+
YAML::load_file(Merb.dir_for(:config) / 'ift.cache').values.flatten.each do |file|
|
6
|
+
unless File.exist?(file)
|
7
|
+
file_path = file.gsub(Dir.pwd, '')
|
8
|
+
cache_path = (Merb.dir_for(:config) / 'ift.cache').gsub(Dir.pwd,'')
|
9
|
+
msg = "Warning: Potential cache corruption. "
|
10
|
+
msg << "File #{path} is listed in the cache "
|
11
|
+
msg << "(#{cache_path}) but doesn't exist."
|
12
|
+
raise msg
|
13
|
+
else
|
14
|
+
FileUtils.rm(file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/controller3.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# as much as I hate external fixtures, in this case the file #render is called
|
2
|
+
# from matters so this controller must be split off into its own file
|
3
|
+
class Controller3 < Merb::Controller
|
4
|
+
def index; render; end
|
5
|
+
end
|
6
|
+
|
7
|
+
__END__
|
8
|
+
@@ foo
|
9
|
+
fou
|
10
|
+
|
11
|
+
@@ controller3/index.html.erb
|
12
|
+
3rdctrl-index
|
13
|
+
|
14
|
+
@@ controller3/qwerty.xml.haml
|
15
|
+
funky
|
@@ -0,0 +1,336 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
begin
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ruby-debug'
|
5
|
+
rescue
|
6
|
+
#pass
|
7
|
+
end
|
8
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
9
|
+
|
10
|
+
describe "In-file templates" do
|
11
|
+
|
12
|
+
before(:all) do
|
13
|
+
Merb.root = File.dirname(__FILE__) / '..' / 'root'
|
14
|
+
Merb.push_path(:view, Merb.root / 'views', '**/*.rb')
|
15
|
+
Merb.push_path(:config, Merb.root / 'config')
|
16
|
+
Merb.push_path(:public, Merb.root / 'public')
|
17
|
+
Merb.push_path(:stylesheets, Merb.dir_for(:public) / "stylesheets", nil)
|
18
|
+
Merb.push_path(:javascripts, Merb.dir_for(:public) / "javascripts", nil)
|
19
|
+
#-----
|
20
|
+
FileUtils.mkdir(Merb.dir_for(:config)) unless File.exist?(Merb.dir_for(:config))
|
21
|
+
# --------- Fixtures
|
22
|
+
class Controller1 < Merb::Controller
|
23
|
+
provides :html, :xml
|
24
|
+
def index; render; end
|
25
|
+
def show; render_from_file("foo", __FILE__); end
|
26
|
+
end
|
27
|
+
class Controller2 < Merb::Controller
|
28
|
+
provides :html, :xml
|
29
|
+
def index; render; end
|
30
|
+
end
|
31
|
+
require @controller3_file = File.dirname(__FILE__) / 'controller3.rb'
|
32
|
+
# ---------- Views
|
33
|
+
# (see end of file for rest of views)
|
34
|
+
dir = Merb.dir_for(:view) / 'controller1'
|
35
|
+
FileUtils.mkdir_p(dir)
|
36
|
+
open(dir / 'static.html.erb','w+') {|file| file.write("=^.^=\n") }
|
37
|
+
end
|
38
|
+
|
39
|
+
before(:each) do
|
40
|
+
Merb::Config[:reload_templates] = true
|
41
|
+
Merb::Template::METHOD_LIST.clear #reset inline templates cache
|
42
|
+
Controller1._template_roots = nil
|
43
|
+
Controller2._template_roots = nil
|
44
|
+
Controller3._template_roots = nil
|
45
|
+
@controller1 = Controller1.new(fake_request)
|
46
|
+
@controller2 = Controller2.new(fake_request)
|
47
|
+
@controller3 = Controller3.new(fake_request)
|
48
|
+
@controller = @controller1 #synonym
|
49
|
+
clean_tpl_files(@controller1)
|
50
|
+
clean_tpl_files(@controller2)
|
51
|
+
clean_tpl_files(@controller3)
|
52
|
+
end
|
53
|
+
|
54
|
+
after(:all) do
|
55
|
+
clean_tpl_files(@controller1)
|
56
|
+
clean_tpl_files(@controller2)
|
57
|
+
clean_tpl_files(@controller3)
|
58
|
+
#Dir[Merb.root / '*'].each {|e| FileUtils::DryRun.rm_rf(e) }
|
59
|
+
Dir[Merb.root / '*'].each {|e| FileUtils.rm_rf(e) }
|
60
|
+
end
|
61
|
+
|
62
|
+
def clean_tpl_files(controller)
|
63
|
+
controller.send(:ift_garbage_collect!)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should be integrated with render" do
|
67
|
+
@controller.render(:index).strip.should == "1stctrl-index"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should be callable from within a controller action" do
|
71
|
+
@controller._dispatch(:show)
|
72
|
+
@controller.body.strip.should == "bar"
|
73
|
+
@controller._dispatch(:index)
|
74
|
+
@controller.body.strip.should == "1stctrl-index"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should be integrated with display" do
|
78
|
+
obj = Object.new; def obj.to_html; '<b>a</b>'; end
|
79
|
+
@controller.action_name = 'fu'
|
80
|
+
@controller.display(obj).strip.should == '<b>a</b>'
|
81
|
+
@controller.display(obj,:index).strip.should == '1stctrl-index'
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should parse template engine code" do
|
85
|
+
@controller.render(:dynamic).strip.should == "dynamic str"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should reload templates when code reloading is on" do
|
89
|
+
Merb::Config[:reload_templates] = true
|
90
|
+
@controller.render(:index).strip.should == "1stctrl-index"
|
91
|
+
@controller.stub!(:ift_parse).and_return({'controller1/index.html.erb' => 'foobar'})
|
92
|
+
@controller.render(:index).strip.should == 'foobar'
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not reload templates when code reloading is off" do
|
96
|
+
Merb::Config[:reload_templates] = false
|
97
|
+
@controller.render(:index).strip.should == "1stctrl-index"
|
98
|
+
@controller.stub!(:ift_parse).and_return({'controller1/index.html.erb' => 'foobar'})
|
99
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
100
|
+
Merb::Config[:reload_templates] = true
|
101
|
+
@controller.render(:index).strip.should == 'foobar'
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should obey template content types (1)" do
|
105
|
+
@controller.content_type(:xml)
|
106
|
+
@controller.render(:index).strip.should == '<x>ml</x>'
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should obey template content types (2)" do
|
110
|
+
@controller.content_type(:html)
|
111
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should look for templates in file where #render is called" do
|
115
|
+
@controller3._dispatch(:index)
|
116
|
+
@controller3.body.strip.should == "3rdctrl-index"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should not get confused with many controllers in different files" do
|
120
|
+
@controller1._dispatch(:index)
|
121
|
+
@controller1.body.strip.should == "1stctrl-index"
|
122
|
+
@controller3._dispatch(:index)
|
123
|
+
@controller3.body.strip.should == "3rdctrl-index"
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not get confused with many controllers in the same file" do
|
127
|
+
@controller1.render(:index).strip.should == '1stctrl-index'
|
128
|
+
@controller2.render(:index).strip.should == '2ndctrl-index'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should create cache file if it doesn't exist" do
|
132
|
+
path = InFileTemplatesMixin::Cache.path
|
133
|
+
cache = File.exist?(path) ? (YAML::load_file(path) || {}) : {}
|
134
|
+
FileUtils.rm(path) if File.exist?(path)
|
135
|
+
File.file?(path).should be_false
|
136
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
137
|
+
File.file?(path).should be_true
|
138
|
+
YAML::load_file(path).should_not be_false #false when not proper yaml
|
139
|
+
end
|
140
|
+
|
141
|
+
it "should respect changes to config options" do
|
142
|
+
view_root = Merb.root / 'tmp' / 'ift' / 'views'
|
143
|
+
css_root = Merb.dir_for(:stylesheets) / 'ift'
|
144
|
+
js_root = Merb.dir_for(:javascripts) / 'ift'
|
145
|
+
#-----
|
146
|
+
Merb::Plugins.config[:in_file_templates] = {
|
147
|
+
:view_root => view_root,
|
148
|
+
:stylesheets_root => css_root,
|
149
|
+
:javascripts_root => js_root
|
150
|
+
}
|
151
|
+
#-----
|
152
|
+
@controller.render(:index)
|
153
|
+
#-----
|
154
|
+
view = view_root / @controller._template_location('') / 'index.html.erb'
|
155
|
+
css = css_root / 'app.css'
|
156
|
+
js = js_root / 'app.js'
|
157
|
+
#-----
|
158
|
+
File.exist?(view).should be_true
|
159
|
+
File.exist?(css).should be_true
|
160
|
+
File.exist?(js).should be_true
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should respect changes to template location" do
|
164
|
+
def @controller._template_location(context, type=nil, controller=controller_name)
|
165
|
+
"#{controller}.#{action_name}.#{type}"
|
166
|
+
end
|
167
|
+
@controller.stub!(:ift_parse).and_return({'controller1.index.html.erb' => '=0.0='})
|
168
|
+
#-----
|
169
|
+
@controller._dispatch(:index)
|
170
|
+
@controller.body.strip.should == "=0.0="
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should ignore commented out templates" do
|
174
|
+
lambda {
|
175
|
+
@controller.render(:commented_out)
|
176
|
+
}.should raise_error(Merb::ControllerExceptions::TemplateNotFound)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should guess template path prefix when not explicitly specified" do
|
180
|
+
@controller.render(:onlyname).strip.should include('Defaults')
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should render layouts" do
|
184
|
+
@controller.render(:index, :layout => :custom).strip.should == "hd\n1stctrl-index\nft"
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should render stylesheets" do
|
188
|
+
@controller.render(:index)
|
189
|
+
File.exist?(@controller.ift_dir_for(:stylesheets) / 'app.css').should be_true
|
190
|
+
end
|
191
|
+
|
192
|
+
it "should render javascript" do
|
193
|
+
@controller.render(:index)
|
194
|
+
File.exist?(@controller.ift_dir_for(:javascripts) / 'app.js').should be_true
|
195
|
+
end
|
196
|
+
|
197
|
+
describe "#render_from_file" do
|
198
|
+
|
199
|
+
it "should read the template data from the file it is called from" do
|
200
|
+
@controller.render_from_file(:foo).strip.should == "bar"
|
201
|
+
@controller.render_from_file('controller1/index.html.erb').strip.should == "1stctrl-index"
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should read template's data from provided file" do
|
205
|
+
@controller.render_from_file(:foo, @controller3_file).strip.should == "fou"
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should raise an error when it cannot find the template" do
|
209
|
+
lambda {
|
210
|
+
@controller.render_from_file(:baz)
|
211
|
+
}.should raise_error(Merb::ControllerExceptions::TemplateNotFound)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should be able to find templates based on action name" do
|
215
|
+
@controller.action_name = 'foo'
|
216
|
+
@controller.render_from_file.strip.should == "bar"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# For the purposes of this plugin, static templates refer to templates
|
221
|
+
# defined in external files (the regular way), as opposed to those
|
222
|
+
# dynamically generated form in-file templates.
|
223
|
+
describe "cohabiting with static templates" do
|
224
|
+
|
225
|
+
it "should be able to render from both in-file template and static template" do
|
226
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
227
|
+
@controller.render(:static).strip.should == '=^.^='
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should not modify static templates that are already in view directories" do
|
231
|
+
static = (
|
232
|
+
@controller._template_root /
|
233
|
+
@controller._template_location('') /
|
234
|
+
'static.html.erb'
|
235
|
+
)
|
236
|
+
File.file?(static).should be_true
|
237
|
+
file_prev = File.new(static)
|
238
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
239
|
+
File.file?(static).should be_true
|
240
|
+
file_prev.read.should == File.new(static).read
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should not overwrite a static template with an in-file template" do
|
244
|
+
# views/controller1/ contains a file called static.html.erb
|
245
|
+
@controller.stub!(:ift_parse).and_return({'static.html.erb' => '=0.0='})
|
246
|
+
@controller.render(:static).strip.should == '=^.^='
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should give precedence to static templates" do
|
250
|
+
# views/controller1/ contains a file called static.html.erb
|
251
|
+
@controller.stub!(:ift_parse).and_return({'static.html.erb' => '=0.0='})
|
252
|
+
@controller.render(:static).strip.should == '=^.^='
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe "rake tasks" do
|
257
|
+
#setup for rake task specs thanks to
|
258
|
+
#http://blog.nicksieger.com/articles/2007/06/11/test-your-rake-tasks
|
259
|
+
|
260
|
+
before(:all) { require 'rake' }
|
261
|
+
|
262
|
+
before(:each) do
|
263
|
+
@rake = Rake::Application.new
|
264
|
+
Rake.application = @rake
|
265
|
+
load 'lib/merb-in-file-templates/merbtasks.rb'
|
266
|
+
end
|
267
|
+
|
268
|
+
after(:each) do
|
269
|
+
Rake.application = nil
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should garbage collect the dynamic views" do
|
273
|
+
@controller1._dispatch(:index)
|
274
|
+
@controller3._dispatch(:index)
|
275
|
+
File.file?(@controller1.ift_path_for('foo' )).should be_true
|
276
|
+
File.file?(@controller1.ift_path_for('index.xml.erb' )).should be_true
|
277
|
+
File.file?(@controller1.ift_path_for('index.html.erb' )).should be_true
|
278
|
+
File.file?(@controller1.ift_path_for('dynamic.html.erb')).should be_true
|
279
|
+
File.file?(@controller3.ift_path_for('foo' )).should be_true
|
280
|
+
File.file?(@controller3.ift_path_for('index.html.erb' )).should be_true
|
281
|
+
File.file?(@controller3.ift_path_for('qwerty.xml.haml' )).should be_true
|
282
|
+
@rake['in_file_templates:clean'].invoke
|
283
|
+
File.file?(@controller1.ift_path_for('foo' )).should be_false
|
284
|
+
File.file?(@controller1.ift_path_for('index.xml.erb' )).should be_false
|
285
|
+
File.file?(@controller1.ift_path_for('index.html.erb' )).should be_false
|
286
|
+
File.file?(@controller1.ift_path_for('dynamic.html.erb')).should be_false
|
287
|
+
File.file?(@controller3.ift_path_for('foo' )).should be_false
|
288
|
+
File.file?(@controller3.ift_path_for('index.html.erb' )).should be_false
|
289
|
+
File.file?(@controller3.ift_path_for('qwerty.xml.haml' )).should be_false
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should raise warn that cache might be corrupted if a listed file doesn't exist" do
|
293
|
+
@controller.render(:index).strip.should == '1stctrl-index'
|
294
|
+
@controller.instance_variable_get(:@cache).store(@controller.ift_path_for('rogue.php'))
|
295
|
+
lambda {
|
296
|
+
@rake['in_file_templates:clean'].invoke
|
297
|
+
}.should raise_error
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
__END__
|
303
|
+
@@ foo
|
304
|
+
bar
|
305
|
+
|
306
|
+
@@ layout/custom.html.erb
|
307
|
+
hd
|
308
|
+
<%= catch_content(:for_layout).strip %>
|
309
|
+
ft
|
310
|
+
|
311
|
+
@@ controller1/index.html.erb
|
312
|
+
1stctrl-index
|
313
|
+
|
314
|
+
@@ controller2/index.html.erb
|
315
|
+
2ndctrl-index
|
316
|
+
|
317
|
+
@@ controller1/dynamic.html.erb
|
318
|
+
<%= "dynamic str" %>
|
319
|
+
|
320
|
+
@@ controller1/index.xml.erb
|
321
|
+
<x>ml</x>
|
322
|
+
|
323
|
+
#@@ controller1/commented_out
|
324
|
+
should not be parsed
|
325
|
+
|
326
|
+
@@ onlyname.html.erb
|
327
|
+
Defaults to current controller (the one #render is called from) when no path
|
328
|
+
prefix is specified. Useful when there's a single controller in the file, but
|
329
|
+
be careful about creating conflicts when there's multiple controllers and they
|
330
|
+
have templates of the same name
|
331
|
+
|
332
|
+
@@ public/stylesheets/app.css
|
333
|
+
a { color: red; }
|
334
|
+
|
335
|
+
@@ javascripts/app.js
|
336
|
+
var x = 'x'
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$TESTING=true
|
2
|
+
$:.push File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'merb-core'
|
6
|
+
require 'merb-in-file-templates'
|
7
|
+
require 'spec'
|
8
|
+
|
9
|
+
Merb.start :environment => 'test'
|
10
|
+
|
11
|
+
Spec::Runner.configure do |config|
|
12
|
+
config.include Merb::Test::RequestHelper
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mynyml-merb-in-file-templates
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Martin Aumont
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-06-10 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: merb
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.9.4
|
23
|
+
version:
|
24
|
+
description: Merb plugin that allows templates (views, css, js) to be defined in the same file as the controller
|
25
|
+
email: mynyml@gmail.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- LICENSE
|
33
|
+
- TODO
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README
|
37
|
+
- Rakefile
|
38
|
+
- TODO
|
39
|
+
- lib/merb-in-file-templates
|
40
|
+
- lib/merb-in-file-templates/cache.rb
|
41
|
+
- lib/merb-in-file-templates/in_file_templates_mixin.rb
|
42
|
+
- lib/merb-in-file-templates/merbtasks.rb
|
43
|
+
- lib/merb-in-file-templates.rb
|
44
|
+
- spec/merb-in-file-templates_spec.rb
|
45
|
+
- spec/spec.opts
|
46
|
+
- spec/controller3.rb
|
47
|
+
- spec/spec_helper.rb
|
48
|
+
has_rdoc: true
|
49
|
+
homepage: http://github.com/mynyml/
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.0.1
|
71
|
+
signing_key:
|
72
|
+
specification_version: 2
|
73
|
+
summary: Merb plugin that allows templates (views, css, js) to be defined in the same file as the controller
|
74
|
+
test_files: []
|
75
|
+
|