radiant-page_factory-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/EXAMPLES.md +136 -0
  2. data/README.md +59 -0
  3. data/Rakefile +136 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/admin/page_factories_controller.rb +42 -0
  6. data/app/helpers/admin/part_description_helper.rb +9 -0
  7. data/app/views/admin/page_factories/_page_factory.html.haml +4 -0
  8. data/app/views/admin/page_factories/index.haml +0 -0
  9. data/app/views/admin/page_parts/_part_description.html.haml +2 -0
  10. data/app/views/admin/pages/_add_child_column.html.haml +3 -0
  11. data/app/views/admin/pages/_edit_header.html.haml +1 -0
  12. data/app/views/admin/pages/_page_factories.html.haml +4 -0
  13. data/app/views/admin/pages/_page_factory_field.html.haml +1 -0
  14. data/config/locales/en.yml +3 -0
  15. data/config/routes.rb +5 -0
  16. data/db/migrate/20100321222140_add_page_factory.rb +9 -0
  17. data/lib/page_factory.rb +12 -0
  18. data/lib/page_factory/base.rb +81 -0
  19. data/lib/page_factory/manager.rb +120 -0
  20. data/lib/page_factory/page_extensions.rb +25 -0
  21. data/lib/page_factory/page_part_extensions.rb +9 -0
  22. data/lib/page_factory/pages_controller_extensions.rb +32 -0
  23. data/lib/tasks/page_factory_extension_tasks.rake +95 -0
  24. data/page_factory_extension.rb +25 -0
  25. data/public/javascripts/admin/dropdown.js +153 -0
  26. data/public/javascripts/admin/pagefactory.js +30 -0
  27. data/public/stylesheets/admin/page_factory.css +14 -0
  28. data/public/stylesheets/sass/admin/dropdown.sass +32 -0
  29. data/public/stylesheets/sass/modules/_gradient.sass +47 -0
  30. data/public/stylesheets/sass/modules/_rounded.sass +41 -0
  31. data/public/stylesheets/sass/modules/_shadow.sass +9 -0
  32. data/spec/controllers/admin/page_factories_controller_spec.rb +47 -0
  33. data/spec/controllers/admin/pages_controller_spec.rb +63 -0
  34. data/spec/helpers/admin/part_description_helper_spec.rb +42 -0
  35. data/spec/lib/manager_spec.rb +218 -0
  36. data/spec/lib/page_extensions_spec.rb +15 -0
  37. data/spec/models/page_factory_spec.rb +95 -0
  38. data/spec/models/page_spec.rb +27 -0
  39. data/spec/spec.opts +6 -0
  40. data/spec/spec_helper.rb +36 -0
  41. metadata +128 -0
@@ -0,0 +1,136 @@
1
+ # Using PageFactory
2
+
3
+ PageFactory is meant to provide a way of defining content types without altering the page editing experience, or the way pages fundamentally behave. A content type is just a set of parts that you can re-use to create many pages with the same structure.
4
+
5
+ Let's say I'm creating a Radiant site for my company, and I need to create an employee directory. I'll have a lot of pages that represent individual employees, and each page will need the same basic parts: first name, last name, and biography.
6
+
7
+ Rather than add these parts to every employee page, it would be nice if I could simply get a new page with these parts already added. Page Factory lets me define "factories" which will set up my new pages exactly the way I want. I can have multiple factories, and I can make changes to existing factories and ask them to update my existing content.
8
+
9
+ ## Creating new factories
10
+
11
+ The first thing I'll do (after installing PageFactory and running `rake db:migrate:extensions`) is to create a factory for "Employee" pages. I'll create a file called "employee_page_factory.rb" (the `_page_factory` suffix is mandatory.) I can put this in the app/models/ or lib/ directory of any extension, or a lib/ directory at the root of my Radiant project.
12
+
13
+ I need to tell my factory what parts I want:
14
+
15
+ class EmployeePageFactory < PageFactory::Base
16
+ part 'first name'
17
+ part 'last name'
18
+ part 'biography'
19
+ end
20
+
21
+ I visit /admin/pages, and click "Add Child." Hey, there's a popup here asking me what kind of page to add! I select "Employee Page" and I'm taken to a new page. The first name, last name, and biography parts are waiting for me! Neat!
22
+
23
+ But I don't need the default "extended" part on my employees page. Let's get rid of it:
24
+
25
+ class EmployeePageFactory < PageFactory::Base
26
+ part 'first name'
27
+ part 'last name'
28
+ part 'biography'
29
+ remove 'extended'
30
+ end
31
+
32
+ Repeat the steps to add a new page, and the "extended" part is no longer taking up space.
33
+
34
+ ## Additional part options
35
+
36
+ I'll be adding a page for each of my coworkers, but I want them to log in and fill out their own biographies. In the meantime, I want some placeholder text in the biography part, even if it's just dummy text. That should motivate everyone to actually fill it out.
37
+
38
+ I'll edit my page factory to add the dummy text:
39
+
40
+ class EmployeePageFactory < PageFactory::Base
41
+ part 'first name'
42
+ part 'last name'
43
+ part 'biography', :content => "Lorem ipsum dolor sit amet."
44
+ end
45
+
46
+ Now when I add a new Employee page, the biography field will be pre-populated with this dummy text. But I want to make it clear that people should replace this with actual content. (Not all of my coworkers speak Latin.) I can add a little helper text that will be shown on the "biography" part tab, in order to explain what this part is used for:
47
+
48
+ class EmployeePageFactory < PageFactory::Base
49
+ part 'first name'
50
+ part 'last name'
51
+ part 'biography', :content => "Lorem ipsum dolor sit amet.",
52
+ :description => "Please replace this with one or two paragraphs about yourself."
53
+ end
54
+
55
+ The helper text gets displayed right above the text field on the biography tab for all new Employee pages.
56
+
57
+ ## Updating existing content
58
+
59
+ ### Adding parts
60
+
61
+ I spent all day adding employee pages for each of my coworkers... and then my boss tells me that the employee pages should list people's department. I add a 'department' part to my EmployeePageFactory, but this won't affect any employee pages I've already created.
62
+
63
+ Luckily, I won't have to go back through each existing employee page to manually add a department part. I can run the following rake task:
64
+
65
+ $ rake radiant:extensions:page_factory:refresh:soft
66
+
67
+ This iterates over every page created with a factory and adds any parts that are listed in the page's factory but missing from the page. Now all of my existing Employee pages have been updated with an empty "department" part.
68
+
69
+ It's called a "soft" refresh because it adds parts, but it won't change or remove any content. If I had more than one factory and I only wanted to act on Employee pages, I could specify a particular factory:
70
+
71
+ $ rake radiant:extensions:page_factory:refresh:soft[employee]
72
+
73
+ That argument is the name of my factory class minus "page_factory," because this rake task is already long enough.
74
+
75
+ ### Removing parts
76
+
77
+ The boss just changed her mind about displaying everyone's department. This always happens! No problem though, I can just as easily remove the extra part. I just remove it from my factory definition and run this task:
78
+
79
+ $ rake radiant:extensions:page_factory:refresh:hard[employee]
80
+
81
+ Unlike a soft refresh, a hard refresh _will_ alter or remove content. In this case, it goes through all of my Employee pages and removes any parts that aren't listed in the factory definition.
82
+
83
+ ## Other factory options
84
+
85
+ ### Descriptions
86
+
87
+ If you have a lot of factories, it might be helpful to add a description to each so that you remember what they're all used for.
88
+
89
+ class EmployeePageFactory < PageFactory::Base
90
+ description "An employee profile page."
91
+
92
+ part 'first name'
93
+ part 'last name'
94
+ ...
95
+ end
96
+
97
+ This description appears in the factory selection popup.
98
+
99
+ ### Default layouts
100
+
101
+ Our very talented designer has just sent me the markup for the employee page. I'd like to put this in a layout and assign it to all the employee pages -- that way I only have to edit it in one place if there are changes later. I create a new layout called "Employee" and paste in the markup. I can make this the default layout by passing its name to the factory:
102
+
103
+ class EmployeePageFactory < PageFactory::Base
104
+ layout "Employee"
105
+
106
+ part 'first name'
107
+ part 'last name'
108
+ part 'biography', :content => "Lorem ipsum dolor sit amet.",
109
+ :description => "..."
110
+ end
111
+
112
+ Now the Employee layout will be automatically selected whenever I create a new Employee page. If I want to update all of my previously created Employee pages to use this new layout, I can do this by running the hard refresh task.
113
+
114
+ ### Default page classes
115
+
116
+ Sometimes it might be useful to set a default page class, if for instance I have a page factory that deals with Archive pages. That's just as easy:
117
+
118
+ class ArchivePageFactory < PageFactory::Base
119
+ page_class "ArchivePage"
120
+ end
121
+
122
+ Again, I'd have to run the hard refresh task to update any existing pages.
123
+
124
+ ## Working with pages
125
+
126
+ Good news! Because PageFactory made it so easy to create and maintain our site, I was awarded the Lifetime Employee Achievement Award! As part of this, I get to have a photo on my employee page. I'll use this nice one of me in a dapper hat.
127
+
128
+ This will require an extra page part, to hold the URL for my photo. It will also require a slightly different layout, to hold the image tag.
129
+
130
+ Does this mean I need to create a new factory and recreate my own employee page? Nope! PageFactory was built with flexibility in mind, and doesn't prevent you from working with pages in the ways that you're used to.
131
+
132
+ I can just open up my page and add a new 'photo url' part, then change the layout to one that accommodates a photo. The EmployeePageFactory doesn't care what happens to employee pages after they've been created. And if they ever find out I've been filching copy paper and revoke my award, I can just as easily remove that extra part and change the layout back to a normal employee layout.
133
+
134
+ (I do have to be careful about running the hard refresh task, however. That will remove my photo part, because it isn't defined in the factory, and reset my layout to the default employee layout. I can safely run it as long as I specify another factory name.)
135
+
136
+ I can also add a plain old page with no factory and add/delete parts as usual -- I don't have to rely on a factory for everything. This makes it easy to add individual pages whenever I want.
@@ -0,0 +1,59 @@
1
+ # Page Factory
2
+
3
+ An experimental Radiant extension for defining content types/page templates. The intent is to stay light and reuse instead of rebuild.
4
+
5
+ There are three basic questions when dealing with content types in any CMS:
6
+
7
+ + Content Definition: what parts make up a particular kind of page?
8
+ + Templating: what's the markup for each set of parts?
9
+ + Versioning: how do we track and share changes to definitions & templates?
10
+
11
+ Page Factory is meant to address the first point, defining pages. Templating and versioning can be achieved with existing extensions and don't need to be reinvented. I like the combination of Nested Layouts and File System Resources, but the goal is to create an extension that's agnostic on those matters.
12
+
13
+ ## Goals
14
+
15
+ I'm using the word "Factory" very deliberately. A traditional "content type" is a model that's attached to a page for the page's entire lifespan. To some extent, the content type dictates what you can and cannot do with that page.
16
+
17
+ This is a different approach. I want a _factory_ that only cares about setting up new pages, and doesn't make any page modifications until I tell it to. I want to retain all of the flexibility that comes with Radiant.
18
+
19
+ I want the following behaviors in my solution:
20
+
21
+ ### Flexibility
22
+
23
+ I want my factories to set up pages for me and then stay out of my way. Using factories shouldn't prevent me from creating a Plain Old Page with my own choice of parts; nor should they prevent me from modifying pages after they're created.
24
+
25
+ ### Simplicity
26
+
27
+ Page factories shouldn't fundamentally alter the way Pages work. I don't want to overload the `:body` part for use as a layout container. Nor do I want to use a web interface to manipulate content types. A Page factory should be a regular Ruby class; I should be able to inherit or extend it.
28
+
29
+ ### Modularity
30
+
31
+ I want my factories to respect the division between presentation and behavior. Factories can _suggest_ a Page class, but shouldn't prevent you from changing that class on new or existing records. I'd like to take a similar approach to layouts -- flexibility is a requirement, not an enhancement.
32
+
33
+ ## Some use cases
34
+
35
+ In addition to the core task of defining content types, there are some specific cases I want Page Factory to address:
36
+
37
+ ### Generic pages
38
+
39
+ I want to add a one-off page somewhere. In the past, generic pages have been catch-all content types with enough parts to fit any use case. They're ugly and hard to use.
40
+
41
+ I should be able to add a Plain Old Page without setting up a content type first. I should be able to add only those parts I need. I should be able to use the `:body` part to hold that page's unique markup, just like normal Radiant usage.
42
+
43
+ ### Edge cases
44
+
45
+ There's a page that needs to look or behave just a little differently from others of its kind. Instead of making its content type pull double duty, or creating a content type to handle a single page, I should be able to switch this page to a different layout. Or use a different page class. Or add a single page part to it.
46
+
47
+ Page factories shouldn't have an opinion about any of those attributes until you tell it to take action on a page or set of pages.
48
+
49
+ ## Usage
50
+
51
+ See EXAMPLES.md for a detailed walkthrough.
52
+
53
+ ## Notes on implementation
54
+
55
+ + **Syncing.** Because I'm not exposing these factories in the admin UI, there's no need to do this in real-time. Unless explicitly asked, the methods responsible for altering existing content ignore Plain Old Pages so that you have at least one type of Page that's always open to modification and not in any danger of being overwritten.
56
+
57
+ + **Changing factories.** I decided not to implement a way to change a page's factory after creation. This is mostly because I felt adding a new element to the page edit interface wasn't in line with PageFactory's stated goal of changing as little as possible about page behavior. It was confusing to have both a 'Page Type' select and a factory/template/whatever select side-by-side.
58
+
59
+ Additionally, I haven't worked out how changing a page's factory should work. Do the parts get reassigned on the fly? What happens if the pages share some parts?
@@ -0,0 +1,136 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "radiant-page_factory-extension"
5
+ gem.summary = %Q{Page Factory Extension for Radiant CMS}
6
+ gem.description = %Q{Page Factory is a small DSL for intelligently defining content types in Radiant CMS.}
7
+ gem.email = "josh@vitamin-j.com"
8
+ gem.homepage = "http://github.com/joshfrench/radiant-page_factory-extension"
9
+ gem.authors = ["Josh French"]
10
+ gem.add_dependency 'radiant', '~> 0.9.0'
11
+ end
12
+ rescue LoadError
13
+ puts "Jeweler (or a dependency) not available. This is only required if you plan to package page-factory as a gem."
14
+ end
15
+
16
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
17
+ # Check to see if the rspec plugin is installed first and require
18
+ # it if it is. If not, use the gem version.
19
+
20
+ # Determine where the RSpec plugin is by loading the boot
21
+ unless defined? RADIANT_ROOT
22
+ ENV["RAILS_ENV"] = "test"
23
+ case
24
+ when ENV["RADIANT_ENV_FILE"]
25
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
26
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
27
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
28
+ else
29
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
30
+ end
31
+ end
32
+
33
+ require 'rake'
34
+ require 'rake/rdoctask'
35
+ require 'rake/testtask'
36
+
37
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
38
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
39
+ require 'spec/rake/spectask'
40
+ require 'cucumber'
41
+ require 'cucumber/rake/task'
42
+
43
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
44
+ Object.send(:remove_const, :RADIANT_ROOT)
45
+
46
+ extension_root = File.expand_path(File.dirname(__FILE__))
47
+
48
+ task :default => :spec
49
+ task :stats => "spec:statsetup"
50
+
51
+ desc "Run all specs in spec directory"
52
+ Spec::Rake::SpecTask.new(:spec) do |t|
53
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
54
+ t.spec_files = FileList['spec/**/*_spec.rb']
55
+ end
56
+
57
+ task :features => 'spec:integration'
58
+
59
+ namespace :spec do
60
+ desc "Run all specs in spec directory with RCov"
61
+ Spec::Rake::SpecTask.new(:rcov) do |t|
62
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
63
+ t.spec_files = FileList['spec/**/*_spec.rb']
64
+ t.rcov = true
65
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
66
+ end
67
+
68
+ desc "Print Specdoc for all specs"
69
+ Spec::Rake::SpecTask.new(:doc) do |t|
70
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
71
+ t.spec_files = FileList['spec/**/*_spec.rb']
72
+ end
73
+
74
+ [:models, :controllers, :views, :helpers].each do |sub|
75
+ desc "Run the specs under spec/#{sub}"
76
+ Spec::Rake::SpecTask.new(sub) do |t|
77
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
78
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
79
+ end
80
+ end
81
+
82
+ desc "Run the Cucumber features"
83
+ Cucumber::Rake::Task.new(:integration) do |t|
84
+ t.fork = true
85
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
86
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
87
+ t.profile = "default"
88
+ end
89
+
90
+ # Setup specs for stats
91
+ task :statsetup do
92
+ require 'code_statistics'
93
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
94
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
95
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
96
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
97
+ ::CodeStatistics::TEST_TYPES << "Model specs"
98
+ ::CodeStatistics::TEST_TYPES << "View specs"
99
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
100
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
101
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
102
+ end
103
+
104
+ namespace :db do
105
+ namespace :fixtures do
106
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
107
+ task :load => :environment do
108
+ require 'active_record/fixtures'
109
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
110
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
111
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
117
+
118
+ desc 'Generate documentation for the page_factory extension.'
119
+ Rake::RDocTask.new(:rdoc) do |rdoc|
120
+ rdoc.rdoc_dir = 'rdoc'
121
+ rdoc.title = 'PageFactoryExtension'
122
+ rdoc.options << '--line-numbers' << '--inline-source'
123
+ rdoc.rdoc_files.include('README')
124
+ rdoc.rdoc_files.include('lib/**/*.rb')
125
+ end
126
+
127
+ # For extensions that are in transition
128
+ desc 'Test the page_factory extension.'
129
+ Rake::TestTask.new(:test) do |t|
130
+ t.libs << 'lib'
131
+ t.pattern = 'test/**/*_test.rb'
132
+ t.verbose = true
133
+ end
134
+
135
+ # Load any custom rakefiles for extension
136
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,42 @@
1
+ class Admin::PageFactoriesController < ApplicationController
2
+ helper_method :factory_link
3
+
4
+ def index
5
+ @page = Page.find_by_id(params[:page])
6
+ @factories = factories
7
+
8
+ respond_to do |format|
9
+ format.html { render :partial => '/admin/page_factories/page_factory', :collection => @factories }
10
+ format.js { render :partial => '/admin/page_factories/page_factory', :collection => @factories }
11
+ format.json { render :json => @factories.to_json() }
12
+ format.xml { render :json => @factories.to_xml() }
13
+ end
14
+ end
15
+
16
+ private
17
+ ##
18
+ # If you need to limit what factories can be selected, alias chain this
19
+ # method. The current user and @page (the page you're adding a child to)
20
+ # are available here, so you can filter according to @page.class_name,
21
+ # @page.page_factory, current_user roles, etc.
22
+ #
23
+ # @return [Array] an array of factory classes which you may then modify
24
+ #
25
+ # @example Don't let designers add Archive pages
26
+ # def factories_with_permissions
27
+ # if current_user.admin?
28
+ # factories_without_permissions
29
+ # else
30
+ # factories_without_permissions.reject { |f| f.page_class == 'ArchivePage' }
31
+ # end
32
+ # end
33
+ # alias_method_chain :factories, :permissions
34
+ def factories
35
+ [PageFactory::Base, *PageFactory::Base.descendants.sort { |a,b| a.name <=> b.name }]
36
+ end
37
+
38
+ def factory_link(factory=PageFactory::Base)
39
+ args = { :factory => factory < PageFactory::Base ? factory : nil }
40
+ @page.nil? ? new_admin_page_path(args) : new_admin_page_child_path(@page, args)
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ module Admin::PartDescriptionHelper
2
+ def description_for(part)
3
+ return nil if @page.nil? or @page.page_factory.blank?
4
+ @page.page_factory.parts.detect do |f|
5
+ f.name.downcase == part.name.downcase and
6
+ f.class == part.class
7
+ end.try :description
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ - if page_factory_counter == 1
2
+ %li{:class => 'separator'}
3
+ %li
4
+ = link_to page_factory.template_name, factory_link(page_factory), :title => page_factory.description
@@ -0,0 +1,2 @@
1
+ %span.part_description
2
+ = description_for(page_part)
@@ -0,0 +1,3 @@
1
+ - unless simple
2
+ %td.add_child
3
+ = link_to t('add_child'), admin_factory_link_path(:page => page), :class => 'dropdown'
@@ -0,0 +1 @@
1
+ %h1== #{controller.template_name.capitalize} #{(@page.page_factory || PageFactory::Base).template_name}
@@ -0,0 +1,4 @@
1
+ - unless @pages.blank?
2
+ %ul.menu{:id => "add_child_dropdown"}
3
+ %li
4
+ %a= link_to PageFactory::Base.template_name, new_admin_page_path, :title => PageFactory::Base.description
@@ -0,0 +1 @@
1
+ = hidden_field_tag 'page[page_factory]', @page.try(:page_factory) || params[:factory]
@@ -0,0 +1,3 @@
1
+ ---
2
+ en:
3
+ page factory: Page Factory
@@ -0,0 +1,5 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.namespace :admin do |admin|
3
+ admin.factory_link '/pages/factories', :controller => 'page_factories', :action => 'index'
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ class AddPageFactory < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :pages, :page_factory, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :pages, :page_factory
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ module PageFactory
2
+ def self.current_factory
3
+ @current_factory ||= PageFactory::Base
4
+ end
5
+
6
+ def self.current_factory=(factory)
7
+ factory = factory.constantize if factory.is_a?(String)
8
+ if factory.nil? or factory <= PageFactory::Base
9
+ @current_factory = factory
10
+ end
11
+ end
12
+ end