radiant-layouts-extension 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ pkg
data/MIT-LICENSE ADDED
@@ -0,0 +1,27 @@
1
+ http://github.com/moklett/radiant-nested-layouts-extension/
2
+
3
+ The following licence applies to the files:
4
+ lib/nested_layouts.rb
5
+ lib/nested_layouts/tags.rb
6
+
7
+ == MIT License
8
+
9
+ Copyright (c) 2008 Michael O. Klett.
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Layouts
2
+
3
+ Merges share_layouts and nested_layouts, making the whole layout adventure a lot more enjoyable
4
+
5
+ ## Share Layouts
6
+
7
+ ### Introduction
8
+
9
+ Allows Rails controllers/actions to use Radiant layouts as their "layout".
10
+ content_for blocks are mapped to page parts, with the exception of :title and
11
+ :breadcrumbs, which map to their specific default tags. The default content,
12
+ or @content_for_layout, is mapped to the 'body' part.
13
+
14
+ #### Inside a controller Controller
15
+
16
+ SomeController < SiteController
17
+ radiant_layout 'Layout name'
18
+
19
+ # or
20
+
21
+ radiant_layout { |controller| c.action_name == "index" ? "main" : "alt" }
22
+
23
+ # and
24
+
25
+ def delete
26
+ @radiant_layout = 'delete'
27
+ end
28
+
29
+ end
30
+
31
+ radiant_layout takes the same options as the built-in layout. To specifically
32
+ override the Radiant layout and use a standard Rails one use
33
+ :layout => "mine", or :layout => false for no layout, as options to render.
34
+
35
+ To choose a different Radiant layout, set the @radiant_layout instance
36
+ variable to the name of a Radiant layout in your controller or view.
37
+
38
+ ### Acknowledgments
39
+
40
+ * Merged into radiant-layouts-extension, Dirk Kelly, August 2010
41
+ * Updated to work with 0.8 RC1 by: Johannes Fahrenkrug (http://springenwerk.com), May 22, 2009
42
+ * Created by: Sean Cribbs (seancribbs AT gmail DOT com), September 20, 2007
43
+
44
+ * Thanks to John Long for clarifying and simplifying the process for me!
45
+ * Thanks to xtoddx for improving the tests and support for tags that use the request and response.
46
+ * Thanks to Digital Pulp, Inc. for funding the initial development of this extension as part of the Redken.com project.
47
+
48
+ ## Nested Layouts
49
+
50
+ ### Introduction
51
+
52
+ Nested Layouts enables reuse of a top-level "master" layout (one that contains your <html> tags and the overall
53
+ structure/wrapper of your site) for several different "nested" layouts (i.e. a one-column layout and a
54
+ two-column layout). Keep your layouts DRY!
55
+
56
+ A simple example is of the following wrapper and page layout
57
+
58
+ <!-- Application Layout -->
59
+ <!html>
60
+ <body class="<r:layout />">
61
+ <r:content_for_layout />
62
+ </body>
63
+ </html>
64
+
65
+ <!-- Page Layout -->
66
+ <r:inside_layout name='Application'>
67
+ <h1>Hi</h1>
68
+ </r:inside_layout>
69
+
70
+ This would render the following if Page Layout was called
71
+
72
+ <!html>
73
+ <body class="<r:layout />">
74
+ <h1>Hi</h1>
75
+ </body>
76
+ </html>
77
+
78
+ ### Acknowledgments
79
+
80
+ * Merged into radiant-layouts-extension, Dirk Kelly, August 2010
81
+ * Original Source: http://github.com/moklett/radiant-nested-layouts-extension
data/Rakefile ADDED
@@ -0,0 +1,125 @@
1
+ # I think this is the one that should be moved to the extension Rakefile template
2
+
3
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
4
+ # Check to see if the rspec plugin is installed first and require
5
+ # it if it is. If not, use the gem version.
6
+
7
+ # Determine where the RSpec plugin is by loading the boot
8
+ unless defined? RADIANT_ROOT
9
+ ENV["RAILS_ENV"] = "test"
10
+ case
11
+ when ENV["RADIANT_ENV_FILE"]
12
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
13
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
14
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
15
+ else
16
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
17
+ end
18
+ end
19
+
20
+ require 'rake'
21
+ require 'rake/rdoctask'
22
+ require 'rake/testtask'
23
+
24
+ begin
25
+ require 'jeweler'
26
+ Jeweler::Tasks.new do |gem|
27
+ gem.name = "radiant-layouts-extension"
28
+ gem.summary = %Q{Provides extensions to standard layouts, including nesting and sharing}
29
+ gem.description = %Q{Provides extensions to standard layouts, including nesting of layouts within each other and sharing radiant layouts with rails controllers}
30
+ gem.email = "dk@squaretalent.com"
31
+ gem.homepage = "http://github.com/squaretalent/radiant-layouts-extension"
32
+ gem.authors = ["Dirk Kelly"]
33
+ gem.add_development_dependency 'rspec', '>= 1.3.0'
34
+ gem.add_development_dependency 'rspec-rails', '>= 1.3.2'
35
+ gem.add_development_dependency 'cucumber', '>= 0.8.5'
36
+ gem.add_development_dependency 'cucumber-rails', '>= 0.3.2'
37
+ gem.add_development_dependency 'database_cleaner','>= 0.4.3'
38
+ gem.add_development_dependency 'ruby-debug', '>= 0.10.3'
39
+ gem.add_development_dependency 'webrat', '>= 0.10.3'
40
+ end
41
+ Jeweler::GemcutterTasks.new
42
+ rescue LoadError
43
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
44
+ end
45
+
46
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
47
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
48
+ require 'spec/rake/spectask'
49
+ # require 'spec/translator'
50
+
51
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
52
+ Object.send(:remove_const, :RADIANT_ROOT)
53
+
54
+ extension_root = File.expand_path(File.dirname(__FILE__))
55
+
56
+ task :default => :spec
57
+ task :stats => "spec:statsetup"
58
+
59
+ desc "Run all specs in spec directory"
60
+ Spec::Rake::SpecTask.new(:spec) do |t|
61
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
62
+ t.spec_files = FileList['spec/**/*_spec.rb']
63
+ end
64
+
65
+ namespace :spec do
66
+ desc "Run all specs in spec directory with RCov"
67
+ Spec::Rake::SpecTask.new(:rcov) do |t|
68
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
69
+ t.spec_files = FileList['spec/**/*_spec.rb']
70
+ t.rcov = true
71
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
72
+ end
73
+
74
+ desc "Print Specdoc for all specs"
75
+ Spec::Rake::SpecTask.new(:doc) do |t|
76
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
77
+ t.spec_files = FileList['spec/**/*_spec.rb']
78
+ end
79
+
80
+ [:models, :controllers, :views, :helpers].each do |sub|
81
+ desc "Run the specs under spec/#{sub}"
82
+ Spec::Rake::SpecTask.new(sub) do |t|
83
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
84
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
85
+ end
86
+ end
87
+
88
+ # Hopefully no one has written their extensions in pre-0.9 style
89
+ # desc "Translate specs from pre-0.9 to 0.9 style"
90
+ # task :translate do
91
+ # translator = ::Spec::Translator.new
92
+ # dir = RAILS_ROOT + '/spec'
93
+ # translator.translate(dir, dir)
94
+ # end
95
+
96
+ # Setup specs for stats
97
+ task :statsetup do
98
+ require 'code_statistics'
99
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
100
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
101
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
102
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
103
+ ::CodeStatistics::TEST_TYPES << "Model specs"
104
+ ::CodeStatistics::TEST_TYPES << "View specs"
105
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
106
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
107
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
108
+ end
109
+
110
+ namespace :db do
111
+ namespace :fixtures do
112
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
113
+ task :load => :environment do
114
+ require 'active_record/fixtures'
115
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
116
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
117
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ # Load any custom rakefiles for extension
125
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.1
@@ -0,0 +1,39 @@
1
+ class RailsPage < Page
2
+
3
+ display_name "Application"
4
+ attr_accessor :breadcrumbs
5
+
6
+ def find_by_url(url, live=true, clean=true)
7
+ found_page = super
8
+ if found_page.nil? || found_page.is_a?(FileNotFoundPage)
9
+ url = clean_url(url) if clean
10
+ self if url.starts_with?(self.url)
11
+ else
12
+ found_page
13
+ end
14
+ end
15
+
16
+ def url=(path)
17
+ @url = path
18
+ end
19
+
20
+ def url
21
+ @url || super
22
+ end
23
+
24
+ def build_parts_from_hash!(content)
25
+ content.each do |k,v|
26
+ (part(k) || parts.build(:name => k.to_s, :filter_id => "")).content = v
27
+ end
28
+ end
29
+
30
+ alias_method "tag:old_breadcrumbs", "tag:breadcrumbs"
31
+ tag 'breadcrumbs' do |tag|
32
+ if tag.locals.page.is_a?(RailsPage) && tag.locals.page.breadcrumbs
33
+ tag.locals.page.breadcrumbs
34
+ else
35
+ render_tag('old_breadcrumbs', tag)
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1 @@
1
+ = radiant_layout
@@ -0,0 +1,16 @@
1
+ # Uncomment this if you reference any of your controllers in activate
2
+ require_dependency 'application_controller'
3
+
4
+ class LayoutsExtension < Radiant::Extension
5
+ version "0.3.1"
6
+ description "Allows Radiant layouts to be used as layouts for standard Rails actions. Includes http://github.com/moklett/radiant-nested-layouts-extension"
7
+ url "http://github.com/squaretalent/radiant-layouts-extension"
8
+
9
+ def activate
10
+ RailsPage
11
+ ActionController::Base.send :include, ShareLayouts::RadiantLayouts
12
+ ActionView::Base.send :include, ShareLayouts::Helper
13
+ Page.send :include, NestedLayouts::Tags
14
+ end
15
+
16
+ end
@@ -0,0 +1,2 @@
1
+ module NestedLayouts
2
+ end
@@ -0,0 +1,127 @@
1
+ module NestedLayouts
2
+ module Tags
3
+ include Radiant::Taggable
4
+
5
+ class TagError < StandardError; end
6
+
7
+ desc %{
8
+ Renders the contents of the tag inside of a "parent" layout, which is selected via the +name+
9
+ attribute. The contents of this tag are placed at a corresponding <r:content_for_layout/> tag
10
+ within the parent layout. This tag is intended to be used within your layouts, and should
11
+ only appear once per layout.
12
+
13
+ *Usage:*
14
+
15
+ <r:inside_layout name="master">
16
+ <div id="main-column">
17
+ <r:content_for_layout/>
18
+ </div>
19
+ </r:inside_layout>
20
+ }
21
+ tag 'inside_layout' do |tag|
22
+ if name = tag.attr['name']
23
+ # Prepare the stacks
24
+ tag.globals.nested_layouts_content_stack ||= []
25
+ tag.globals.nested_layouts_layout_stack ||= []
26
+
27
+ # Remember the original layout to support the +layout+ tag
28
+ tag.globals.page_original_layout ||= tag.globals.page.layout # Remember the original layout
29
+
30
+ # Find the layout
31
+ name.strip!
32
+ if layout = Layout.find_by_name(name)
33
+ # Track this layout on the stack
34
+ tag.globals.nested_layouts_layout_stack << name
35
+
36
+ # Save contents of inside_layout for later insertion
37
+ tag.globals.nested_layouts_content_stack << tag.expand
38
+
39
+ # Set the page layout that Radiant should use for rendering, which is different than the actual
40
+ # page's layout when layouts are nested. The final/highest +inside_layout+ tag will set or
41
+ # overwrite this value for the last time.
42
+ tag.globals.page.layout = layout
43
+ tag.globals.page.render
44
+ else
45
+ raise TagError.new(%{Error (nested_layouts): Parent layout "#{name.strip}" not found for "inside_layout" tag})
46
+ end
47
+ else
48
+ raise TagError.new(%{Error (nested_layouts): "inside_layout" tag must contain a "name" attribute})
49
+ end
50
+ end
51
+
52
+ desc %{
53
+ Allows nested layouts to target this layout. The contents of <r:inside_layout> tag blocks in another
54
+ layout will have their contents inserted at the location given by this tag (if they target this
55
+ layout). This tag also behaves like a standard <r:content/> tag if this layout is specified directly
56
+ by a page.
57
+
58
+ This tag is intended to be used inside layouts.
59
+
60
+ *Usage:*
61
+
62
+ <html>
63
+ <body>
64
+ <r:content_for_layout/>
65
+ </body>
66
+ </html>
67
+
68
+ }
69
+ tag 'content_for_layout' do |tag|
70
+ tag.globals.nested_layouts_content_stack ||= []
71
+
72
+ # return the saved content if any, or mimic a default +<r:content/>+ tag (render the body part)
73
+ tag.globals.nested_layouts_content_stack.pop || tag.globals.page.render_snippet(tag.locals.page.part('body'))
74
+ end
75
+
76
+ desc %{
77
+ Return the layout name of the current page.
78
+
79
+ *Usage:*
80
+
81
+ <html>
82
+ <body id="<r:layout/>"
83
+ My body tag has an id corresponding to the layout I use. Sweet!
84
+ </body>
85
+ </html>
86
+ }
87
+ tag 'layout' do |tag|
88
+ if layout = tag.globals.page_original_layout
89
+ layout.name
90
+ else
91
+ if layout = tag.globals.page.layout
92
+ layout.name
93
+ else
94
+ ''
95
+ end
96
+ end
97
+ end
98
+
99
+ desc %{ output the contents of tag if layout equals name }
100
+ tag 'if_layout' do |tag|
101
+ if name = tag.attr['name']
102
+ if layout = tag.globals.page_original_layout
103
+ tag.expand if layout.name == name
104
+ elsif layout = tag.globals.page.layout
105
+ tag.expand if layout.name == name
106
+ end
107
+ else
108
+ raise TagError.new(%{Error (nested_layouts): "if_layout" tag must contain a "name" attribute})
109
+ end
110
+ end
111
+
112
+ desc %{ output the contents of tag unless layout equals name }
113
+ tag 'unless_layout' do |tag|
114
+ if name = tag.attr['name']
115
+ if layout = tag.globals.page_original_layout
116
+ tag.expand if layout.name != name
117
+ elsif layout = tag.globals.page.layout
118
+ tag.expand if layout.name != name
119
+ else
120
+ tag.expand
121
+ end
122
+ else
123
+ raise TagError.new(%{Error (nested_layouts): "if_layout" tag must contain a "name" attribute})
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,2 @@
1
+ module ShareLayouts
2
+ end
@@ -0,0 +1,39 @@
1
+ module ShareLayouts::Helper
2
+
3
+ def radiant_layout(name = @radiant_layout)
4
+ page = find_page
5
+ assign_attributes!(page, name)
6
+ page.build_parts_from_hash!(extract_captures)
7
+ page.render
8
+ end
9
+
10
+ def assign_attributes!(page, name = @radiant_layout)
11
+ page.layout = Layout.find_by_name(name) || page.layout
12
+ page.title = @title || @content_for_title || page.title || ''
13
+ page.breadcrumb = @breadcrumb || @content_for_breadcrumb || page.breadcrumb || page.title
14
+ page.breadcrumbs = @breadcrumbs || @content_for_breadcrumbs || nil
15
+ page.url = request.path
16
+ page.slug = page.url.split("/").last
17
+ page.published_at ||= Time.now
18
+ page.request = request
19
+ page.response = response
20
+ end
21
+
22
+ def extract_captures
23
+ variables = instance_variables.grep(/@content_for_/)
24
+ variables.inject({}) do |h, var|
25
+ var =~ /^@content_for_(.*)$/
26
+ key = $1.intern
27
+ key = :body if key == :layout
28
+ unless key == :title || key == :breadcrumbs
29
+ h[key] = instance_variable_get(var)
30
+ end
31
+ h
32
+ end
33
+ end
34
+
35
+ def find_page
36
+ page = Page.find_by_url(request.path) rescue nil
37
+ page.is_a?(RailsPage) ? page : RailsPage.new(:class_name => "RailsPage")
38
+ end
39
+ end