Permalink
Browse files

inital outsourced from salesking

  • Loading branch information...
0 parents commit 4f284c3b4d6ad9db68e0b49fe9ce9ca6d8a36b2e @schorsch schorsch committed Jul 27, 2012
Showing with 621 additions and 0 deletions.
  1. +17 −0 .gitignore
  2. +3 −0 Gemfile
  3. +22 −0 LICENSE
  4. +29 −0 README.md
  5. +9 −0 Rakefile
  6. +30 −0 king_placeholder.gemspec
  7. +117 −0 lib/king_placeholder.rb
  8. +204 −0 lib/king_placeholder/parse_context.rb
  9. +3 −0 lib/king_placeholder/version.rb
  10. +166 −0 spec/king_placeholder_spec.rb
  11. +21 −0 spec/spec_helper.rb
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+Gemfile.lock
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+gem 'king_views', :git => 'https://github.com/salesking/king_views.git', :branch => 'develop'
+gemspec
22 LICENSE
@@ -0,0 +1,22 @@
+Copyright (c) 2012 Georg Leciejewski
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
+# KingPlaceholder
+
+TODO: Write a gem description
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+ gem 'king_placeholder'
+
+And then execute:
+
+ $ bundle
+
+Or install it yourself as:
+
+ $ gem install king_placeholder
+
+## Usage
+
+TODO: Write usage instructions here
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Added some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
@@ -0,0 +1,9 @@
+#!/usr/bin/env rake
+require 'bundler/gem_tasks'
+require 'rspec'
+require 'rspec/core/rake_task'
+require 'rdoc/task'
+
+desc "Run specs"
+RSpec::Core::RakeTask.new
+task :default => :spec
@@ -0,0 +1,30 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/king_placeholder/version', __FILE__)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Georg Leciejewski"]
+ gem.email = ["gl@salesking.eu"]
+ gem.description = %q{}
+ gem.summary = %q{Placeholder Parsing in Strings}
+ gem.homepage = 'https://github.com/salesking/king_placeholder.git'
+
+ gem.files = `git ls-files`.split($\)
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
+ gem.name = "king_placeholder"
+ gem.require_paths = ["lib"]
+ gem.version = KingPlaceholder::VERSION
+
+ gem.add_runtime_dependency 'statemachine'
+ gem.add_runtime_dependency 'i18n'
+ gem.add_runtime_dependency 'activesupport'
+ gem.add_runtime_dependency 'actionpack'
+ #gem.add_runtime_dependency 'actionview'
+ #gem.add_runtime_dependency 'king_views'
+
+ gem.add_development_dependency 'activerecord'
+ gem.add_development_dependency 'rdoc'
+ gem.add_development_dependency 'rspec'
+ gem.add_development_dependency 'simplecov'
+ gem.add_development_dependency 'rake', '>= 0.9.2'
+end
@@ -0,0 +1,117 @@
+# Define fields/methods of the including class as placeholders.
+# A Placeholder can be used inside any text string and will be replaced with a
+# stringified, formatted value(by KingViews gem => KingFormat::FormattingHelper.strfval )
+# Used for text snippets, PDF creation or E-Mail templates.
+require 'active_support'
+require 'active_support/version'
+require 'action_view' # king_views related suxs
+require 'action_controller' # king_views
+require 'king_views'
+
+module KingPlaceholder
+
+ # sets :placeholders and init Class.placeholders as emtpy array on inclusion
+ def self.included(base)
+ if ActiveSupport::VERSION::MAJOR == 3 && ActiveSupport::VERSION::MINOR > 0
+ base.class_attribute :placeholders
+ else
+ base.send :class_inheritable_accessor, :placeholders
+ end
+ base.placeholders = []
+ base.extend(ClassMethods)
+ end
+
+ module ClassMethods
+
+ # Defines the fields returned by self.placeholders.
+ # Sets self.publish if empty.
+ # ==== Parameter
+ # fieldnames<Array[Symbol]>:: the names of the fields which are available
+ # throught the placeholder methods
+ def has_placeholders(*fieldnames)
+ self.placeholders = fieldnames
+ include InstanceMethods
+ end
+ end #ClassMethods
+
+ module InstanceMethods
+
+ # Check if a given field is declared as placeholder
+ # TODO check usage and/or move to class methods
+ # ==== Parameter
+ # fieldname<String|Symbol>:: the field to search in the placeholders array
+ # ==== Returns
+ # <Boolean>:: true if in
+ def is_placeholder?(fieldname)
+ self.class.placeholders.include?(fieldname.to_sym)
+ end
+
+ # Substitute placeholder in a string with their current values.
+ # It handles strings, arrays (of strings) or hashes (with string values)
+ # and returns data with the same data type e.g. if you put a hash, you will
+ # get a hash.
+ #
+ # ==== Examples
+ #
+ # Placeholders in text strings can be written in different notations.
+ #
+ # ===== Simple Notation:
+ #
+ # => [first_name]
+ # The fieldname is directly looked up on the current class:
+ # client.expand_placeholders("Hello [first_name]")
+ # => "Hello Herbert"
+ # invoice.expand_placeholders(["You owe me [price_to_pay]", "Invoice Nr. [number]"])
+ # => ["You owe me 495,00 EUR", "Invoice Nr. 123"]
+ #
+ # ===== Namespaced Notation
+ #
+ # => [company.organisation]
+ # If the prefix equals the type of the current object the field is looked up on it.
+ # client.expand_placeholders("Hello [client.first_name]")
+ # => "Hello Herbert"
+ #
+ # If the prefix is a single related object => Client :belongs_to Company,
+ # the substitution is delegated to that class.
+ # client.expand_placeholders("Belongs to [company.name]")
+ # => ""Belongs to Big Money Coorp."
+ # It goes down all the way:
+ # invoice.expand_placeholders("[client.company.default_address.zip]")
+ # => "50999"
+ #
+ # ===== Namespaced Notation with multiple related objects
+ #
+ # In a has_many relationship, related objects reside in an array, which can
+ # be reached using two different strategies.
+ #
+ # Access and Iterate over the whole Group:
+ # invoice.expand_placeholders("You bought: [items] [name] [/items]")
+ # => "You bought: Apple Banana Orange"
+ #
+ # Access a single object by its array index:
+ # invoice.expand_placeholders("You bought an [items.0.name] for [items.0.price]")
+ # => "You bought an Apple for 12 EUR"
+ #
+ # === Parameter
+ # content<Hash,Array, String>:: Collection, Hash or single string containing
+ # placeholders
+ # === Returns
+ # <Hash,Array, String>:: whatever type you threw in is also returned
+ def expand_placeholders(content, opts={})
+ if content.is_a?(Array) # Expand all array elements and go recursive
+ result = []
+ content.each{|element| result << self.expand_placeholders(element, opts) }
+ return result
+ elsif content.is_a?(Hash) # Expand all hash elements and go recursive
+ result = {}
+ content.each_pair{ |key,val| result[key] = self.expand_placeholders(val, opts) }
+ return result
+ else # Only proceed with strings
+ return content unless content.is_a?(String)
+ end
+ parser = ParseContext.new(self, content, opts)
+ parser.sm.match
+ parser.result if parser.sm.state == :finished
+ end
+ end # instance methods
+end # KingPlaceholders
Oops, something went wrong.

0 comments on commit 4f284c3

Please sign in to comment.