mynyml-merb_simple_views 0.5.0

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.
File without changes
data/LICENSE ADDED
File without changes
data/README ADDED
@@ -0,0 +1,158 @@
1
+ merb_simple_views *ALPHA*
2
+ ==============================
3
+
4
+ WARNING: This plugin is a rewrite of merb-in-file-templates for merb >= 1.0 It
5
+ is very much a work in progress, and is NOT yet stable! Feel free to contribute
6
+ or fork if you are interesting though.
7
+
8
+ UPDATE: Due to the direction the merb project has taken, this plugin's
9
+ development has been put on hold indefinitly.
10
+
11
+
12
+
13
+ A plugin for the Merb framework that allows templates (views) to be defined in
14
+ the same file as the controller (Sinatra style). Especially useful for
15
+ --very-flat apps (making them truly flat), apps that have litle/small view
16
+ code, and for rapid prototyping.
17
+
18
+ ==== Features
19
+ * Seamless integration with #render, #display
20
+ * Respects template reloading
21
+ * Very simple to use
22
+ * Flexible
23
+
24
+ ==== Dependencies
25
+ * Merb > 0.9.4 (?)
26
+ * Rspec to run the specs
27
+
28
+ ==== Examples
29
+ #example for --very-flat app (single file app)
30
+
31
+ #...
32
+ class Application < Merb::Controller; end
33
+ class Products < Application
34
+ def index
35
+ @products = Product.all
36
+ render
37
+ end
38
+ def show
39
+ @product = Product[params[:id]]
40
+ render
41
+ end
42
+ end
43
+
44
+ __END__
45
+ @@ index.html.erb
46
+ <h1>Product List</h1>
47
+ <ul>
48
+ <% for product in @products -%>
49
+ <li><%= product.name %></li>
50
+ <% end -%>
51
+ </ul>
52
+
53
+ @@ show.html.erb
54
+ <h1><%= @product.name %></h1>
55
+
56
+ In-file templates cohabit peacefully with regular external templates. So in the
57
+ above example, show.html.erb could be defined in views/products/show.html.erb
58
+ and both templates will still be picked up normally. In case of a name conflict
59
+ between an in-file and an external template, the external one will take
60
+ precedence and won't be overwritten, keeping it safe from data loss.
61
+
62
+ Template names follow the same rules as regular templates (usually
63
+ action.mime_type.templating_engine).
64
+
65
+ Layouts, stylesheets and javascript can also be placed in in-file templates.
66
+
67
+ #...
68
+
69
+ __END__
70
+ @@ layout/application.css
71
+ #...
72
+
73
+ @@ layout/products.css
74
+ #...
75
+
76
+ @@ stylesheets/application.css
77
+ #...
78
+
79
+ @@ javascripts/jquery.js
80
+ #...
81
+
82
+ ==== Tweaking
83
+ In order to be fed into merb's templating system, in-file templates need to be
84
+ written to external files. This means you will see dynamically created view
85
+ files inside your Merb.dir_for(:view) directory/subdirectories.
86
+
87
+ The directory in which files are stored is chosen based on the templating
88
+ system's native mechanisms, and so merb-in-file-templates will respect any
89
+ changes to it. Therefore if you want to change where template files are stored,
90
+ you can play with Merb.push_path(:view, ...) and the controller's
91
+ #_template_location method.
92
+
93
+ Merb.push_path(:view, Merb.root / 'views')
94
+ class Application
95
+ def _template_location(context, type=nil, controller = controller_name)
96
+ "#{controller}.#{action_name}.#{type}"
97
+ end
98
+ end
99
+
100
+ This will tell Merb to look under the /views directory, for a template named
101
+ products.index.html.erb.
102
+
103
+ want even flatter?
104
+
105
+ Merb.push_path(:view, Merb.root)
106
+ class Application
107
+ def _template_location(context, type=nil, controller=controller_name)
108
+ "view.#{controller}.#{action_name}.#{type}"
109
+ end
110
+ end
111
+
112
+ will give you a template under the root dir called view.products.index.html.erb
113
+ (adding a common prefix, 'view.' in the example above, causes template files to
114
+ show up nicely grouped with ls, file managers, etc, so they look organized even
115
+ without being placed in a subdirectory).
116
+
117
+ If you mix in-file and external templates and you don't want them to be mixed
118
+ in the same directories, you can tell merb-in-file-templates to store its
119
+ templates somewhere else. This is done through the config hash:
120
+
121
+ Merb::Plugins.config[:in_file_templates] = {
122
+ :view_root => '...',
123
+ :stylesheets_root => '...',
124
+ :javascripts_root => '...',
125
+ }
126
+
127
+ For example, you could set
128
+
129
+ :view_root => Merb.root / 'tmp' / 'ift_views'
130
+
131
+ to store your files in merb-root/tmp/ift_views, or
132
+
133
+ :view_root => '/tmp'
134
+
135
+ to store files in your system's tmp directory.
136
+
137
+ Same goes for stylesheets and javascripts, but remember that those need to be
138
+ placed in a public directory, and that they need to be referenced properly from
139
+ within your html header. You can use the controller's
140
+ #ift_dir_for(:stylesheets) and #ift_dir_for(:javascripts) methods to find their
141
+ locations.
142
+
143
+ ==== Rake Task
144
+ TODO
145
+ (cleanup rake task before deployment..)
146
+
147
+ ==== Installation
148
+ TODO
149
+
150
+ ==== Contact
151
+ If you have suggestions, comments, a patch, a git pull request, rants, doc
152
+ fixes/improvements, etc., feel free to contact me: mynyml at gmail,
153
+ irc.freenode.net #rubyonrails, #merb
154
+
155
+ Happy Hacking!
156
+
157
+ -------------------------------------------------------------------------
158
+ Copyright (c) 2008 Martin Aumont (mynyml), released under the MIT license
@@ -0,0 +1,49 @@
1
+ require 'rake/gempackagetask'
2
+ require 'pathname'
3
+ require 'yaml'
4
+
5
+ def gem
6
+ RUBY_1_9 ? 'gem19' : 'gem'
7
+ end
8
+
9
+ def all_except(paths)
10
+ Dir['**/*'] - paths.map {|path| path.strip.gsub(/^\//,'').gsub(/\/$/,'') }
11
+ end
12
+
13
+ spec = Gem::Specification.new do |s|
14
+ s.name = 'merb_simple_views'
15
+ s.version = '0.5.0'
16
+ s.summary = 'Merb plugin that allows defining templates (views, css, js)in the same file as the controller.'
17
+ s.description = 'Merb plugin that allows defining templates (views, css, js)in the same file as the controller.'
18
+ s.author = "Martin Aumont"
19
+ s.email = 'mynyml@gmail.com'
20
+ s.homepage = ''
21
+ s.has_rdoc = true
22
+ s.require_path = "lib"
23
+ s.files = all_except(%w( tmp/* log/* ))
24
+ s.add_dependency 'merb-core >= 1.0'
25
+ end
26
+
27
+ Rake::GemPackageTask.new(spec) do |p|
28
+ p.gem_spec = spec
29
+ end
30
+
31
+
32
+ desc "Remove package products"
33
+ task :clean => :clobber_package
34
+
35
+ desc "Update the gemspec for GitHub's gem server"
36
+ task :gemspec do
37
+ Pathname("#{spec.name}.gemspec").open('w') {|f| f << YAML.dump(spec) }
38
+ end
39
+
40
+ desc "Install gem"
41
+ task :install => [:clobber, :package] do
42
+ sh "#{SUDO} #{gem} install pkg/#{spec.full_name}.gem"
43
+ end
44
+
45
+ desc "Uninstall gem"
46
+ task :uninstall => :clean do
47
+ sh "#{SUDO} #{gem} uninstall -v #{spec.version} -x #{spec.name}"
48
+ end
49
+
data/TODO ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ Autotest.add_discovery { "simpleviews" }
2
+ Autotest.add_discovery { "rspec" }
@@ -0,0 +1,106 @@
1
+ # adaptest from autotest/merb_rspec.rb
2
+ require 'autotest'
3
+
4
+ class RspecCommandError < StandardError; end
5
+
6
+ class Autotest::RspecSimpleviews < Autotest
7
+ def initialize
8
+ super
9
+
10
+ # Ignore any happenings in these directories
11
+ add_exception %r%^\./(?:doc|log|tmp|autotest|bin|\.git|\.autotest)%
12
+
13
+ # Ignore any mappings that Autotest may have already set up
14
+ clear_mappings
15
+
16
+ # run all specs if spec_helper is modified
17
+ add_mapping %r%^spec/spec_helper\.rb% do |_,_|
18
+ all_specs
19
+ end
20
+
21
+ # run all specs if main lib file is modified
22
+ add_mapping %r%^lib/merb_simple_views\.rb% do |_,_|
23
+ all_specs
24
+ end
25
+
26
+ # changing a lib file runs corresponding spec
27
+ add_mapping %r%^lib/merb_simple_views/(.*)\.rb% do |_, m|
28
+ files_matching %r%^spec/.*#{m[1]}_spec\.rb$%
29
+ end
30
+
31
+ # Changing a spec will cause it to run itself
32
+ add_mapping %r%^spec/.*_spec\.rb$% do |filename, _|
33
+ filename
34
+ end
35
+
36
+ end
37
+
38
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39
+
40
+ def failed_results(results)
41
+ results.scan(/^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m)
42
+ end
43
+
44
+ def handle_results(results)
45
+ @failures = failed_results(results)
46
+ @files_to_test = consolidate_failures(@failures)
47
+ @files_to_test.empty? && !$TESTING ? hook(:green) : hook(:red)
48
+ @tainted = !@files_to_test.empty?
49
+ end
50
+
51
+ def consolidate_failures(failed)
52
+ filters = Hash.new { |h,k| h[k] = [] }
53
+ failed.each do |spec, failed_trace|
54
+ if f = test_files_for(failed).find { |f| f =~ /spec\// }
55
+ filters[f] << spec
56
+ break
57
+ end
58
+ end
59
+ filters
60
+ end
61
+
62
+ def make_test_cmd(specs_to_runs)
63
+ [
64
+ ruby,
65
+ "-S",
66
+ spec_command,
67
+ add_options_if_present,
68
+ files_to_test.keys.flatten.join(' ')
69
+ ].join(' ')
70
+ end
71
+
72
+ def add_options_if_present
73
+ File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
74
+ end
75
+
76
+ # Finds the proper spec command to use. Precendence is set in the
77
+ # lazily-evaluated method spec_commands. Alias + Override that in
78
+ # ~/.autotest to provide a different spec command then the default
79
+ # paths provided.
80
+ def spec_command(separator=File::ALT_SEPARATOR)
81
+ unless defined?(@spec_command)
82
+ @spec_command = spec_commands.find { |cmd| File.exists?(cmd) }
83
+
84
+ raise RspecCommandError, "No spec command could be found" unless @spec_command
85
+
86
+ @spec_command.gsub!(File::SEPARATOR, separator) if separator
87
+ end
88
+ @spec_command
89
+ end
90
+
91
+ # Autotest will look for spec commands in the following
92
+ # locations, in this order:
93
+ #
94
+ # * default spec bin/loader installed in Rubygems
95
+ # * any spec command found in PATH
96
+ def spec_commands
97
+ [File.join(Config::CONFIG['bindir'], 'spec'), 'spec']
98
+ end
99
+
100
+ private
101
+
102
+ # Runs +files_matching+ for all specs
103
+ def all_specs
104
+ files_matching %r%^spec/.*_spec\.rb$%
105
+ end
106
+ end
@@ -0,0 +1,33 @@
1
+ if defined?(Merb::Plugins)
2
+ dir = Pathname(__FILE__).dirname / 'merb_simple_views'
3
+
4
+ # Make Merb::RenderMixin's #render and #display methods chainable
5
+ #
6
+ # ==== Notes
7
+ # This is used as a (arguably) more elegant workaround to
8
+ # alias_method_chaining them.
9
+ #
10
+ # "We consider cases of people using alias_method_chain on Merb to be a bug in
11
+ # Merb, and try to find ways to expose enough functionality so it will not be
12
+ # required."
13
+ # -- http://yehudakatz.com/2008/05/22/the-greatest-thing-since-sliced-merb/
14
+ #
15
+ # Ideally those methods would be declared chainable within the RenderMixin
16
+ # itself and this monkey patch wouldn't be needed.
17
+ Merb::RenderMixin.module_eval do
18
+ [:render, :display].each do |name|
19
+ method = instance_method(name)
20
+ self.class.chainable { send(:define_method, name, method) }
21
+ end
22
+ end
23
+
24
+ require dir / 'template_parser'
25
+ require dir / 'mixin'
26
+
27
+ # config options
28
+ Merb::Plugins.config[:simple_views] = {}
29
+
30
+ Merb::BootLoader.after_app_loads do
31
+ Merb::Controller.class_eval { include SimpleViews::Mixin }
32
+ end
33
+ end
@@ -0,0 +1,84 @@
1
+ module SimpleViews
2
+
3
+ TEMPLATES = {}
4
+
5
+ # Adds SimpleViews functionality to a Merb controller, allowing templates
6
+ # defined in the controller's file to serve as views. See README for more.
7
+ module Mixin
8
+ attr_reader :_template_parser
9
+
10
+ def initialize
11
+ @_template_parser = SimpleViews::TemplateParser.new
12
+ super
13
+ end
14
+
15
+ # In addition to default #render behaviour, parse simple views defined in
16
+ # controller's file and render them when requested, or render external
17
+ # templates otherwise.
18
+ #
19
+ # ==== Notes
20
+ # 1. Turned into a chainable method in merb_simple_views.rb
21
+ # 2. Uses a VirtualFile to trick template engines.
22
+ #
23
+ # ==== Parameters
24
+ # See Merb::RenderMixin#render
25
+ #
26
+ # ==== Options
27
+ # See Merb::RenderMixin#render
28
+ #
29
+ # ==== Returns
30
+ # See Merb::RenderMixin#render
31
+ #
32
+ # ==== Raises
33
+ # See Merb::RenderMixin#render
34
+ #
35
+ # ==== Alternatives
36
+ # See Merb::RenderMixin#render
37
+ #
38
+ # :api: public
39
+ def render(*args)
40
+ tpls_file = (@__caller_info__ || __caller_info__).first.first
41
+ self._template_parser.load(tpls_file).parse.each do |template_name, raw_content|
42
+ # no controller name if absolute view path
43
+ ctrl_name = template_name.match(/^\//) ? nil : self.controller_name
44
+ path = Merb.dir_for(:view) / self._template_location(template_name.gsub(/^\//,''), nil, ctrl_name)
45
+ file = VirtualFile.new(raw_content, path)
46
+ TEMPLATES[path.to_s] = file
47
+ end
48
+ super
49
+ end
50
+
51
+ # Wrap #display and store caller info so that #render (called internally by
52
+ # #display) knows what file to fetch template data from.
53
+ #
54
+ # ==== Notes
55
+ # Turned into a chainable method in merb_simple_views.rb
56
+ #
57
+ # ==== Parameters
58
+ # See Merb::RenderMixin#display
59
+ #
60
+ # ==== Options
61
+ # See Merb::RenderMixin#display
62
+ #
63
+ # ==== Returns
64
+ # See Merb::RenderMixin#display
65
+ #
66
+ # ==== Raises
67
+ # See Merb::RenderMixin#display
68
+ #
69
+ # ==== Alternatives
70
+ # See Merb::RenderMixin#display
71
+ #
72
+ # :api: public
73
+ def display(*args)
74
+ @__caller_info__ = __caller_info__
75
+ super
76
+ end
77
+ end
78
+ end
79
+
80
+ module Merb::Template
81
+ def self.load_template_io(path)
82
+ super || template_extensions.map {|ext| SimpleViews::TEMPLATES["#{path}.#{ext}"] }.compact.first
83
+ end
84
+ end
@@ -0,0 +1,93 @@
1
+ module SimpleViews
2
+ class TemplateParser
3
+ # templates as a string, directly extracted from the file.
4
+ attr_accessor :raw_templates
5
+ alias :raw :raw_templates
6
+ alias :raw= :raw_templates=
7
+
8
+ # templates as a {'name' => 'content'} hash
9
+ attr_accessor :parsed_templates
10
+ alias :parsed :raw_templates
11
+ alias :parsed= :raw_templates=
12
+
13
+ def initialize
14
+ self.raw_templates = ''
15
+ self.parsed_templates = {}
16
+ end
17
+
18
+ # Read a file and fetch its __END__ section, if any.
19
+ #
20
+ # ==== Parameters
21
+ # file<String,Pathname>:: File to find in-file templates in
22
+ #
23
+ # ==== Returns
24
+ # self
25
+ #
26
+ # :api: public
27
+ def load(file='')
28
+ file = Pathname(file)
29
+ if file.exist?
30
+ parts = file.read.split(/^__END__$/)
31
+ if parts.size > 1
32
+ self.raw_templates = parts[1].lstrip
33
+ end
34
+ end
35
+ self
36
+ end
37
+
38
+ # Parse templates string and extract template names and contents.
39
+ #
40
+ # Template names must be preceded with '@@', appear alone on their line,
41
+ # and follow the same conventions regular templates do. They can also be
42
+ # disabled by simply commenting out their name.
43
+ #
44
+ # ==== Parameters
45
+ # file<String,Pathname>:: File to find in-file templates in
46
+ #
47
+ # ==== Returns
48
+ # Hash:: Parsed templates as {'name' => 'content'}
49
+ #
50
+ # ==== Examples
51
+ #
52
+ # #posts_controller.rb
53
+ # [...]
54
+ # __END__
55
+ # @@ index.html.erb
56
+ # posts
57
+ #
58
+ # @@ show.html.erb
59
+ # post01
60
+ #
61
+ # #=> {'index.html.erb' => "posts", 'show.html.erb' => "post01"}
62
+ #
63
+ # To disable a template, comment out its name:
64
+ #
65
+ # __END__
66
+ # #@@ index.html.erb
67
+ # posts
68
+ #
69
+ # #=> {}
70
+ #
71
+ # ==== Notes
72
+ # Also stores the result in self.parsed_templates
73
+ #
74
+ # :api: public
75
+ def parse(file='')
76
+ self.load(file) if file
77
+ templates, current, ignore = {}, nil, false
78
+ self.raw_templates.each_line do |line|
79
+ if matches = line.strip.match(/^\s*(\#)*\s*@@\s*(.*)/)
80
+ ignore = (matches[1] && matches[1].match(/^#/)) and next #skip commented out templates
81
+ templates[current = matches[2]] = ''
82
+ elsif ignore
83
+ next
84
+ elsif current
85
+ templates[current] << line
86
+ end
87
+ end
88
+ # remove trailing witespace off every template body and template name
89
+ self.parsed_templates = templates.each {|key,value| templates[key.chomp.gsub(/[[:blank:]]|\t/,'')] = value.rstrip }
90
+ self.parsed_templates
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,160 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Simple Views" do
4
+
5
+ before(:all) do
6
+ Merb.root.should == Pathname(__FILE__).dirname.parent.expand_path.to_s
7
+ views_dir = Pathname(Merb.root / "spec/fixtures/views")
8
+ views_dir.mkdir unless views_dir.directory?
9
+ Merb.push_path(:view, views_dir, "**/*")
10
+ end
11
+
12
+ before(:each) do
13
+ class Posts < Merb::Controller
14
+ def index() render end
15
+ def edit() render end
16
+ def quote() render end
17
+ def nohaz() render end
18
+ def random() render end
19
+ def show
20
+ obj = Object.new; def obj.to_html() '<b>x</b>' end
21
+ display(obj)
22
+ end
23
+ def new
24
+ obj = Object.new; def obj.to_html() '<b>y</b>' end
25
+ display(obj)
26
+ end
27
+ end
28
+ class Topics < Merb::Controller
29
+ def index() render end
30
+ def quote() render end
31
+ end
32
+ # -----
33
+ @posts = Posts.new(fake_request)
34
+ @topics = Topics.new(fake_request)
35
+ # -----
36
+ clean_view_dir!
37
+ end
38
+
39
+ it "should be injected in Merb::Controller" do
40
+ Merb::Controller.included_modules.should include(SimpleViews::Mixin)
41
+ end
42
+
43
+ describe "parsing templates" do
44
+
45
+ it "should parse in-file templates on render" do
46
+ @posts._dispatch(:index)
47
+ @posts._template_parser.parsed_templates['index.html.erb'].should == "kittehs"
48
+ @posts.body.should == "kittehs"
49
+ end
50
+
51
+ it "should parse in-file templates on display" do
52
+ @posts._dispatch(:show)
53
+ @posts._template_parser.parsed_templates['show.html.erb'].should == "kitteh-01"
54
+ @posts.body.should == "kitteh-01"
55
+ end
56
+
57
+ it "should parse absolute paths" do
58
+ @posts._dispatch(:quote)
59
+ @posts._template_parser.parsed_templates['/posts/quote.html.erb'].should == "<i>kitteh-01</i>"
60
+ @posts.body.should == "<i>kitteh-01</i>"
61
+ end
62
+
63
+ it "should let template engines parse views" do
64
+ @posts._dispatch(:random)
65
+ @posts._template_parser.parsed_templates['/posts/random.html.erb'].should == "kitteh-<%= '07' %>"
66
+ @posts.body.should == "kitteh-07"
67
+ end
68
+
69
+ it "should respect changes to #_template_location" do
70
+ def @posts._template_location(context, type=nil, controller=controller_name)
71
+ "#{controller}.#{action_name}.#{type}"
72
+ end
73
+ @posts._dispatch(:index)
74
+ @posts.body.should == "tiny kittehs"
75
+ end
76
+
77
+ describe "with template reloading" do
78
+
79
+ it "should reload templates when code reloading is on" do
80
+ Merb::Config[:reload_templates] = true
81
+ # -----
82
+ @posts._dispatch(:index)
83
+ @posts.body.should == "kittehs"
84
+ # -----
85
+ @posts._template_parser.stub!(:parsed_templates).and_return({'index.html.erb' => 'swapped'})
86
+ # -----
87
+ @posts._dispatch(:index)
88
+ @posts.body.should == "swapped"
89
+ end
90
+
91
+ it "should not reload templates when code reloading is off" do
92
+ Merb::Config[:reload_templates] = false
93
+ # -----
94
+ @posts._dispatch(:index)
95
+ @posts.body.should == "kittehs"
96
+ # -----
97
+ @posts._template_parser.stub!(:parsed_templates).and_return({'index.html.erb' => 'swapped'})
98
+ # -----
99
+ @posts._dispatch(:index)
100
+ @posts.body.should == "kittehs"
101
+ end
102
+ end
103
+
104
+ describe "falling back to default behaviour" do
105
+
106
+ it "should delegate to regular render control flow when no in-file template exists" do
107
+ write_template('edit.html.erb', "<i>ohaie!</i>", @posts)
108
+ @posts._dispatch(:edit)
109
+ @posts.body.should == "<i>ohaie!</i>"
110
+ end
111
+
112
+ it "should delegate to regular display control flow when no in-file template exists" do
113
+ @posts._dispatch(:new)
114
+ @posts.body.should == "<b>y</b>"
115
+ end
116
+
117
+ it "should raise exception when template is not found" do
118
+ lambda {
119
+ @posts._dispatch(:nohaz)
120
+ }.should raise_error(Merb::ControllerExceptions::TemplateNotFound)
121
+ end
122
+ end
123
+
124
+ describe "with multiple controllers" do
125
+
126
+ it "should pick up templates from the same file" do
127
+ @posts._dispatch(:quote)
128
+ @posts.body.should == "<i>kitteh-01</i>"
129
+ @topics._dispatch(:quote)
130
+ @topics.body.should == "<i>ceilingcat</i>"
131
+ end
132
+
133
+ it "should allow different controllers to use the same, relative template" do
134
+ @posts._dispatch(:index)
135
+ @posts.body.should == "kittehs"
136
+ @topics._dispatch(:index)
137
+ @topics.body.should == "kittehs"
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ __END__
144
+ @@ index.html.erb
145
+ kittehs
146
+
147
+ @@ show.html.erb
148
+ kitteh-01
149
+
150
+ @@ /posts/random.html.erb
151
+ kitteh-<%= '07' %>
152
+
153
+ @@ /posts/quote.html.erb
154
+ <i>kitteh-01</i>
155
+
156
+ @@ /topics/quote.html.erb
157
+ <i>ceilingcat</i>
158
+
159
+ @@ /posts.index.html.erb
160
+ tiny kittehs
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,51 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rubygems'
4
+ require 'spec'
5
+ require 'merb-core'
6
+ require 'merb_simple_views'
7
+
8
+ begin
9
+ require 'ruby-debug'
10
+ rescue LoadError, RuntimeError
11
+ # i can haz dibugz plz?
12
+ end
13
+
14
+ Merb.start :environment => 'test', :adapter => 'runner'
15
+
16
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17
+ # Core Extensions
18
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19
+ # This might cause errors to slip into specs, but it beats using fixtures.
20
+ class String
21
+ def unindent
22
+ indent = self.select {|line| !line.strip.empty? }.map {|line| line.index(/[^\s]/) }.compact.min
23
+ self.gsub(/^[[:blank:]]{#{indent}}/, '')
24
+ end
25
+ def unindent!
26
+ self.replace(self.unindent)
27
+ end
28
+ end
29
+
30
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31
+ # Helpers
32
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33
+ module Helpers
34
+ def write_template(name, content, controller)
35
+ view_path = Merb.dir_for(:view) / controller.controller_name / name
36
+ view_path.dirname.mkdir
37
+ Kernel.open(view_path, 'w+') {|file| file.write(content) }
38
+ end
39
+
40
+ def clean_view_dir!
41
+ FileUtils.rm_rf( Pathname.glob(Merb.dir_for(:view) / "*") )
42
+ end
43
+ end
44
+
45
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
+ # Config
47
+ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48
+ Spec::Runner.configure do |config|
49
+ config.include Merb::Test::RequestHelper
50
+ config.include Helpers
51
+ end
@@ -0,0 +1,52 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper')
2
+
3
+ describe "Parser" do
4
+
5
+ before(:each) do
6
+ @parser = SimpleViews::TemplateParser.new.load(__FILE__)
7
+ end
8
+
9
+ it "should load in-file templates" do
10
+ @parser.raw_templates.should match(/ohaie/)
11
+ end
12
+
13
+ describe "when parsing template strings" do
14
+
15
+ it "should split templates at @@ marks" do
16
+ @parser.raw = %|
17
+ @@ index
18
+ kittehs
19
+ @@ show
20
+ kitteh1
21
+ |.unindent
22
+ @parser.parse.size.should == 2
23
+ @parser.parse['index'].strip.should == 'kittehs'
24
+ @parser.parse['show'].strip.should == 'kitteh1'
25
+ end
26
+
27
+ it "should remove trailing witespace off every template" do
28
+ @parser.raw = %|
29
+ @@ index
30
+
31
+ kittehs \t\n
32
+ |.unindent
33
+ @parser.parse['index'].should_not match(/\t\n$/)
34
+ @parser.parse['index'].should match(/^\n/)
35
+ end
36
+
37
+ it "should not be bothered by amount of spaces or tabs between marker and template name" do
38
+ @parser.raw = %|
39
+ @@index
40
+ kittehs
41
+ @@\t\sshow
42
+ kitteh1
43
+ |.unindent
44
+ @parser.parse['index'].should_not be_nil
45
+ @parser.parse['show'].should_not be_nil
46
+ @parser.parse["\t\sshow"].should be_nil
47
+ end
48
+ end
49
+ end
50
+
51
+ __END__
52
+ ohaie
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mynyml-merb_simple_views
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Martin Aumont
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-14 21:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb-core >= 1.0
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Merb plugin that allows defining templates (views, css, js)in the same file as the controller.
26
+ email: mynyml@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files: []
32
+
33
+ files:
34
+ - CHANGELOG
35
+ - log
36
+ - lib
37
+ - lib/merb_simple_views.rb
38
+ - lib/merb_simple_views
39
+ - lib/merb_simple_views/mixin.bk.rb
40
+ - lib/merb_simple_views/cache.rb
41
+ - lib/merb_simple_views/cache.bk.rb
42
+ - lib/merb_simple_views/merbtasks.rb
43
+ - lib/merb_simple_views/merbtasks.bk.rb
44
+ - lib/merb_simple_views/mixin.rb
45
+ - lib/merb_simple_views/template_parser.rb
46
+ - lib/merb_simple_views.bk.rb
47
+ - LICENSE
48
+ - README
49
+ - Rakefile
50
+ - MYTODO
51
+ - draft
52
+ - TODO
53
+ - autotest
54
+ - autotest/rspec_simpleviews.rb
55
+ - autotest/discover.rb
56
+ - autotest/rspec_simpleviews.bk.rb
57
+ - spec
58
+ - spec/spec_helper.rb
59
+ - spec/mixin_spec.bk.rb
60
+ - spec/mixin_spec.rb
61
+ - spec/fixtures
62
+ - spec/fixtures/views
63
+ - spec/fixtures/controller3.rb
64
+ - spec/spec.opts
65
+ - spec/template_parser_spec.rb
66
+ has_rdoc: true
67
+ homepage: ""
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.2.0
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: Merb plugin that allows defining templates (views, css, js)in the same file as the controller.
92
+ test_files: []
93
+