renderit 0.1.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.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andrey Romanov
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.rdoc ADDED
@@ -0,0 +1,25 @@
1
+ == RenderIt
2
+
3
+ Main purpose of this gem was to make easier development of websites using html5/css3.
4
+ The problem that we have at the moment is that old browsers and ALL stable Internet Explorers don't support html5/css3, but we have to support all the main browsers.
5
+ To be able to use rounded corners, gradients, css-transformations, application cache and so on we can support two versions of website - one for old browsers and one for new.
6
+ Browser name and browser version will be defined from user_agent that is sent by all the modern browsers.
7
+ User expirience in new browser can be much better comparing to the versions of web applications written to work same under all browsers (including old once).
8
+
9
+ To use this gem you can just install this gem, require it in your rails application and create configuration file conf/renderit.yml
10
+ In this file you can define regular expressions to define browser name and version (if defaults are not enough). By default renderit supports InternetExplorer, Opera, Firefox, Chrome, Safari, SafariMobile.
11
+ Also you can define templates that will be rendered for specific browsers. This templates will be used for rendering views as well as layouts.
12
+ Here is an example of renderit.yml config file:
13
+
14
+ templates:
15
+ new: chrome>=4, firefox>=3.5, opera>=10.5
16
+
17
+ If Chrome>=4 version, Firefox >= 3.5 version or Opera >= 10.5 version browser is used to get page of your rails application, rails will try to render page with '_new' postfix. For example, not 'sample_view' view,
18
+ but 'sample_view_new' view (if it is present). If not - default 'sample_view' view will be rendered. Same thing with layouts. If you have 'application_new' layout - it will be rendered. If not 'application' layout
19
+ will be used.
20
+
21
+ In order to use those tempates, default view or layout have to be present. You will not be able to render 'application_new' layout in case you have no 'application' layout.
22
+
23
+ Have fun :)
24
+
25
+ Copyright (c) 2010 Andrey Romanov. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "renderit"
8
+ gem.summary = %Q{Renders different templates depending on browser user_agent.}
9
+ gem.description = %Q{Renders different templates depending on browser user_agent.}
10
+ gem.email = "judo.ras@gmail.com"
11
+ gem.homepage = "http://github.com/romanoff/renderit"
12
+ gem.authors = ["Andrey Romanov"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "renderit #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/renderit.rb ADDED
@@ -0,0 +1,126 @@
1
+ class ActionController::Base
2
+ private
3
+
4
+ # default_render method for ActionController::Base is redefined
5
+ # in order to render views for specific browsers (depending on user_agent)
6
+ def default_render
7
+ @renderit_template ||= RenderIt.get_template_name(request)
8
+ template_path = default_template_name + '_' + @renderit_template
9
+ if view_paths.find_template(template_path, default_template_format)
10
+ render template_path
11
+ end
12
+ rescue ActionView::MissingTemplate => e
13
+ render default_template_name
14
+ end
15
+
16
+ # default_layout method for ActionController::Base is redefined
17
+ # in order to render layouts for specific browsers (depending on user_agent)
18
+ def default_layout
19
+ @renderit_template = RenderIt.get_template_name(request)
20
+ layout = self.class.read_inheritable_attribute(:layout)
21
+ return layout unless self.class.read_inheritable_attribute(:auto_layout)
22
+ begin
23
+ rendered_layout = find_layout(layout+ '_' + @renderit_template, default_template_format)
24
+ rescue ActionView::MissingTemplate
25
+ end
26
+ return rendered_layout if rendered_layout
27
+ find_layout(layout, default_template_format)
28
+ rescue ActionView::MissingTemplate
29
+ nil
30
+ end
31
+
32
+ end
33
+
34
+ class RenderIt
35
+ # Default regular expressions to define browser and its version
36
+ DEFAULT_BROWSERS_CONFIG = {
37
+ 'ie' => 'msie (\d+\.\d).*\)(?!\s*opera)',
38
+ 'firefox' => 'gecko.*?firefox\/(\d+\.\d)',
39
+ 'chrome' => 'applewebkit.*?chrome\/(\d+\.\d)',
40
+ 'safari' => 'applewebkit.*?version\/(\d+.\d)\.\d(?!\s*mobile).*?safari',
41
+ 'safarimobile' => 'applewebkit.*?version\/(\d+.\d)\.\d\smobile.*?safari',
42
+ 'opera' => 'opera.*?version\/(\d+\.\d)'
43
+ }
44
+ VERSION_MATCH_REGEXP = Regexp.new("([a-z]+)(.*)", "i")
45
+ NON_EXPRESSION_REGEXP = Regexp.new("^[^><=]")
46
+
47
+ Browser = Struct.new(:name, :version)
48
+
49
+ # Returns template name depending on request.
50
+ # Template name depends on configuration defined in conf/renderit.yml
51
+ # For example, if renderit.yml will contain following:
52
+ #
53
+ # templates:
54
+ # new: chrome>5, firefox>3.5, opera>10.5
55
+ #
56
+ # And request will be made from Chrome6.0 then if 'new' string should be returned.
57
+ def self.get_template_name(request)
58
+ user_agent = request.env["HTTP_USER_AGENT"]
59
+ browser = self.get_browser(user_agent)
60
+ return self.template_name(browser)
61
+ end
62
+
63
+
64
+ # Returns browser name and its version
65
+ def self.get_browser(user_agent)
66
+ browsers_config = read_inheritable_attribute(:browsers_config)
67
+ browsers_config.keys.each do |browser_name|
68
+ if version = browsers_config[browser_name].match(user_agent)
69
+ return Browser.new(browser_name, version[1])
70
+ end
71
+ end
72
+ end
73
+
74
+
75
+ # Returns template name based on browser and configuration
76
+ def self.template_name(browser)
77
+ templates_config = read_inheritable_attribute(:templates_config)
78
+ return '' unless templates_config
79
+ if (browser)
80
+ templates_config.keys.each do |name|
81
+ if comparator = templates_config[name][browser.name]
82
+ return name if eval(browser.version+comparator)
83
+ end
84
+ end
85
+ end
86
+ return ''
87
+ end
88
+
89
+ # Loads initial configuration from config/renderit.yml file
90
+ # This is made once on rails application start
91
+ def self.load_config
92
+ if File.exist?(File.join(Rails.root, 'config/renderit.yml'))
93
+ renderit_config = YAML::load_file(File.join(Rails.root, 'config/renderit.yml'))
94
+
95
+ #Loading browsers config
96
+ browsers_config = renderit_config['browsers']||{}
97
+ browsers_config.merge!(DEFAULT_BROWSERS_CONFIG)
98
+ #Turning strings into RegExp
99
+ browsers_config.keys.each do |browser|
100
+ browsers_config[browser] = Regexp.new(browsers_config[browser], 'i')
101
+ end
102
+ write_inheritable_attribute(:browsers_config, browsers_config)
103
+
104
+ #Loading templates config
105
+ templates_config = renderit_config['templates']
106
+ templates_config.keys.each do |template_name|
107
+ matching_browser_versions = templates_config[template_name]
108
+ templates_config[template_name] = {}
109
+ matching_browser_versions.split(',').each do |value|
110
+ match = VERSION_MATCH_REGEXP.match(value)
111
+ if (browser = match[1]) && (expression = match[2])
112
+ expression = expression.strip
113
+ expression = '=='+expression if NON_EXPRESSION_REGEXP.match(expression)
114
+ templates_config[template_name][browser.strip.downcase] = expression
115
+ end
116
+ end
117
+ end
118
+
119
+ write_inheritable_attribute(:templates_config, templates_config)
120
+ end
121
+
122
+ end
123
+
124
+ end
125
+
126
+ RenderIt.load_config
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'renderit'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,4 @@
1
+ require 'helper'
2
+
3
+ class TestRenderit < Test::Unit::TestCase
4
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: renderit
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Andrey Romanov
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-05 00:00:00 +03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thoughtbot-shoulda
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ description: Renders different templates depending on browser user_agent.
36
+ email: judo.ras@gmail.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - .document
46
+ - .gitignore
47
+ - LICENSE
48
+ - README.rdoc
49
+ - Rakefile
50
+ - VERSION
51
+ - lib/renderit.rb
52
+ - test/helper.rb
53
+ - test/test_renderit.rb
54
+ has_rdoc: true
55
+ homepage: http://github.com/romanoff/renderit
56
+ licenses: []
57
+
58
+ post_install_message:
59
+ rdoc_options:
60
+ - --charset=UTF-8
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 0
80
+ version: "0"
81
+ requirements: []
82
+
83
+ rubyforge_project:
84
+ rubygems_version: 1.3.7
85
+ signing_key:
86
+ specification_version: 3
87
+ summary: Renders different templates depending on browser user_agent.
88
+ test_files:
89
+ - test/helper.rb
90
+ - test/test_renderit.rb