snippr 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/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+ == 0.1.0 (2010-04-30)
2
+ * Initial version.
data/README.rdoc ADDED
@@ -0,0 +1,62 @@
1
+ = Snippr
2
+ ==== File based content management
3
+
4
+ A snippr is a piece of HTML to be included in a website. They are plain text
5
+ files stored on the file system.
6
+
7
+ == Snippr path
8
+
9
+ You need to specify the path to the snippr directory:
10
+
11
+ Snippr.path = File.join(File.dirname(__FILE__), "..", "snippr")
12
+
13
+ When running on JRuby, you can also set the path via JVM properties. The property
14
+ you need to specify is defined in +SnipprPath::JVMProperty+. This allows system
15
+ administrators to change the path without having to touch your application.
16
+
17
+ == Instantiation
18
+
19
+ Instantiating a new snippr is done by passing in the path to the snippr file as
20
+ a String (including path separators):
21
+
22
+ Snippr.new "tariff/einheit"
23
+
24
+ or by using multiple Strings or Symbols:
25
+
26
+ Snippr.new :tariff, :einheit
27
+
28
+ === Dynamic values
29
+
30
+ A snippr may contain placeholders to be replaced with dynamic values. Placeholders
31
+ are wrapped in curly braces.
32
+
33
+ <p>You're topup of {topup_amount} at {date_today} was successful.</p>
34
+
35
+ To replace both {topup_amount} and {date_today} with a dynamic value, you just pass
36
+ in a Hash of placeholders and dynamic values when instantiating a new snippr.
37
+
38
+ Snippr.new :topup, :success, :topup_amount => number_to_currency(15), :date_today => Date.today
39
+
40
+ The result will obviously be something like:
41
+
42
+ <p>You're topup of 15,00 &euro; at 2010-04-03 was successful.</p>
43
+
44
+ == Links
45
+
46
+ ...
47
+
48
+ == Snippr content
49
+
50
+ Returning the snippr content is done by calling the +to_s+ method. This will replace
51
+ all specified placeholders and links.
52
+
53
+ Snippr.new(:tariff, :einheit).to_s
54
+
55
+ == Rails Helper
56
+
57
+ When using the Snippr component with Rails, it automatically adds the +SnipprHelper+
58
+ module to your views. You can then use the +snippr+ helper method to load snippr files.
59
+
60
+ %h1 Topup successful
61
+ .topup.info
62
+ = snippr :topup, :success
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "rake"
2
+ require "spec/rake/spectask"
3
+ require "spec/rake/verify_rcov"
4
+
5
+ task :default => :spec
6
+
7
+ Spec::Rake::SpecTask.new do |t|
8
+ # t.rcov = true
9
+ # t.rcov_opts = %w(--exclude-only ^\/User,spec\/)
10
+ end
11
+
12
+ namespace :spec do
13
+ RCov::VerifyTask.new(:rcov => :spec) do |t|
14
+ t.threshold = 90
15
+ t.index_html = "coverage/index.html"
16
+ end
17
+ end
18
+
19
+ begin
20
+ require "hanna/rdoctask"
21
+
22
+ Rake::RDocTask.new do |t|
23
+ t.title = "Snippr - File based content management"
24
+ t.rdoc_dir = "doc"
25
+ t.rdoc_files.include("**/*.rdoc").include("lib/**/*.rb")
26
+ t.options << "--line-numbers"
27
+ t.options << "--webcvs=http://github.com/blaulabs/snippr/tree/master/"
28
+ end
29
+ rescue LoadError
30
+ puts "'gem install hanna' for documentation"
31
+ end
@@ -0,0 +1,12 @@
1
+ class String
2
+
3
+ # Returns the String in lowerCamelCase.
4
+ def lower_camelcase
5
+ str = dup
6
+ str.gsub!(/\/(.?)/) { "::#{$1.upcase}" }
7
+ str.gsub!(/(?:_+|-+)([a-z])/) { $1.upcase }
8
+ str.gsub!(/(\A|\s)([A-Z])/) { $1 + $2.downcase }
9
+ str
10
+ end
11
+
12
+ end
@@ -0,0 +1,114 @@
1
+ # = Snippr
2
+ # ==== File based content management
3
+ #
4
+ # A snippr is a piece of HTML to be included in a website. They are plain text
5
+ # files stored on the file system.
6
+ #
7
+ # == Snippr path
8
+ #
9
+ # You need to specify the path to the snippr directory:
10
+ #
11
+ # Snippr.path = File.join(File.dirname(__FILE__), "..", "snipprs")
12
+ #
13
+ # When running on JRuby, you can also set the path via JVM properties. The property
14
+ # you need to specify is defined in +SnipprPath::JVMProperty+. This allows system
15
+ # administrators to change the path without having to touch your application.
16
+ #
17
+ # == Instantiation
18
+ #
19
+ # Instantiating a new snippr is done by passing in the path to the snippr file as
20
+ # a String (including path separators):
21
+ #
22
+ # Snippr.new "tariff/einheit"
23
+ #
24
+ # or by using multiple Strings or Symbols:
25
+ #
26
+ # Snippr.new :tariff, :einheit
27
+ #
28
+ # === Dynamic values
29
+ #
30
+ # A snippr may contain placeholders to be replaced with dynamic values. Placeholders
31
+ # are wrapped in curly braces.
32
+ #
33
+ # <p>You're topup of {topup_amount} at {date_today} was successful.</p>
34
+ #
35
+ # To replace both {topup_amount} and {date_today} with a dynamic value, you just pass
36
+ # in a Hash of placeholders and dynamic values when instantiating a new snippr.
37
+ #
38
+ # Snippr.new :topup, :success, :topup_amount => number_to_currency(15), :date_today => Date.today
39
+ #
40
+ # The result will obviously be something like:
41
+ #
42
+ # <p>You're topup of 15,00 &euro; at 2010-04-03 was successful.</p>
43
+ #
44
+ # == Links
45
+ #
46
+ # ...
47
+ #
48
+ # == Snippr content
49
+ #
50
+ # Returning the snippr content is done by calling the +to_s+ method. This will replace
51
+ # all specified placeholders and links.
52
+ #
53
+ # Snippr.new(:tariff, :einheit).to_s
54
+ #
55
+ # == Rails Helper
56
+ #
57
+ # When using the Snippr component with Rails, it automatically adds the +SnipprHelper+
58
+ # module to your views. You can then use the +snippr+ helper method to load snippr files.
59
+ #
60
+ # %h1 Topup successful
61
+ # .topup.info
62
+ # = snippr :topup, :success
63
+ class Snippr
64
+ extend SnipprPath
65
+
66
+ # The snippr file extension.
67
+ SnipprFileExtension = ".snip"
68
+
69
+ # The comments wrapping a snippr.
70
+ SnipprWrapper = "<!-- starting with snippr: %s -->\n%s\n<!-- ending with snippr: %s -->"
71
+
72
+ # The fallback for a missing snippr.
73
+ MissingSnippr = '<samp class="missing snippr" />'
74
+
75
+ # Expects the paths to a snippr. Also accepts a Hash of placeholders
76
+ # to be replaced with dynamic values.
77
+ def initialize(*args)
78
+ @dynamic_values = args.last.kind_of?(Hash) ? args.pop : {}
79
+ @snippr_name = args.map { |arg| arg.kind_of?(Symbol) ? arg.to_s.lower_camelcase : arg }.join("/")
80
+ end
81
+
82
+ # Returns the snippr content.
83
+ def to_s
84
+ wrap_in_comments { snippr }
85
+ end
86
+
87
+ private
88
+
89
+ # Returns the raw snippr content or a +MissingSnippr+ tag in case
90
+ # the snippr file does not exist.
91
+ def snippr
92
+ return MissingSnippr unless File.exist? snippr_file
93
+
94
+ snippr = File.read(snippr_file).strip
95
+ insert_dynamic_values snippr
96
+ snippr
97
+ end
98
+
99
+ # Replaces placeholders with dynamic values.
100
+ def insert_dynamic_values(snippr)
101
+ @dynamic_values.each { |placeholder, value| snippr.gsub! "{#{placeholder}}", value.to_s }
102
+ end
103
+
104
+ # Returns the complete path to a snippr file.
105
+ def snippr_file
106
+ File.join self.class.path, "#{@snippr_name}#{SnipprFileExtension}"
107
+ end
108
+
109
+ # Wraps the content from a given +block+ in descriptive comments.
110
+ def wrap_in_comments
111
+ SnipprWrapper % [@snippr_name, yield, @snippr_name]
112
+ end
113
+
114
+ end
@@ -0,0 +1,20 @@
1
+ # = SnipprHelper
2
+ #
3
+ # This module is automatically included into +ActionView::Base+ when using the Snippr
4
+ # component with Rails. It provides a +snippr+ helper method for loading snipprs.
5
+ #
6
+ # %h1 Topup successful
7
+ # .topup.info
8
+ # = snippr :topup, :success
9
+ module SnipprHelper
10
+
11
+ # Returns a snippr specified via +args+.
12
+ def snippr(*args)
13
+ Snippr.new(*args).to_s
14
+ end
15
+
16
+ end
17
+
18
+ if defined? ActionView::Base
19
+ ActionView::Base.send :include, SnipprHelper
20
+ end
@@ -0,0 +1,38 @@
1
+ # = SnipprPath
2
+ #
3
+ # This module is included into the Snippr component for retrieving and setting
4
+ # the path to the snippr files.
5
+ module SnipprPath
6
+
7
+ # The snippr path JVM property.
8
+ JVMProperty = "cms.snippet.path"
9
+
10
+ # Returns the snippr path from JVM properties.
11
+ def path
12
+ JavaLang::System.get_property(JVMProperty) rescue @path
13
+ end
14
+
15
+ # Sets the snippr path as a JVM property.
16
+ def path=(path)
17
+ path = path.to_s
18
+ raise ArgumentError, "Invalid path: #{path}" unless File.directory? path
19
+ JavaLang::System.set_property(JVMProperty, path) if jruby?
20
+ @path = path
21
+ end
22
+
23
+ private
24
+
25
+ # Returns whether the current Ruby platform is JRuby.
26
+ def jruby?
27
+ RUBY_PLATFORM =~ /java/
28
+ end
29
+
30
+ module_function :jruby?
31
+
32
+ if jruby?
33
+ module JavaLang
34
+ include_package "java.lang"
35
+ end
36
+ end
37
+
38
+ end
data/lib/snippr.rb ADDED
@@ -0,0 +1,4 @@
1
+ require "snippr/core_ext"
2
+ require "snippr/snippr_path"
3
+ require "snippr/snippr_helper"
4
+ require "snippr/snippr"
@@ -0,0 +1 @@
1
+ <p>Home</p>
@@ -0,0 +1 @@
1
+ <p>tariff: einheit</p>
@@ -0,0 +1 @@
1
+ <p>Some error occurred.</p>
@@ -0,0 +1 @@
1
+ <p>You're topup of {topup_amount} at {date_today} was successful.</p>
@@ -0,0 +1,11 @@
1
+ require "spec_helper"
2
+
3
+ describe String do
4
+
5
+ describe "lower_camelcase" do
6
+ it "converts a snakecase String to lowerCamelCase" do
7
+ "lower_camel_case".lower_camelcase.should == "lowerCamelCase"
8
+ end
9
+ end
10
+
11
+ end
@@ -0,0 +1,53 @@
1
+ require "spec_helper"
2
+
3
+ describe Snippr do
4
+ before :all do
5
+ snippr_path = File.join File.dirname(__FILE__), "..", "fixtures"
6
+
7
+ if RUBY_PLATFORM =~ /java/
8
+ SnipprPath::JavaLang::System.set_property SnipprPath::JVMProperty, snippr_path
9
+ else
10
+ Snippr.path = snippr_path
11
+ end
12
+ end
13
+
14
+ it "should return the content of a snippr" do
15
+ Snippr.new(:home).to_s.should include("<p>Home</p>")
16
+ end
17
+
18
+ it "should return the content a snippr from a subfolder" do
19
+ Snippr.new("tariff/einheit").to_s.should include("<p>tariff: einheit</p>")
20
+ end
21
+
22
+ it "should return the content a snippr from a subfolder specified via multiple arguments" do
23
+ Snippr.new(:tariff, :einheit).to_s.should include("<p>tariff: einheit</p>")
24
+ end
25
+
26
+ it "should convert snake_case Symbols to lowerCamelCase Strings" do
27
+ Snippr.new(:topup, :some_error).to_s.should include("<p>Some error occurred.</p>")
28
+ end
29
+
30
+ it "should wrap the snippr in descriptive comments" do
31
+ Snippr.new(:home).to_s.should ==
32
+ "<!-- starting with snippr: home -->\n" <<
33
+ "<p>Home</p>\n" <<
34
+ "<!-- ending with snippr: home -->"
35
+ end
36
+
37
+ it "should replace placeholders with dynamic values" do
38
+ snippr = Snippr.new :topup, :success, :topup_amount => "15,00 &euro;", :date_today => Date.today
39
+ snippr.to_s.should include("<p>You're topup of 15,00 &euro; at #{Date.today} was successful.</p>")
40
+ end
41
+
42
+ it "should return a fallback wrapped in descriptive comments for missing snipprs" do
43
+ Snippr.new(:doesnotexist).to_s.should ==
44
+ "<!-- starting with snippr: doesnotexist -->\n" <<
45
+ "<samp class=\"missing snippr\" />\n" <<
46
+ "<!-- ending with snippr: doesnotexist -->"
47
+ end
48
+
49
+ it "should raise an ArgumentError if the +path+ does not exist" do
50
+ lambda { Snippr.path = "does_not_exist" }.should raise_exception(ArgumentError)
51
+ end
52
+
53
+ end
@@ -0,0 +1,4 @@
1
+ require "spec"
2
+ require "date"
3
+
4
+ require "snippr"
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: snippr
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Daniel Harrington
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-30 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 8
31
+ version: 1.2.8
32
+ type: :development
33
+ version_requirements: *id001
34
+ description:
35
+ email: me@rubiii.com
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - README.rdoc
42
+ files:
43
+ - CHANGELOG
44
+ - Rakefile
45
+ - README.rdoc
46
+ - lib/snippr/core_ext.rb
47
+ - lib/snippr/snippr.rb
48
+ - lib/snippr/snippr_helper.rb
49
+ - lib/snippr/snippr_path.rb
50
+ - lib/snippr.rb
51
+ - spec/snippr/core_ext_spec.rb
52
+ - spec/snippr/snippr_spec.rb
53
+ - spec/spec_helper.rb
54
+ - spec/fixtures/home.snip
55
+ - spec/fixtures/tariff/einheit.snip
56
+ - spec/fixtures/topup/someError.snip
57
+ - spec/fixtures/topup/success.snip
58
+ has_rdoc: true
59
+ homepage: http://github.com/blaulabs/snippr
60
+ licenses: []
61
+
62
+ post_install_message:
63
+ rdoc_options:
64
+ - --charset=UTF-8
65
+ - --line-numbers
66
+ - --inline-source
67
+ - --title
68
+ - Snippr - File based content management
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.3.6
89
+ signing_key:
90
+ specification_version: 3
91
+ summary: File based content management
92
+ test_files:
93
+ - spec/snippr/core_ext_spec.rb
94
+ - spec/snippr/snippr_spec.rb
95
+ - spec/spec_helper.rb