pubba 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/.gitignore +14 -0
  2. data/.yardopts +2 -0
  3. data/Gemfile +3 -0
  4. data/README.md +163 -0
  5. data/Rakefile +46 -0
  6. data/lib/sinatra/pubba.rb +28 -0
  7. data/lib/sinatra/pubba/assets/configuration.rb +25 -0
  8. data/lib/sinatra/pubba/assets/handler.rb +15 -0
  9. data/lib/sinatra/pubba/assets/sprockets_handler.rb +34 -0
  10. data/lib/sinatra/pubba/errors.rb +5 -0
  11. data/lib/sinatra/pubba/html/helpers.rb +33 -0
  12. data/lib/sinatra/pubba/locale.rb +18 -0
  13. data/lib/sinatra/pubba/page.rb +52 -0
  14. data/lib/sinatra/pubba/site.rb +136 -0
  15. data/lib/sinatra/pubba/version.rb +5 -0
  16. data/pubba.gemspec +30 -0
  17. data/test/helper.rb +73 -0
  18. data/test/pubba/assets/test_configuration.rb +33 -0
  19. data/test/pubba/assets/test_handler.rb +16 -0
  20. data/test/pubba/html/test_helpers.rb +18 -0
  21. data/test/pubba/test_page.rb +17 -0
  22. data/test/pubba/test_site.rb +36 -0
  23. data/test/sinatra/app/assets/javascripts/custom/app.js +3 -0
  24. data/test/sinatra/app/assets/javascripts/custom/track.js +3 -0
  25. data/test/sinatra/app/assets/javascripts/third-party/jq.js +3 -0
  26. data/test/sinatra/app/assets/javascripts/third-party/jqc.js +3 -0
  27. data/test/sinatra/app/assets/stylesheets/custom/global.css +3 -0
  28. data/test/sinatra/app/assets/stylesheets/custom/home.css +4 -0
  29. data/test/sinatra/app/assets/stylesheets/custom/search.css +3 -0
  30. data/test/sinatra/app/assets/stylesheets/third-party/widget.css +3 -0
  31. data/test/sinatra/app/i18n/en.yml +15 -0
  32. data/test/sinatra/config/pubba.yml +20 -0
  33. data/test/sinatra/public/javascripts/_ +0 -0
  34. data/test/sinatra/public/stylesheets/_ +0 -0
  35. metadata +148 -0
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ *.swp
2
+ *.gem
3
+
4
+ readme.html
5
+ Gemfile.lock
6
+
7
+ .bundle
8
+ .rvmrc
9
+ .DS_Store
10
+ .yardoc
11
+
12
+ doc
13
+ coverage
14
+ pkg
data/.yardopts ADDED
@@ -0,0 +1,2 @@
1
+ --title Pubba
2
+ --files CHANGES,LICENSE
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # pubba
2
+
3
+ pubba is a Sinatra extension designed to help you manage your site. It uses [Sprockets](https://github.com/sstephenson/sprockets) for packaging assets and [R18n](http://r18n.rubyforge.org/) for internationalization/localization. I use R18n as a central location for default text, the internationalization functionality is a nice bonus in the event the application needs to move in that direction.
4
+
5
+ # Note
6
+
7
+ This extension is under heavy, heavy development and is subject to massive changes over the next week or so.
8
+
9
+ TODO:
10
+
11
+ * Support 3rd part script tags in pubba.yml
12
+ * Add support for media queries on style definitions. This will obviously change the current pubba.yml format.
13
+ * Remove requirement for placing of scripts/styles in subdirectories. For instance, the convention now is scripts would be in subdirs like javascripts/custom and javscripts/third-party. The only scripts/styles in the root dir are those generated by this extension.
14
+ * Compress the combined assets
15
+ * More tests!
16
+ * Improve documentation!
17
+
18
+ # Why?
19
+
20
+ There's really two main driving forces behind this extension: audit requirements and code organization.
21
+
22
+ If you've ever had to deal with an audit department, you understand some of the strict requirements that can be placed on releases. One of the main themes in audit is providing proof on what was released.
23
+
24
+ Any process that involves changing code between environments, even in an automated fashion, is great fodder for the audit machine. This extension makes sure the javascript and css you work with in development is the same as it will be in production.
25
+
26
+ This does the require the use of a cache bursting query parameter to be added to the url instead of the digest per asset approach. While the digest approach is much more accurate it complicates using a commit/tag to completely represent the deployment contents.
27
+
28
+ As mentioned, code organization is another focus of Pubba. The config file __pubba.yml__ uses the global section to clearly state which assets should be on all pages. In addition, when using R18n, Pubba gives you access through a single page object.
29
+
30
+
31
+ # Settings
32
+
33
+ More details on these later, but here are the configuration options:
34
+
35
+ **Note: __settings.root__ refers to \<ProjectRoot\>/app/**
36
+
37
+ ### Location of the config file. REQUIRED
38
+ set :pubba_config, File.join(settings.root, '..', 'config', 'pubba.yml')
39
+
40
+ ### Location of the public_folder. REQUIRED
41
+ set :public_folder, File.join(settings.root, '..', 'public')
42
+
43
+ ### Location of the asset_folder. REQUIRED
44
+ set :asset_folder, File.join(settings.root, 'assets')
45
+
46
+ ### Asset handler. Defaults to [Sprockets](https://github.com/sstephenson/sprockets)
47
+ Right now there's only support for Sprockets, but leaving the option open for others.
48
+ set :asset_handler, Sinatra::Pubba::Assets::SprocketsHandler
49
+
50
+ ### Location of the [R18n](http://r18n.rubyforge.org/) folder. OPTIONAL
51
+ set :r18n_folder, File.join(settings.root, 'i18n')
52
+
53
+ ### Locale. Defaults to 'en'
54
+ set :r18n_locale, 'en'
55
+
56
+
57
+
58
+ # How?
59
+
60
+ First things first, you'll want to install the gem:
61
+
62
+ gem install pubba
63
+
64
+ Then you'll want to use it in your app like so:
65
+
66
+ require 'sinatra/pubba'
67
+
68
+ class App < Sinatra::Application
69
+ # Settings as described above
70
+ set :asset_folder, File.join(settings.root, 'assets')
71
+ set :public_folder, File.join(settings.root, '..', 'public')
72
+ set :r18n_folder, File.join(settings.root, 'i18n')
73
+
74
+ set :pubba_config, File.join(settings.root, '..', 'config', 'pubba.yml')
75
+
76
+ register Sinatra::Pubba
77
+ end
78
+
79
+ Next up is creating the all important __pubba.yml__ config file:
80
+
81
+ global:
82
+ styles:
83
+ - "custom/global"
84
+ head_scripts:
85
+ - "third-party/jquery-1.7.0.min"
86
+ body_scripts:
87
+ - "third-party/jquery.cookie"
88
+ - "custom/autocomplete"
89
+ - "custom/application"
90
+
91
+ # Home page configuration
92
+ home:
93
+ styles:
94
+ - "custom/home"
95
+
96
+ # Search results page configuration
97
+ search:
98
+ styles:
99
+ - "custom/search"
100
+
101
+ The config file is referencing the javascripts and stylesheets located in the `asset_folder`.
102
+
103
+ If you're using R18n, you will need a translation file, here's a sample en.yml:
104
+
105
+ home:
106
+ title: "Home title"
107
+ meta_description: "Home meta description"
108
+ meta_keywords: "Home keywords"
109
+ welcome_text: "Welcome Home"
110
+
111
+ logout_link: "Logout"
112
+ login_link: "Login"
113
+ home_link: "Home"
114
+ account_link: "My Account"
115
+
116
+ Take note of the __home__ section in both __pubba.yml__ and __en.yml__. If you have a route in your app that you want to use the __home__ defintions, do this:
117
+
118
+ get '/' do
119
+ @page = Sinatra::Pubba::Site.page('home')
120
+ slim :"aux/index"
121
+ end
122
+
123
+ The `@page` variable gives you access to the definitions in __en.yml__. In your view you'll be able to use it like so:
124
+
125
+ html
126
+ head
127
+ title = @page.title
128
+ body
129
+ menu
130
+ a href="/" = @page.home_link
131
+
132
+ Notice that `title` is defined under the `home` section, but `home_link` is a top level definition. Pubba makes the effort to correctly resolve the __en.yml__ reference for you. Nice isn't it.
133
+
134
+ Now you obviouslly need some helpers to make use of the definitions in __pubba.yml__, and here they are:
135
+
136
+ * `page_head_tags`
137
+ * This helper emits the `link` and `script` tags with the contents defined in __pubba.yml__
138
+ * `page_body_tags`
139
+ * This helper emits the `script` tag with the contents defined in __pubba.yml__. You would typically place this just before the `</body>` tag.
140
+ * `burst(url)`
141
+ * This helper simply appends a cache bursting parameter named `aid` to the end of the url. In development mode the `aid` value is updated per request. The intent is to help with the particularly aggressive caching Google's Chrome browser likes to implement. In production mode, Pubba requires `ENV[ASSET_ID]` to be set and uses this for the `aid` value. I expect this to be tweaked as I get further into implementation.
142
+
143
+ Sample use:
144
+
145
+ html
146
+ head
147
+ title = @page.title
148
+ == page_head_tags
149
+ body
150
+ menu
151
+ a href="/" = @page.home_link
152
+ == page_body_tags
153
+
154
+ What you'll see when working with Pubba is that the files in your `asset_folder` are never referenced in your view. Even in development mode! The intent is that development mode is as close to production mode as possible. So, you are working with the same combined asset file you will be deploying.
155
+
156
+ # Acknowledgement
157
+
158
+ Huge thanks to my company, [Primedia](http://primedia.com) for encouraging open source contributions. This particular extension is obviously very new and hasn't hit a production site yet, but it will. I will post a list here as we migrate our applications from Rails to Sinatra.
159
+
160
+ # Contributors
161
+
162
+ I highly value contributions and will happily list all those who submit accepted pull requests.
163
+
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ begin
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+ rescue Exception => e
5
+ end
6
+
7
+ require 'rake/testtask'
8
+
9
+ Rake::TestTask.new('test') do |t|
10
+ t.libs << 'lib' << 'test'
11
+ t.test_files = Dir.glob('test/**/test_*.rb')
12
+ t.verbose = true
13
+ end
14
+
15
+ task 'test:ci' do |t|
16
+ Rake::Task[ENV['TASK']].execute
17
+ end
18
+
19
+ begin
20
+ require 'rcov/rcovtask'
21
+ Rcov::RcovTask.new do |t|
22
+ t.libs << 'lib' << 'test'
23
+ t.test_files = Dir.glob('test/**/test_*.rb')
24
+ t.verbose = true
25
+ end
26
+ rescue LoadError
27
+ task :rcov do
28
+ abort "RCov is not available. In order to run rcov, you must: gem install rcov"
29
+ end
30
+ end
31
+
32
+ begin
33
+ require 'yard'
34
+ YARD::Rake::YardocTask.new do |t|
35
+ t.files = %w(lib/**/*.rb)
36
+ end
37
+ rescue LoadError
38
+ task :yard do
39
+ abort "YARD is not available. In order to run yard, you must: gem install yard"
40
+ end
41
+ end
42
+
43
+ desc "Generate Documentation"
44
+ task :doc => :yard
45
+
46
+ task :default => 'test'
@@ -0,0 +1,28 @@
1
+ require 'sinatra/base'
2
+
3
+ require_relative 'pubba/errors'
4
+ require_relative 'pubba/site'
5
+ require_relative 'pubba/html/helpers'
6
+
7
+ module Sinatra
8
+ module Pubba
9
+ def self.registered(app)
10
+ if app.settings.development? || app.settings.test?
11
+ Site.configure(app)
12
+
13
+ app.before do
14
+ app.settings.set :asset_id, ->{Time.now.strftime("%N")}
15
+ end
16
+ else
17
+ app.settings.set :asset_id, asset_id
18
+ end
19
+
20
+ app.helpers Sinatra::Pubba::HTML::Helpers
21
+
22
+ end
23
+
24
+ def self.asset_id
25
+ ENV['ASSET_ID'] || raise(ConfigurationError, "Required ENV[ASSET_ID] not defined")
26
+ end
27
+ end # Pubba
28
+ end # Sinatra
@@ -0,0 +1,25 @@
1
+ require 'psych'
2
+
3
+ module Sinatra
4
+ module Pubba
5
+ module Assets
6
+ class Configuration
7
+ attr_reader :yaml
8
+
9
+ def initialize(config_file)
10
+ @yaml = Psych.load_file(config_file)
11
+ end
12
+
13
+ def global_config!
14
+ yaml.delete("global")
15
+ end
16
+
17
+ def process
18
+ yaml.each do |page, config|
19
+ yield page, config
20
+ end
21
+ end
22
+ end # Configuration
23
+ end # Assets
24
+ end # Pubba
25
+ end # Sinatra
@@ -0,0 +1,15 @@
1
+ module Sinatra
2
+ module Pubba
3
+ module Assets
4
+ class Handler
5
+ def self.asset(file)
6
+ raise NotImplementedError
7
+ end
8
+
9
+ def save_as(file)
10
+ raise NotImplementedError
11
+ end
12
+ end # Handler
13
+ end # Assets
14
+ end # Pubba
15
+ end # Sinatra
@@ -0,0 +1,34 @@
1
+ require 'sprockets'
2
+ require_relative 'handler'
3
+
4
+ module Sinatra
5
+ module Pubba
6
+ module Assets
7
+ class SprocketsHandler < Handler
8
+ def self.find(file)
9
+ SprocketsHandler.new(sprockets.find_asset(file))
10
+ end
11
+
12
+ def self.asset_paths(*paths)
13
+ paths.each do |path|
14
+ sprockets.append_path path
15
+ end
16
+ end
17
+
18
+ def self.sprockets
19
+ @sprockets ||= Sprockets::Environment.new()
20
+ end
21
+
22
+ attr_reader :asset
23
+
24
+ def initialize(asset)
25
+ @asset = asset
26
+ end
27
+
28
+ def save_as(file)
29
+ asset.write_to(file)
30
+ end
31
+ end # SprocketsHandler
32
+ end # Assets
33
+ end # Pubba
34
+ end # Sinatra
@@ -0,0 +1,5 @@
1
+ module Sinatra
2
+ module Pubba
3
+ class ConfigurationError < StandardError; end
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ module Sinatra
2
+ module Pubba
3
+ module HTML
4
+ module Helpers
5
+ def page_head_tags
6
+ tag_content('link', '', { href: burst("/stylesheets/#{@page.name}-styles.css"), rel: "stylesheet", type: "text/css" }) + tag_content('script', '', { src: burst("/javascripts/#{@page.name}-head.js"), type: "text/javascript" })
7
+ end
8
+
9
+ def page_body_tags
10
+ tag_content('script', '', { src: burst("/javascripts/#{@page.name}-body.js"), type: "text/javascript" })
11
+ end
12
+
13
+ def burst(url)
14
+ joiner = url.include?("?") ? "&" : "?"
15
+ "#{url}#{joiner}aid=#{settings.asset_id}"
16
+ end
17
+
18
+ def tag_content(tag, content, attrs={}, self_closing=false)
19
+ base = "<#{tag}#{tag_attrs(attrs)}"
20
+ self_closing ? "#{base}/>":"#{base}>#{content}</#{tag}>"
21
+ end
22
+
23
+ def tag_attrs(attrs)
24
+ return '' if attrs.empty?
25
+
26
+ return " " + attrs.collect do |k,v|
27
+ %|#{k}="#{v}"|
28
+ end.join(' ')
29
+ end
30
+ end
31
+ end # HTML
32
+ end # Pubba
33
+ end # Sinatra
@@ -0,0 +1,18 @@
1
+ require 'r18n-desktop'
2
+
3
+ module Sinatra
4
+ module Pubba
5
+ class Locale
6
+ include R18n::Helpers
7
+
8
+ R18n.from_env Site.r18n_folder, Site.r18n_locale
9
+
10
+ def get(category, name, *args)
11
+ res = t.send(category).send(name, *args)
12
+ res = t.send(name, *args) if R18n::Untranslated === res
13
+
14
+ R18n::Untranslated === res ? nil : res
15
+ end
16
+ end # Locale
17
+ end # Pubba
18
+ end # Sinatra
@@ -0,0 +1,52 @@
1
+ module Sinatra
2
+ module Pubba
3
+ class Page
4
+ attr_accessor :name
5
+ attr_reader :assets
6
+
7
+ def initialize(name, global_configuration = {})
8
+ @name = name
9
+ @assets = {}
10
+
11
+ Site.asset_types.keys.each do |asset|
12
+ @assets[asset] = global_configuration[asset] || []
13
+ end
14
+ end
15
+
16
+ def add_asset(name, array)
17
+ assets[name] += array unless array.empty?
18
+ end
19
+
20
+ def assetize
21
+ Site.asset_types.each{ |key, val| create_asset(key, val) }
22
+ end
23
+
24
+ def method_missing(meth, *args)
25
+ if Site.locale && (t = Site.locale.get(name, meth, *args))
26
+ return t
27
+ end
28
+ super
29
+ end
30
+
31
+ private
32
+
33
+ def process_scripts(array)
34
+ return [] if array.nil? || array.empty?
35
+
36
+ array.each{|ele| scripts << ele }
37
+ end
38
+
39
+ def create_asset(asset, dir)
40
+ type = asset.split('_').first
41
+ ext = asset.end_with?('styles') ? 'css' : 'js'
42
+
43
+ File.open( File.join(dir, "#{name}-#{type}.#{ext}"), 'w') do |f|
44
+ f.write Site.disclaimer
45
+ assets[asset].each do |script|
46
+ f.write "//= require #{script}.#{ext}\n"
47
+ end
48
+ end
49
+ end
50
+ end # Page
51
+ end # Pubba
52
+ end # Sinatra
@@ -0,0 +1,136 @@
1
+ require_relative 'assets/configuration'
2
+ require_relative 'assets/sprockets_handler'
3
+ require_relative 'page'
4
+
5
+ module Sinatra
6
+ module Pubba
7
+ module Site
8
+ extend self
9
+ attr_accessor :global_asset_configuration, :asset_handler
10
+
11
+ attr_reader :asset_types
12
+ attr_reader :script_asset_folder, :style_asset_folder
13
+ attr_reader :script_public_folder, :style_public_folder
14
+
15
+ attr_reader :disclaimer
16
+
17
+ attr_reader :locale, :r18n_folder, :r18n_locale
18
+
19
+
20
+ def configure(app)
21
+ settings = app.settings
22
+
23
+ validate_settings(settings)
24
+
25
+ set_defaults(settings)
26
+
27
+ maybe_init_r18n(settings)
28
+
29
+ # Load pubba_config
30
+ asset_configuration = Sinatra::Pubba::Assets::Configuration.new(settings.pubba_config)
31
+
32
+ # Set assset handler
33
+ configure_asset_handler(settings)
34
+
35
+ # Grab the global section defined in @pubba_config
36
+ @global_asset_configuration = asset_configuration.global_config!
37
+
38
+ # Process the remaining @pubba_config sections
39
+ asset_configuration.process do |page, config|
40
+ Site.add_page(page, config).assetize
41
+ end
42
+
43
+ # Write assets to public_folder
44
+ compile_assets(app)
45
+ end
46
+
47
+
48
+ def validate_settings(settings)
49
+ missing_settings = []
50
+ unless settings.respond_to? :public_folder
51
+ missing_settings << ":public_folder has not been set!"
52
+ end
53
+
54
+ unless settings.respond_to? :asset_folder
55
+ missing_settings << ":asset_folder has not been set!"
56
+ end
57
+
58
+ if missing_settings.length > 0
59
+ messages = missing_settings.join("\n")
60
+ raise Pubba::ConfigurationError.new("Missing configuration options:\n#{messages}")
61
+ end
62
+ end
63
+
64
+ def set_defaults(settings)
65
+ @script_public_folder = File.join(settings.public_folder, 'javascripts')
66
+ @style_public_folder = File.join(settings.public_folder, 'stylesheets')
67
+ @script_asset_folder = File.join(settings.asset_folder, 'javascripts')
68
+ @style_asset_folder = File.join(settings.asset_folder, 'stylesheets')
69
+
70
+ @asset_types = {'styles' => style_asset_folder,
71
+ 'head_scripts' => script_asset_folder,
72
+ 'body_scripts' => script_asset_folder}
73
+
74
+ @disclaimer = "// This file is automatically generated from the contents\n// in #{settings.pubba_config}\n//\n"
75
+ end
76
+
77
+ def maybe_init_r18n(settings)
78
+ return unless settings.respond_to?(:r18n_folder)
79
+
80
+ locale = 'en'
81
+ if settings.respond_to?(:r18n_locale)
82
+ locale = settings.r18n_locale
83
+ end
84
+
85
+ @r18n_folder = settings.r18n_folder
86
+ @r18n_locale = locale
87
+
88
+ require_relative 'locale'
89
+
90
+ @locale = Locale.new
91
+ end
92
+
93
+ def configure_asset_handler(settings)
94
+ @asset_handler = Sinatra::Pubba::Assets::SprocketsHandler
95
+ if settings.respond_to?(:asset_handler) && (handler = settings.asset_handler)
96
+ @asset_handler = handler
97
+ end
98
+ @asset_handler.asset_paths style_asset_folder, script_asset_folder
99
+ end
100
+
101
+ def page(name)
102
+ pages[name]
103
+ end
104
+
105
+ def pages
106
+ @pages ||= {}
107
+ end
108
+
109
+ def add_page(name, hash)
110
+ page = Page.new(name, global_asset_configuration)
111
+
112
+ asset_types.keys.each do |asset|
113
+ page.add_asset(asset, hash[asset]) if hash[asset]
114
+ end
115
+
116
+ pages[name] = page
117
+ end
118
+
119
+ private
120
+
121
+ def compile_assets(app)
122
+ process_assets(script_asset_folder, script_public_folder)
123
+ process_assets(style_asset_folder, style_public_folder)
124
+ end
125
+
126
+ def process_assets(from_folder, to_folder)
127
+ Dir.glob("#{from_folder}/*.*") do |file|
128
+ asset = asset_handler.find(file)
129
+ asset.save_as "#{to_folder}/#{File.basename(file)}"
130
+ end
131
+ end
132
+
133
+ @global_asset_configuration = {}
134
+ end # Site
135
+ end # Pubba
136
+ end # Sinatra
@@ -0,0 +1,5 @@
1
+ module Pubba
2
+ # Pubba version string
3
+ # @api public
4
+ VERSION = '0.1.0'
5
+ end
data/pubba.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.dirname(__FILE__) + '/lib/sinatra/pubba/version'
3
+ require 'date'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'pubba'
7
+ s.version = Pubba::VERSION
8
+ s.date = Date.today.to_s
9
+ s.authors = ['Andrew Stone']
10
+ s.email = ['andy@stonean.com']
11
+ s.summary = 'Pubba is a Sinatra extension.'
12
+ s.description = 'Pubba is a Sinatra extension designed to help you manage your site.'
13
+ s.homepage = 'http://github.com/stonean/pubba'
14
+ s.extra_rdoc_files = %w(README.md)
15
+ s.rdoc_options = %w(--charset=UTF-8)
16
+ s.rubyforge_project = s.name
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = %w(lib)
21
+
22
+
23
+ s.add_runtime_dependency('sprockets', ['~> 2.1.2'])
24
+ s.add_runtime_dependency('r18n-desktop', ['~> 0.4.11'])
25
+
26
+ s.add_development_dependency('rake', ['>= 0.9.2'])
27
+ s.add_development_dependency('sinatra', ['>= 1.3.1'])
28
+ s.add_development_dependency('sinatra-contrib', ['>= 1.3.1'])
29
+ s.add_development_dependency('yard', ['>= 0'])
30
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,73 @@
1
+ require 'minitest/unit'
2
+ require 'sinatra/test_helpers'
3
+
4
+ MiniTest::Unit.autorun
5
+
6
+ module R
7
+ extend self
8
+
9
+ def app_folder
10
+ File.join(File.dirname(__FILE__), 'sinatra', 'app')
11
+ end
12
+
13
+ def asset_folder
14
+ File.join(app_folder, 'assets')
15
+ end
16
+
17
+ def r18n_folder
18
+ File.join(app_folder, 'i18n')
19
+ end
20
+
21
+ def public_folder
22
+ File.join(File.dirname(__FILE__), 'sinatra', 'public')
23
+ end
24
+
25
+ def pubba_config_file
26
+ File.join(File.dirname(__FILE__), 'sinatra', 'config', 'pubba.yml')
27
+ end
28
+ end
29
+
30
+ class TestPubba < MiniTest::Unit::TestCase
31
+ include Sinatra::TestHelpers
32
+
33
+ def setup
34
+ mock_app do
35
+ require 'sinatra/pubba'
36
+
37
+ settings.set :public_folder, R.public_folder
38
+ settings.set :asset_folder, R.asset_folder
39
+ settings.set :r18n_folder, R.r18n_folder
40
+
41
+ settings.set :pubba_config, R.pubba_config_file
42
+
43
+ register Sinatra::Pubba
44
+
45
+ get('/home-page-head-tags') do
46
+ @page = Sinatra::Pubba::Site.page('home');
47
+ page_head_tags
48
+ end
49
+
50
+ get('/home-page-body-tags') do
51
+ @page = Sinatra::Pubba::Site.page('home');
52
+ page_body_tags
53
+ end
54
+ end
55
+ end
56
+
57
+ def teardown
58
+ [R.asset_folder, R.public_folder].each do |root_folder|
59
+ Dir.glob(File.join(root_folder, 'javascripts', '*.js')) do |f|
60
+ File.delete(f) if File.exist?(f)
61
+ end
62
+
63
+ Dir.glob(File.join(root_folder, 'stylesheets', '*.css')) do |f|
64
+ File.delete(f) if File.exist?(f)
65
+ end
66
+ end
67
+ end
68
+
69
+ def empty_hash
70
+ {}
71
+ end
72
+ end
73
+
@@ -0,0 +1,33 @@
1
+ require 'helper'
2
+
3
+ class TestPubbaAssetsConfiguration < TestPubba
4
+ def setup
5
+ @config = Sinatra::Pubba::Assets::Configuration.new(R.pubba_config_file)
6
+ end
7
+
8
+ def test_yaml_is_initialized
9
+ hsh = {"global"=>{"styles"=>["custom/global"], "head_scripts"=>["third-party/jq"], "body_scripts"=>["third-party/jqc", "custom/app"]}, "home"=>{"styles"=>["custom/home"]}, "search"=>{"styles"=>["custom/search", "third-party/widget"]}}
10
+ assert_equal hsh, @config.yaml
11
+ end
12
+
13
+ def test_global_config
14
+ hsh = {"styles"=>["custom/global"], "head_scripts"=>["third-party/jq"], "body_scripts"=>["third-party/jqc", "custom/app"]}
15
+ assert_equal hsh, @config.global_config!
16
+
17
+ assert_nil @config.yaml["global"]
18
+ end
19
+
20
+ def test_process
21
+ sections = ["home", "search"]
22
+
23
+ @config.global_config!
24
+
25
+ @config.process do |page, config|
26
+ assert sections.include?(page), "Page :#{page} not expected"
27
+ end
28
+ end
29
+
30
+ def teardown
31
+ @config = nil
32
+ end
33
+ end
@@ -0,0 +1,16 @@
1
+ require 'helper'
2
+
3
+ class TestHandler < TestPubba
4
+ def test_asset
5
+ assert_raises NotImplementedError do
6
+ Sinatra::Pubba::Assets::Handler.asset('')
7
+ end
8
+ end
9
+
10
+ def test_save_as
11
+ handler = Sinatra::Pubba::Assets::Handler.new
12
+ assert_raises NotImplementedError do
13
+ handler.save_as('')
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'helper'
2
+ require 'sinatra/pubba/html/helpers'
3
+
4
+ class TestPubbaHTMLHelper < TestPubba
5
+ include Sinatra::Pubba::HTML::Helpers
6
+
7
+ def test_home_page_head_tags
8
+ res = get('/home-page-head-tags').body.gsub /\d/,'1'
9
+ str = %|<link href="/stylesheets/home-styles.css?aid=111111111" rel="stylesheet" type="text/css"></link><script src="/javascripts/home-head.js?aid=111111111" type="text/javascript"></script>|
10
+ assert_equal str, res
11
+ end
12
+
13
+ def test_home_page_body_tags
14
+ res = get('/home-page-body-tags').body.gsub /\d/,'1'
15
+ str = %|<script src="/javascripts/home-body.js?aid=111111111" type="text/javascript"></script>|
16
+ assert_equal str, res
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require 'helper'
2
+
3
+ class TestPubbaPage < TestPubba
4
+ def test_home_r18n
5
+ page = Sinatra::Pubba::Site.page('home')
6
+
7
+ assert_equal 'Home title', page.title
8
+ assert_equal 'Logout', page.logout_link
9
+ end
10
+
11
+ def test_search_r18n
12
+ page = Sinatra::Pubba::Site.page('search')
13
+
14
+ assert_equal 'Search title', page.title
15
+ assert_equal 'Logout', page.logout_link
16
+ end
17
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ class TestPubbaSite < TestPubba
4
+ def test_global_asset_configuration_initialization
5
+ hsh = {"styles"=>["custom/global"], "head_scripts"=>["third-party/jq"], "body_scripts"=>["third-party/jqc", "custom/app"]}
6
+ assert_equal hsh, Sinatra::Pubba::Site.global_asset_configuration
7
+ end
8
+
9
+ def test_asset_handler_initialization
10
+ assert_equal Sinatra::Pubba::Assets::SprocketsHandler, Sinatra::Pubba::Site.asset_handler
11
+ end
12
+
13
+ def test_script_public_folder_initialization
14
+ assert_equal "#{R.public_folder}/javascripts", Sinatra::Pubba::Site.script_public_folder
15
+ end
16
+
17
+ def test_style_public_folder_initialization
18
+ assert_equal "#{R.public_folder}/stylesheets", Sinatra::Pubba::Site.style_public_folder
19
+ end
20
+
21
+ def test_script_asset_folder_initialization
22
+ assert_equal "#{R.asset_folder}/javascripts", Sinatra::Pubba::Site.script_asset_folder
23
+ end
24
+
25
+ def test_style_asset_folder_initialization
26
+ assert_equal "#{R.asset_folder}/stylesheets", Sinatra::Pubba::Site.style_asset_folder
27
+ end
28
+
29
+ def test_asset_types_initialization
30
+ asset_types = Sinatra::Pubba::Site.asset_types
31
+ assert_equal Sinatra::Pubba::Site.style_asset_folder, asset_types.delete('styles')
32
+ assert_equal Sinatra::Pubba::Site.script_asset_folder, asset_types.delete('head_scripts')
33
+ assert_equal Sinatra::Pubba::Site.script_asset_folder, asset_types.delete('body_scripts')
34
+ assert asset_types.empty?
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ function app(){
2
+ alert('This is the app test file');
3
+ }
@@ -0,0 +1,3 @@
1
+ function track(){
2
+ alert('This is the track test file');
3
+ }
@@ -0,0 +1,3 @@
1
+ function jq(){
2
+ alert('This is the jq test file');
3
+ }
@@ -0,0 +1,3 @@
1
+ function jqc(){
2
+ alert('This is the jqc test file');
3
+ }
@@ -0,0 +1,3 @@
1
+ #global{
2
+ font-weight: bold;
3
+ }
@@ -0,0 +1,4 @@
1
+ #home{
2
+ font-weight: bold;
3
+ text-decoration: underline;
4
+ }
@@ -0,0 +1,3 @@
1
+ #search{
2
+ text-align: left;
3
+ }
@@ -0,0 +1,3 @@
1
+ #widget{
2
+ color: #66f;
3
+ }
@@ -0,0 +1,15 @@
1
+ home:
2
+ title: "Home title"
3
+ meta_description: "Home meta description"
4
+ meta_keywords: "Home keywords"
5
+ welcome_text: "Welcome Home"
6
+
7
+ search:
8
+ title: "Search title"
9
+ meta_description: "Search meta description"
10
+ meta_keywords: "Search meta keywords"
11
+
12
+ logout_link: "Logout"
13
+ login_link: "Login"
14
+ home_link: "Home"
15
+ account_link: "My Account"
@@ -0,0 +1,20 @@
1
+ # Global configuration. Settings here will be applied to all pages.
2
+ global:
3
+ styles:
4
+ - "custom/global"
5
+ head_scripts:
6
+ - "third-party/jq"
7
+ body_scripts:
8
+ - "third-party/jqc"
9
+ - "custom/app"
10
+
11
+ # Home page configuration
12
+ home:
13
+ styles:
14
+ - "custom/home"
15
+
16
+ # Search page configuration
17
+ search:
18
+ styles:
19
+ - "custom/search"
20
+ - "third-party/widget"
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pubba
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Stone
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: sprockets
16
+ requirement: &2151906900 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.1.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2151906900
25
+ - !ruby/object:Gem::Dependency
26
+ name: r18n-desktop
27
+ requirement: &2151906320 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.4.11
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2151906320
36
+ - !ruby/object:Gem::Dependency
37
+ name: rake
38
+ requirement: &2151905780 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.9.2
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2151905780
47
+ - !ruby/object:Gem::Dependency
48
+ name: sinatra
49
+ requirement: &2151905080 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.1
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2151905080
58
+ - !ruby/object:Gem::Dependency
59
+ name: sinatra-contrib
60
+ requirement: &2151904480 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: 1.3.1
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2151904480
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: &2151903920 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *2151903920
80
+ description: Pubba is a Sinatra extension designed to help you manage your site.
81
+ email:
82
+ - andy@stonean.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files:
86
+ - README.md
87
+ files:
88
+ - .gitignore
89
+ - .yardopts
90
+ - Gemfile
91
+ - README.md
92
+ - Rakefile
93
+ - lib/sinatra/pubba.rb
94
+ - lib/sinatra/pubba/assets/configuration.rb
95
+ - lib/sinatra/pubba/assets/handler.rb
96
+ - lib/sinatra/pubba/assets/sprockets_handler.rb
97
+ - lib/sinatra/pubba/errors.rb
98
+ - lib/sinatra/pubba/html/helpers.rb
99
+ - lib/sinatra/pubba/locale.rb
100
+ - lib/sinatra/pubba/page.rb
101
+ - lib/sinatra/pubba/site.rb
102
+ - lib/sinatra/pubba/version.rb
103
+ - pubba.gemspec
104
+ - test/helper.rb
105
+ - test/pubba/assets/test_configuration.rb
106
+ - test/pubba/assets/test_handler.rb
107
+ - test/pubba/html/test_helpers.rb
108
+ - test/pubba/test_page.rb
109
+ - test/pubba/test_site.rb
110
+ - test/sinatra/app/assets/javascripts/custom/app.js
111
+ - test/sinatra/app/assets/javascripts/custom/track.js
112
+ - test/sinatra/app/assets/javascripts/third-party/jq.js
113
+ - test/sinatra/app/assets/javascripts/third-party/jqc.js
114
+ - test/sinatra/app/assets/stylesheets/custom/global.css
115
+ - test/sinatra/app/assets/stylesheets/custom/home.css
116
+ - test/sinatra/app/assets/stylesheets/custom/search.css
117
+ - test/sinatra/app/assets/stylesheets/third-party/widget.css
118
+ - test/sinatra/app/i18n/en.yml
119
+ - test/sinatra/config/pubba.yml
120
+ - test/sinatra/public/javascripts/_
121
+ - test/sinatra/public/stylesheets/_
122
+ homepage: http://github.com/stonean/pubba
123
+ licenses: []
124
+ post_install_message:
125
+ rdoc_options:
126
+ - --charset=UTF-8
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ none: false
131
+ requirements:
132
+ - - ! '>='
133
+ - !ruby/object:Gem::Version
134
+ version: '0'
135
+ required_rubygems_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ requirements: []
142
+ rubyforge_project: pubba
143
+ rubygems_version: 1.8.10
144
+ signing_key:
145
+ specification_version: 3
146
+ summary: Pubba is a Sinatra extension.
147
+ test_files: []
148
+ has_rdoc: