ginsu 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
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.
@@ -0,0 +1,88 @@
1
+ h1. Ginsu
2
+
3
+ Rails applications are not always born as Rails applications. Sometimes graphic designers create web designs using tools like Dreamweaver and then pass them off to software developers for implementation as web applications
4
+
5
+ But Rails has a different model for a web site than a tool like BBEdit. Rails thinks in terms of routes that lead to actions that render from templates that can use layouts, but Rapidweaver thinks in terms of pages. Every page includes the whole layout.
6
+
7
+ Ginsu manages the transition of a web project, from a static web site to the final implementation as a Rails application. Ginsu creates hybrid web sites with some sections served as static content and some sections powered by dynamic Rails actions.
8
+
9
+ h2. The Problem
10
+
11
+ You work in a high-volume web shop. Your job is the nerd stuff: programming the dynamic parts of web projects and dealing with site implementation and hosting. A producer gives you a .zip file and tells you that the deadline to get the site hosted is that afternoon. The .zip file contains static .html, .css, image and Flash files from a Dreamweaver project that a graphic designer developed. Then, the punchline: "Only pages X and Y need to be dynamic, leave the rest static. We're still designing it. Oh and we'll be updating this part of page X and this part of page Y once a week."
12
+
13
+ You don't want to work with a graphic designer every week to update your .erb or .haml files because that makes updates very expensive, which is not very agile. You don't want to configure your web server to serve only a few routes from your Rails app because making changes is hard and so that's also not very agile. You can't implement a CMS back-end for making it all irrelevant because you work in a high-volume shop and you only have an hour.
14
+
15
+ You need a way to bring your graphic designer into the agile process, so that you and the designer can both make updates to your respective areas of the project.
16
+
17
+ h2. The Solution
18
+
19
+ <pre><code>cd yourapp
20
+ mkdir static</code></pre>
21
+
22
+ Copy your static web site from your graphic designer into your Rails application's new "static" directory. If your static web site has a root index file called "index.html", then your Rails app should have a file called "static/index.html".
23
+
24
+ Configure Ginsu to slice sections of pages from the static web site into partial templates in your Rails application by adding slicing instructions to your config/initializers/ginsu.rb:
25
+
26
+ <pre><code># Create a 'header' partial by plucking header HTML from static/index.html using a CSS selector.
27
+ ginsu.partials << { :css => 'h3.r a.l', :static => 'index.html', :partial => 'header' }
28
+
29
+ # Create a 'header' partial by plucking header HTML from static/index.html using an xpath selector.
30
+ ginsu.partials << { partial :xpath => '//h3/a[@class="l"]', :static => 'index.html', :partial => 'header' }
31
+
32
+ # Just use the 'search' parameter to use either CSS or xpath.
33
+ ginsu.partials << { :search => 'h3.r a.l', :static => 'index.html', :partial => 'header' }
34
+ ginsu.partials << { :search => '//h3/a[@class="m"]', :static => 'index.html', :partial => 'header' }
35
+
36
+ # Create symbolic links in the public/ directory of the Rails app for selected sections and files.
37
+ ginsu.links << { :static => 'galleries' }
38
+ ginsu.links << { :static => 'events' }
39
+ ginsu.links << { :static => 'holdout.html' }
40
+ </pre></code>
41
+
42
+ Now when you run:
43
+
44
+ <pre><code>rake ginsu:slice</code></pre>
45
+
46
+ ...Ginsu will find the header in your static/index.html file and create a partial in app/views/_header.html.erb with the contents of the HTML element that it locates using your CSS or xpath selector.
47
+
48
+ Using this technique does not require your graphic designer to make any changes to the Dreamweaver project. You don't have to tag the section that you want to slice out, you simply describe where it's located and Ginsu will find it and slice it out. You bring your graphic designers into the agile process by enabling them to update parts of the web site with their tools, without learning Rails.
49
+
50
+ h2. Installation
51
+
52
+ Install the Ginsu gem in your Rails application with:
53
+
54
+ <pre><code>script/plugin install git://github.com/endymion/ginsu.git</code></pre>
55
+
56
+ Generate your initializer, for configuring Ginsu:
57
+
58
+ <pre><code>script/generate ginsu</code></pre>
59
+
60
+ h2. Configure
61
+
62
+ The Ginsu configuration is in the initializer file config/initializers/ginsu.rb:
63
+
64
+ <pre><code>require 'ginsu'
65
+ Ginsu::Knife.configure do |ginsu|
66
+
67
+ # The default location of the static web site is 'site', but maybe your static
68
+ # site includes 150 MB worth of Photoshop .psd files and you don't want those
69
+ # in your Capistrano deployments. Change the source path here if you want.
70
+ ginsu.source = '/home/webproject/site'
71
+
72
+ ginsu.partials << { :search => '#header', :static => 'index.html', :partial => 'header' }
73
+ ginsu.partials << { :search => '#footer', :static => 'index.html', :partial => 'footer' }
74
+
75
+ ginsu.links << { :static => 'galleries' }
76
+ ginsu.links << { :static => 'news' }
77
+
78
+ end</code></pre>
79
+
80
+ h2. Features
81
+
82
+ h3. partial
83
+
84
+ A partial is the content of an HTML element that Ginsu will partial out of a static HTML document and drop into a Rails partial template.
85
+
86
+ h3. link
87
+
88
+ A link is a page or a folder that you want to be entirely served as static content. Ginsu will create symbolic links in your Rails application's public/ directory for each link.
@@ -0,0 +1,40 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the ginsu plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the ginsu plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Ginsu'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+
25
+ begin
26
+ require 'jeweler'
27
+ Jeweler::Tasks.new do |gemspec|
28
+ gemspec.name = 'ginsu'
29
+ gemspec.summary = 'A Ruby on Rails plugin for carving partials out of static web sites.'
30
+ gemspec.email = 'rap@endymion.com'
31
+ # gemspec.homepage = "http://github.com/technicalpickles/the-perfect-gem"
32
+ gemspec.description = <<-EOF
33
+ Ginsu is a Ruby on Rails plugin for carving partials out of static web sites, for including
34
+ graphic designers in the agile process for developing a web project.
35
+ EOF
36
+ gemspec.authors = ["Ryan Porter"]
37
+ end
38
+ rescue LoadError
39
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
40
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates the Ginsu initializer in config/intitializers/ginsu.rb
3
+
4
+ Example:
5
+ ./script/generate ginsu
6
+
7
+ This will create:
8
+ config/initializers/ginsu.rb
@@ -0,0 +1,7 @@
1
+ class GinsuGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.template 'config/initializers/ginsu.rb', 'config/initializers/ginsu.rb'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,17 @@
1
+ require 'ginsu'
2
+ Ginsu::Knife.configure do |ginsu|
3
+
4
+ # The default location of the static web site is the 'static' folder in your Rails app,
5
+ # but maybe your static site includes 150 MB worth of Photoshop .psd files and you don't
6
+ # want those in your Capistrano deployments. Change the source path here if you want.
7
+ # ginsu.source = '/home/webproject/site'
8
+
9
+ # ginsu.partials << { :static => 'index.html', :partial => 'header', :search => '#header' }
10
+ # ginsu.partials << { :static => 'index.html', :partial => 'footer', :search => '#footer' }
11
+
12
+ # ginsu.templates << { :static => 'Templates/master.dwt', :template => 'master' }
13
+
14
+ # ginsu.links << { :static => 'galleries' }
15
+ # ginsu.links << { :static => 'news' }
16
+
17
+ end
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{ginsu}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Ryan Porter"]
12
+ s.date = %q{2011-05-19}
13
+ s.description = %q{Ginsu is a Ruby on Rails plugin for carving partials out of static web sites, for including
14
+ graphic designers in the agile process for developing a web project.
15
+ }
16
+ s.email = %q{rap@endymion.com}
17
+ s.extra_rdoc_files = [
18
+ "README.textile"
19
+ ]
20
+ s.files = [
21
+ "MIT-LICENSE",
22
+ "README.textile",
23
+ "Rakefile",
24
+ "VERSION",
25
+ "generators/ginsu/USAGE",
26
+ "generators/ginsu/ginsu_generator.rb",
27
+ "generators/ginsu/templates/config/initializers/ginsu.rb",
28
+ "ginsu.gemspec",
29
+ "init.rb",
30
+ "install.rb",
31
+ "lib/ginsu.rb",
32
+ "lib/ginsu/config.rb",
33
+ "lib/ginsu/knife.rb",
34
+ "lib/this_method.rb",
35
+ "rails/init.rb",
36
+ "tasks/ginsu_tasks.rake",
37
+ "test/ginsu_test.rb",
38
+ "test/test_helper.rb",
39
+ "uninstall.rb"
40
+ ]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.7}
43
+ s.summary = %q{A Ruby on Rails plugin for carving partials out of static web sites.}
44
+ s.test_files = [
45
+ "test/ginsu_test.rb",
46
+ "test/test_helper.rb"
47
+ ]
48
+
49
+ if s.respond_to? :specification_version then
50
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
51
+ s.specification_version = 3
52
+
53
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
+ else
55
+ end
56
+ else
57
+ end
58
+ end
59
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/rails/init"
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,13 @@
1
+ module Ginsu; end
2
+
3
+ require('rubygems')
4
+
5
+ require('hpricot')
6
+
7
+ def require_local(suffix)
8
+ require(File.expand_path(File.join(File.dirname(__FILE__), suffix)))
9
+ end
10
+
11
+ require_local('this_method')
12
+ require_local('ginsu/knife')
13
+ require_local('ginsu/config')
@@ -0,0 +1,47 @@
1
+ # config.rb contains classes, methods and extends existing Ginsu classes
2
+ # to provide easy configuration facilities.
3
+
4
+ module Ginsu
5
+ # Represents global configuration for Ginsu::Knife.
6
+ # Can override the following configuration options:
7
+ # * <tt>source</tt> - the source directory of the static web site. Defaults to 'static'.
8
+ class Config
9
+ @@ATTRIBUTES = [
10
+ :source,
11
+ :partials,
12
+ :pages,
13
+ :templates,
14
+ :links,
15
+ :folders
16
+ ]
17
+ attr_accessor *@@ATTRIBUTES
18
+
19
+ def initialize(params = {})
20
+ params.each do |key,val|
21
+ self.send("#{key}=", val) if self.respond_to? key
22
+ end
23
+ self.send(:init) if self.respond_to? :init
24
+ end
25
+
26
+ end
27
+
28
+ class Knife
29
+ @@defaults = {
30
+ :source => 'static',
31
+ :partials => [],
32
+ :pages => [],
33
+ :templates => [],
34
+ :links => [],
35
+ :folders => []
36
+ }
37
+ @@config = Ginsu::Config.new(@@defaults)
38
+
39
+ class << self
40
+ # Yields to given <tt>block</tt> to configure the Ginsu.
41
+ def configure(&block)
42
+ raise ArgumentError, "Block must be provided to configure" unless block_given?
43
+ yield @@config
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,145 @@
1
+ module Ginsu
2
+ class Knife
3
+
4
+ def self.slice
5
+ self.partials
6
+ self.pages
7
+ self.templates
8
+ self.links
9
+ self.folders
10
+ end
11
+
12
+ def self.pages parameters=nil
13
+ files = (parameters and parameters[:partials]) ? @@config.partials : @@config.pages
14
+ files.each do |file|
15
+
16
+ # These should probably raise errors.
17
+ puts "Error: Each file requires a :static parameter to specify the source file." if
18
+ file[:static].blank?
19
+ puts "Error: Each file requires a :search parameter with a search string." if
20
+ file[:search].blank?
21
+ puts "Error: Each file requires a :partial parameter with the name of the destination template." if
22
+ file[:partial].blank?
23
+
24
+ # Open the static source HTML file.
25
+ static_source_string = ''
26
+ static_source_path = File.join(@@config.source, file[:static])
27
+ File.open(static_source_path, "r") { |f|
28
+ static_source_string = ''
29
+ # Run a proc on each line?
30
+ if file[:do]
31
+ f.each {|line| static_source_string << file[:do].call(line)}
32
+ else
33
+ static_source_string = f.read
34
+ end
35
+ }
36
+ static_source = Hpricot(static_source_string)
37
+
38
+ # Use Hpricot to slice out the desired element.
39
+ found = static_source.search(file[:search]).first
40
+
41
+ # Make sure that the target folder exists.
42
+ unless File.exists?(target_folder = File.join('app/views/', File.dirname(file[:partial])))
43
+ Dir.mkdir(target_folder)
44
+ end
45
+
46
+ # Drop that found string into the appropriate partial.
47
+ target_filename = file[:partial]
48
+ puts "Slicing '#{target_filename}' from '#{static_source_path}'..."
49
+ target_filename.gsub!(/\/([^\_][^\/]+$)/) {|string| '/_' + $1 } if
50
+ parameters and parameters[:partials]
51
+ target_filename += '.html.erb' unless target_filename =~ /\./
52
+ target_filename = File.join('app/views/', target_filename)
53
+ File.open(target_filename, 'w') do |f|
54
+ f.write(found)
55
+ end
56
+
57
+ end
58
+ end
59
+
60
+ def self.partials
61
+ self.pages :partials => true
62
+ end
63
+
64
+ def self.templates parameters=nil
65
+ files = @@config.templates
66
+ files.each do |file|
67
+
68
+ # These should probably raise errors.
69
+ puts "Error: Each file requires a :static parameter to specify the source file." if
70
+ file[:static].blank?
71
+ puts "Error: Each file requires a :search parameter with a search string." if
72
+ file[:search].blank?
73
+ puts "Error: Each file requires a :template parameter with the name of the destination template." if
74
+ file[:template].blank?
75
+
76
+ # Open the static source HTML file.
77
+ static_source_string = ''
78
+ static_source_path = File.join(@@config.source, file[:static])
79
+ File.open(static_source_path, "r") { |f|
80
+ static_source_string = ''
81
+ # Run a proc on each line?
82
+ if file[:do]
83
+ f.each {|line| static_source_string << file[:do].call(line)}
84
+ else
85
+ static_source_string = f.read
86
+ end
87
+ }
88
+ static_source = Hpricot(static_source_string)
89
+
90
+ # Use Hpricot to replace the desired element.
91
+ static_source.at(file[:search]).swap(file[:replace])
92
+ found = static_source.to_original_html
93
+
94
+ # Drop that found string into the appropriate partial.
95
+ target_filename = file[:template]
96
+ puts "Slicing template '#{target_filename}' from '#{static_source_path}'..."
97
+ target_filename += '.html.erb' unless target_filename =~ /\./
98
+ target_filename = File.join('app/views/layouts', target_filename)
99
+ File.open(target_filename, 'w') do |f|
100
+ f.write(found)
101
+ end
102
+
103
+ end
104
+ end
105
+
106
+ def self.links
107
+ @@config.links.each do |link|
108
+
109
+ source = File.join(FileUtils.pwd, @@config.source, link[:static])
110
+ destination = File.join('public', link[:static])
111
+
112
+ puts "Linking '#{source}' to '#{destination}'..."
113
+
114
+ puts "Each link requires a :static parameter with the name of the static resource" +
115
+ " to link to the public/ directory in your Rails application." if
116
+ link[:static].blank?
117
+
118
+ FileUtils.ln_s source, destination, :force => true unless File.exists? destination
119
+
120
+ end
121
+ end
122
+
123
+ def self.folders
124
+ @@config.folders.each do |folder|
125
+
126
+ source = File.join(FileUtils.pwd, @@config.source, folder[:static])
127
+ destination = File.join('public', folder[:static])
128
+
129
+ puts "Purging '#{destination}'..."
130
+
131
+ FileUtils.rm_rf destination
132
+
133
+ puts "Recursively copying '#{source}' to '#{destination}'..."
134
+
135
+ puts "Each folder requires a :static parameter with the name of the static resource" +
136
+ " to copy to the public/ directory in your Rails application." if
137
+ folder[:static].blank?
138
+
139
+ FileUtils.cp_r source, destination
140
+
141
+ end
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,6 @@
1
+ module Kernel
2
+ private
3
+ def this_method
4
+ caller[0] =~ /`([^']*)'/ and $1
5
+ end
6
+ end
@@ -0,0 +1 @@
1
+ # Include hook code here
@@ -0,0 +1,6 @@
1
+ namespace :ginsu do
2
+ desc "Update Rails application from static web site source."
3
+ task :slice => :environment do
4
+ Ginsu::Knife.slice
5
+ end
6
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class GinsuTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ginsu
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - Ryan Porter
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-19 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: |
23
+ Ginsu is a Ruby on Rails plugin for carving partials out of static web sites, for including
24
+ graphic designers in the agile process for developing a web project.
25
+
26
+ email: rap@endymion.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.textile
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.textile
36
+ - Rakefile
37
+ - VERSION
38
+ - generators/ginsu/USAGE
39
+ - generators/ginsu/ginsu_generator.rb
40
+ - generators/ginsu/templates/config/initializers/ginsu.rb
41
+ - ginsu.gemspec
42
+ - init.rb
43
+ - install.rb
44
+ - lib/ginsu.rb
45
+ - lib/ginsu/config.rb
46
+ - lib/ginsu/knife.rb
47
+ - lib/this_method.rb
48
+ - rails/init.rb
49
+ - tasks/ginsu_tasks.rake
50
+ - test/ginsu_test.rb
51
+ - test/test_helper.rb
52
+ - uninstall.rb
53
+ has_rdoc: true
54
+ homepage:
55
+ licenses: []
56
+
57
+ post_install_message:
58
+ rdoc_options: []
59
+
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ requirements: []
81
+
82
+ rubyforge_project:
83
+ rubygems_version: 1.3.7
84
+ signing_key:
85
+ specification_version: 3
86
+ summary: A Ruby on Rails plugin for carving partials out of static web sites.
87
+ test_files:
88
+ - test/ginsu_test.rb
89
+ - test/test_helper.rb