├── .rspec ├── examples ├── app_no_underscores │ ├── views │ │ ├── magic.haml │ │ ├── news.haml │ │ ├── meta.haml │ │ ├── home.haml │ │ ├── locality.haml │ │ └── layout.haml │ ├── config.rb │ ├── config.ru │ └── app.rb ├── app_no_underscores_and_slim │ ├── views │ │ ├── magic.slim │ │ ├── news.slim │ │ ├── home.slim │ │ ├── meta.slim │ │ ├── locality.slim │ │ └── layout.slim │ ├── config.rb │ ├── config.ru │ └── app.rb ├── app_with_underscores │ ├── views │ │ ├── _magic.haml │ │ ├── _news.haml │ │ ├── _meta.haml │ │ ├── home.haml │ │ ├── _locality.haml │ │ └── layout.haml │ ├── config.rb │ ├── config.ru │ └── app.rb ├── app_with_underscores_and_erb │ ├── views │ │ ├── _magic.erb │ │ ├── _meta.erb │ │ ├── home.erb │ │ ├── _news.erb │ │ ├── _locality.erb │ │ └── layout.erb │ ├── config.rb │ ├── config.ru │ └── app.rb ├── app_with_underscores_and_erb_and_subdirs │ ├── views │ │ ├── partials │ │ │ ├── _magic.erb │ │ │ ├── _meta.erb │ │ │ ├── _news.erb │ │ │ └── _locality.erb │ │ ├── home.erb │ │ └── layout.erb │ ├── config.rb │ ├── config.ru │ └── app.rb ├── ext │ └── kernel.rb └── whitespace_remove.rb ├── lib └── sinatra │ ├── partial │ └── version.rb │ └── partial.rb ├── .gitignore ├── .travis.yml ├── Gemfile ├── spec ├── sinatra_partial_helpers_spec.rb ├── spec_helper.rb ├── sinatra_partial_private_spec.rb └── examples_spec.rb ├── sinatra-partial.gemspec ├── Rakefile ├── LICENCE.txt ├── CHANGES.markdown └── README.markdown /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | -------------------------------------------------------------------------------- /examples/app_no_underscores/views/magic.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Show me magic! -------------------------------------------------------------------------------- /examples/app_no_underscores/views/news.haml: -------------------------------------------------------------------------------- 1 | %li{ klass } 2 | = news -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/magic.slim: -------------------------------------------------------------------------------- 1 | p Show me magic! -------------------------------------------------------------------------------- /examples/app_with_underscores/views/_magic.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Show me magic! -------------------------------------------------------------------------------- /examples/app_with_underscores/views/_news.haml: -------------------------------------------------------------------------------- 1 | %li{ klass } 2 | = news -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/news.slim: -------------------------------------------------------------------------------- 1 | li{*klass} 2 | = news -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/_magic.erb: -------------------------------------------------------------------------------- 1 |

Show me magic!

-------------------------------------------------------------------------------- /examples/app_no_underscores/views/meta.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Time is #{Time.now.localtime} -------------------------------------------------------------------------------- /examples/app_no_underscores/views/home.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Hello, World 3 | 4 | #{show_me_magic} -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/home.slim: -------------------------------------------------------------------------------- 1 | p Hello, World 2 | == show_me_magic 3 | -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/meta.slim: -------------------------------------------------------------------------------- 1 | p 2 | | Time is #{Time.now.localtime} -------------------------------------------------------------------------------- /examples/app_with_underscores/views/_meta.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Time is #{Time.now.localtime} 3 | -------------------------------------------------------------------------------- /examples/app_with_underscores/views/home.haml: -------------------------------------------------------------------------------- 1 | %p 2 | Hello, World 3 | #{show_me_magic} 4 | -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/partials/_magic.erb: -------------------------------------------------------------------------------- 1 |

Show me magic!

-------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/_meta.erb: -------------------------------------------------------------------------------- 1 |

2 | Time is <%= Time.now.localtime %> 3 |

-------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/home.erb: -------------------------------------------------------------------------------- 1 |

2 | Hello, World 3 |

4 | <%= show_me_magic %> -------------------------------------------------------------------------------- /lib/sinatra/partial/version.rb: -------------------------------------------------------------------------------- 1 | module Sinatra 2 | module Partial 3 | VERSION = "1.0.1" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/home.erb: -------------------------------------------------------------------------------- 1 |

2 | Hello, World 3 |

4 | <%= show_me_magic %> -------------------------------------------------------------------------------- /examples/app_no_underscores/views/locality.haml: -------------------------------------------------------------------------------- 1 | %p= "A is #{a}" 2 | %p= "B is #{b}" 3 | %p= "C is #{c}" 4 | %p= "D is #{d}" -------------------------------------------------------------------------------- /examples/app_with_underscores/views/_locality.haml: -------------------------------------------------------------------------------- 1 | %p= "A is #{a}" 2 | %p= "B is #{b}" 3 | %p= "C is #{c}" 4 | %p= "D is #{d}" -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/partials/_meta.erb: -------------------------------------------------------------------------------- 1 |

2 | Time is <%= Time.now.localtime %> 3 |

-------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/locality.slim: -------------------------------------------------------------------------------- 1 | p= "A is #{a}" 2 | p= "B is #{b}" 3 | p= "C is #{c}" 4 | p= "D is #{d}" -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/_news.erb: -------------------------------------------------------------------------------- 1 |
  • > 2 | <%= news %> 3 |
  • -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/_locality.erb: -------------------------------------------------------------------------------- 1 |

    A is <%= a %>

    2 |

    B is <%= b %>

    3 |

    C is <%= c %>

    4 |

    D is <%= d %>

    -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/partials/_news.erb: -------------------------------------------------------------------------------- 1 |
  • > 2 | <%= news %> 3 |
  • -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/partials/_locality.erb: -------------------------------------------------------------------------------- 1 |

    A is <%= a %>

    2 |

    B is <%= b %>

    3 |

    C is <%= c %>

    4 |

    D is <%= d %>

    -------------------------------------------------------------------------------- /examples/ext/kernel.rb: -------------------------------------------------------------------------------- 1 | unless Kernel.respond_to?(:require_relative) 2 | module Kernel 3 | def require_relative(path) 4 | require File.join(File.dirname(caller[0]), path.to_str) 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /examples/app_no_underscores/config.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module AppNoUnderscores 4 | 5 | require_relative "./app.rb" 6 | 7 | def self.app 8 | Rack::Builder.app do 9 | run App 10 | end 11 | end # self.app 12 | 13 | end -------------------------------------------------------------------------------- /examples/app_with_underscores/config.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module AppWithUnderscores 4 | 5 | require_relative "./app.rb" 6 | 7 | def self.app 8 | Rack::Builder.app do 9 | run App 10 | end 11 | end # self.app 12 | 13 | end -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/config.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module AppNoUnderscoresAndSlim 4 | 5 | require_relative "./app.rb" 6 | 7 | def self.app 8 | Rack::Builder.app do 9 | run App 10 | end 11 | end # self.app 12 | 13 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/config.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module AppWithUnderscoresAndErb 4 | 5 | require_relative "./app.rb" 6 | 7 | def self.app 8 | Rack::Builder.app do 9 | run App 10 | end 11 | end # self.app 12 | 13 | end -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .rvmrc 3 | *.tmproj 4 | key 5 | log/ 6 | files/ 7 | thin/ 8 | .sass-cache/ 9 | run/ 10 | app/.sass-cache/ 11 | *.gem 12 | .bundle/ 13 | Gemfile.lock 14 | vendor/ 15 | vendor.noindex/ 16 | .yardoc/ 17 | bin/ 18 | docs/ 19 | coverage/ 20 | .rbx/ 21 | -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/config.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module AppWithUnderscoresAndErbAndSubdirs 4 | 5 | require_relative "./app.rb" 6 | 7 | def self.app 8 | Rack::Builder.app do 9 | run App 10 | end 11 | end # self.app 12 | 13 | end -------------------------------------------------------------------------------- /examples/app_no_underscores/views/layout.haml: -------------------------------------------------------------------------------- 1 | %html 2 | %head 3 | %body 4 | = partial :meta 5 | 6 | %ul 7 | = partial :news, :collection => settings.news, :locals => {:klass => {:class => "klassic"}} 8 | 9 | = partial :locality, :locals => Hash[%w{a b c d}.zip(%w{A B C D})] 10 | 11 | = yield -------------------------------------------------------------------------------- /examples/app_with_underscores/views/layout.haml: -------------------------------------------------------------------------------- 1 | %html 2 | %head 3 | %body 4 | = partial :meta 5 | 6 | %ul 7 | = partial :news, :collection => settings.news, :locals => {:klass => {:class => "klassic"}} 8 | 9 | = partial :locality, :locals => Hash[%w{a b c d}.zip(%w{A B C D})] 10 | 11 | = yield -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/views/layout.slim: -------------------------------------------------------------------------------- 1 | html 2 | head 3 | body 4 | == partial :meta 5 | 6 | ul 7 | == partial :news, :collection => settings.news, :locals => {:klass => {:class => "klassic"}} 8 | 9 | == partial :locality, :locals => Hash[%w{a b c d}.zip(%w{A B C D})] 10 | 11 | == yield -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.0.0 4 | - 2.1.0 5 | - 2.2.2 6 | - jruby-19mode # JRuby in 1.9 mode 7 | - rbx 8 | - ruby-head 9 | - jruby-head 10 | 11 | # whitelist 12 | branches: 13 | only: 14 | - master 15 | - develop 16 | 17 | matrix: 18 | allow_failures: 19 | - rvm: jruby-head 20 | - rvm: ruby-head 21 | - rvm: rbx -------------------------------------------------------------------------------- /examples/app_no_underscores/config.ru: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | root = File.expand_path File.dirname(__FILE__) 8 | require File.join( root , "./config.rb" ) 9 | 10 | # everything else separate module/file (config.rb) to make it easier to set up tests 11 | 12 | map "/" do 13 | run AppNoUnderscores.app 14 | end -------------------------------------------------------------------------------- /examples/app_with_underscores/config.ru: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | root = File.expand_path File.dirname(__FILE__) 8 | require File.join( root , "./config.rb" ) 9 | 10 | # everything else separate module/file (config.rb) to make it easier to set up tests 11 | 12 | map "/" do 13 | run AppWithUnderscores.app 14 | end -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/config.ru: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | root = File.expand_path File.dirname(__FILE__) 8 | require File.join( root , "./config.rb" ) 9 | 10 | # everything else separate module/file (config.rb) to make it easier to set up tests 11 | 12 | map "/" do 13 | run AppNoUnderscoresAndSlim.app 14 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/config.ru: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | root = File.expand_path File.dirname(__FILE__) 8 | require File.join( root , "./config.rb" ) 9 | 10 | # everything else separate module/file (config.rb) to make it easier to set up tests 11 | 12 | map "/" do 13 | run AppWithUnderscoresAndErb.app 14 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/views/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= partial :meta %> 5 | 6 | 9 | 10 | <%= partial( :locality, :locals => Hash[%w{a b c d}.zip(%w{A B C D})]) %> 11 | 12 | <%= yield %> 13 | 14 | -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/config.ru: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rubygems' 4 | require 'bundler' 5 | Bundler.require 6 | 7 | root = File.expand_path File.dirname(__FILE__) 8 | require File.join( root , "./config.rb" ) 9 | 10 | # everything else separate module/file (config.rb) to make it easier to set up tests 11 | 12 | map "/" do 13 | run AppWithUnderscoresAndErbAndSubdirs.app 14 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/views/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <%= partial :"partials/meta" %> 5 | 6 | 9 | 10 | <%= partial( :"partials/locality", :locals => Hash[%w{a b c d}.zip(%w{A B C D})]) %> 11 | 12 | <%= yield %> 13 | 14 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gemspec 4 | 5 | gem "rake" 6 | 7 | group :development do 8 | unless RUBY_ENGINE == 'jruby' || RUBY_ENGINE == "rbx" 9 | gem "pry-byebug" 10 | end 11 | gem "maruku" 12 | gem "yard" 13 | gem "travis-lint" 14 | end 15 | 16 | gem "sinatra", ">=2.0.0" 17 | 18 | group :test do 19 | gem "rack-test" 20 | gem "rspec" 21 | gem "rspec-its" 22 | gem "simplecov" 23 | gem "haml" 24 | gem 'timecop' 25 | gem "slim" 26 | end 27 | -------------------------------------------------------------------------------- /examples/app_no_underscores/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'haml' 3 | require File.expand_path( File.join File.dirname(__FILE__), "../ext/kernel.rb") 4 | require_relative "../../lib/sinatra/partial.rb" 5 | require_relative "../whitespace_remove.rb" 6 | 7 | module AppNoUnderscores 8 | class App < Sinatra::Base 9 | register Sinatra::Partial 10 | use WhiteSpaceRemove 11 | 12 | configure do 13 | set :news, ["This", "is", "all", "new"] 14 | end 15 | 16 | 17 | get "/" do 18 | magic = partial :magic 19 | haml :home, :locals => { :show_me_magic => magic } 20 | end 21 | end 22 | end -------------------------------------------------------------------------------- /examples/app_with_underscores/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'haml' 3 | require File.expand_path( File.join File.dirname(__FILE__), "../ext/kernel.rb") 4 | require_relative "../../lib/sinatra/partial.rb" 5 | require_relative "../whitespace_remove.rb" 6 | 7 | module AppWithUnderscores 8 | class App < Sinatra::Base 9 | register Sinatra::Partial 10 | use WhiteSpaceRemove 11 | 12 | configure do 13 | set :news, ["This", "is", "all", "new"] 14 | end 15 | 16 | set :partial_underscores, true 17 | 18 | 19 | get "/" do 20 | magic = partial :magic 21 | haml :home, :locals => { :show_me_magic => magic } 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /examples/whitespace_remove.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | ## Here to strip out whitespace, because ERB (can you believe it?) doesn't use whitespace well. Many thanks to http://stackoverflow.com/questions/8827845/how-do-i-strip-html-whitespace-in-erb-templates#answer-8828830 4 | class WhiteSpaceRemove 5 | def initialize(app, options = {}) 6 | @app = app 7 | end 8 | 9 | def call(env) 10 | status, headers, response = @app.call(env) 11 | 12 | if headers["Content-Type"] =~ /\bhtml\b/ 13 | response[0] = response[0].gsub(/\s*(<[^>]+>)\s*/, '\1') 14 | headers["Content-Length"] = response[0].size.to_s 15 | end 16 | 17 | [status, headers, response] 18 | end 19 | end -------------------------------------------------------------------------------- /examples/app_no_underscores_and_slim/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'slim' 3 | require File.expand_path( File.join File.dirname(__FILE__), "../ext/kernel.rb") 4 | require_relative "../../lib/sinatra/partial.rb" 5 | require_relative "../whitespace_remove.rb" 6 | 7 | module AppNoUnderscoresAndSlim 8 | class App < Sinatra::Base 9 | register Sinatra::Partial 10 | use WhiteSpaceRemove 11 | 12 | configure do 13 | set :news, ["This", "is", "all", "new"] 14 | set :partial_template_engine, :slim 15 | end 16 | 17 | 18 | get "/" do 19 | magic = partial :magic 20 | slim :home, :locals => { :show_me_magic => magic } 21 | end 22 | end 23 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'erb' 3 | require File.expand_path( File.join File.dirname(__FILE__), "../ext/kernel.rb") 4 | require_relative "../../lib/sinatra/partial.rb" 5 | require_relative "../whitespace_remove.rb" 6 | 7 | module AppWithUnderscoresAndErb 8 | class App < Sinatra::Base 9 | register Sinatra::Partial 10 | use WhiteSpaceRemove 11 | 12 | configure do 13 | set :news, ["This", "is", "all", "new"] 14 | end 15 | 16 | enable :partial_underscores 17 | set :partial_template_engine, :erb 18 | 19 | get "/" do 20 | magic = partial :magic 21 | erb :home, :locals => { :show_me_magic => magic } 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /spec/sinatra_partial_helpers_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require "spec_helper" 4 | require_relative "../lib/sinatra/partial.rb" 5 | 6 | 7 | describe "Helpers::partial" do 8 | 9 | engines = [:haml, :erb] 10 | underscores = [true, false] 11 | partials = ["news", "meta/news"] 12 | engines.product(underscores).product(partials).map{|x| x.flatten}.each do |(engine, underscore, partial)| 13 | context "Engine: #{engine} Underscores: #{underscore}, Partial: #{partial}" do 14 | let(:settings) { OpenStruct.new({:partial_template_engine => engine, :underscores => underscore}) } 15 | 16 | pending "Need to find a way to run spec without Sinatra, which so far is proving tricky, as that's kind of the point." 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /examples/app_with_underscores_and_erb_and_subdirs/app.rb: -------------------------------------------------------------------------------- 1 | require 'sinatra/base' 2 | require 'erb' 3 | require File.expand_path( File.join File.dirname(__FILE__), "../ext/kernel.rb") 4 | require_relative "../../lib/sinatra/partial.rb" 5 | require_relative "../whitespace_remove.rb" 6 | 7 | module AppWithUnderscoresAndErbAndSubdirs 8 | class App < Sinatra::Base 9 | register Sinatra::Partial 10 | use WhiteSpaceRemove 11 | 12 | configure do 13 | set :news, ["This", "is", "all", "new"] 14 | end 15 | 16 | enable :partial_underscores 17 | set :partial_template_engine, :erb 18 | 19 | 20 | get "/" do 21 | magic = partial :"partials/magic" 22 | erb :home, :locals => { :show_me_magic => magic } 23 | end 24 | end 25 | end -------------------------------------------------------------------------------- /sinatra-partial.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "sinatra/partial/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "sinatra-partial" 7 | s.version = Sinatra::Partial::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Chris Schneider", "Sam Elliott", "Iain Barnett"] 10 | s.email = ["iainspeed@gmail.com"] 11 | s.homepage = "https://github.com/yb66/Sinatra-Partial" 12 | s.summary = %q{A sinatra extension for render partials.} 13 | s.description = %q{Just the partials helper in a gem. That is all.} 14 | s.license = 'MIT' 15 | 16 | s.add_dependency 'sinatra', ">=1.4" 17 | 18 | s.files = `git ls-files`.split("\n") 19 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 20 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } 21 | s.require_paths = ["lib"] 22 | end 23 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rake' 4 | 5 | task :default => "spec" 6 | 7 | 8 | desc "(Re-) generate documentation and place it in the docs/ dir." 9 | task :docs => :"docs:yard" 10 | namespace :docs do 11 | require 'yard' 12 | YARD::Rake::YardocTask.new do |t| 13 | t.files = ['lib/**/*.rb'] 14 | t.options = ['-odocs/', '--no-private'] 15 | end 16 | 17 | desc "Docs including private methods." 18 | YARD::Rake::YardocTask.new(:all) do |t| 19 | t.files = ['lib/**/*.rb'] 20 | t.options = ['-odocs/'] 21 | end 22 | 23 | desc "How to use the docs." 24 | task :usage do 25 | puts "Open the index.html file in the docs directory to read them. Does not include methods marked private unless you ran the 'all' version (you'll only need these if you plan to hack on the library itself)." 26 | end 27 | end 28 | 29 | 30 | require 'rspec/core/rake_task' 31 | 32 | desc "Run specs" 33 | RSpec::Core::RakeTask.new do |t| 34 | t.pattern = "./spec/**/*_spec.rb" 35 | end 36 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'rspec' 4 | require 'rspec/its' 5 | Spec_dir = File.expand_path( File.dirname __FILE__ ) 6 | unless Kernel.respond_to?(:require_relative) 7 | module Kernel 8 | def require_relative(path) 9 | require File.join(File.dirname(caller[0]), path.to_str) 10 | end 11 | end 12 | end 13 | 14 | # code coverage 15 | require 'simplecov' 16 | SimpleCov.start do 17 | add_filter "/vendor/" 18 | end 19 | 20 | require "rack/test" 21 | ENV['RACK_ENV'] ||= 'test' 22 | ENV["EXPECT_WITH"] ||= "racktest" 23 | 24 | require "logger" 25 | logger = Logger.new STDOUT 26 | logger.level = Logger::DEBUG 27 | logger.datetime_format = '%a %d-%m-%Y %H%M ' 28 | LOgger = logger 29 | 30 | 31 | Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f| 32 | puts "requiring #{f}" 33 | require f 34 | end 35 | 36 | 37 | RSpec.configure do |config| 38 | config.treat_symbols_as_metadata_keys_with_true_values = true 39 | config.include Rack::Test::Methods 40 | end 41 | 42 | # freeze time! 43 | require 'date' 44 | require 'timecop' 45 | Timecop.freeze( Date.today ) -------------------------------------------------------------------------------- /LICENCE.txt: -------------------------------------------------------------------------------- 1 | ### Licence ### 2 | 3 | Copyright (c) 2012 Iain Barnett 4 | 5 | MIT Licence 6 | 7 | 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: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 10 | 11 | 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. -------------------------------------------------------------------------------- /spec/sinatra_partial_private_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require "spec_helper" 4 | require_relative "../lib/sinatra/partial.rb" 5 | 6 | 7 | describe "partial_expand_path" do 8 | 9 | subject{ Sinatra::Partial::Private.partial_expand_path( partial_path, underscores ) } 10 | 11 | context "Given a single word" do 12 | let(:partial_path) { "news" } 13 | context "and underscores is set to false." do 14 | let(:expected) { :news } 15 | let(:underscores) { false } 16 | it { should == expected } 17 | end 18 | context "and underscores is set to true." do 19 | let(:expected) { :"_news" } 20 | let(:underscores) { true } 21 | it { should == expected } 22 | end 23 | end 24 | context "Given a path" do 25 | let(:partial_path) { "meta/news" } 26 | context "and underscores is set to false." do 27 | let(:expected) { :"meta/news" } 28 | let(:underscores) { false } 29 | it { should == expected } 30 | end 31 | context "and underscores is set to true." do 32 | let(:expected) { :"meta/_news" } 33 | let(:underscores) { true } 34 | it { should == expected } 35 | end 36 | end 37 | end -------------------------------------------------------------------------------- /spec/examples_spec.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require "spec_helper" 4 | 5 | require_relative "../lib/sinatra/partial.rb" 6 | 7 | require_relative "../examples/app_no_underscores/config.rb" 8 | require_relative "../examples/app_with_underscores/config.rb" 9 | require_relative "../examples/app_with_underscores_and_erb/config.rb" 10 | require_relative "../examples/app_with_underscores_and_erb_and_subdirs/config.rb" 11 | #require_relative "../examples/app_no_underscores_and_slim/config.rb" 12 | 13 | 14 | shared_context "Running different apps" do |c| 15 | include Rack::Test::Methods 16 | let(:app){ c.app } 17 | before{ get '/' } 18 | end 19 | 20 | 21 | shared_examples_for "all in examples dir" do 22 | subject { last_response } 23 | it { should be_ok } 24 | its(:body) { should == expected } 25 | end 26 | 27 | 28 | [AppNoUnderscores, AppWithUnderscores, AppWithUnderscoresAndErb, AppWithUnderscoresAndErbAndSubdirs 29 | ].each do |c| 30 | describe c.to_s do 31 | include_context "Running different apps", c 32 | it_should_behave_like "all in examples dir" do 33 | let(:expected) { "

    Time is #{Time.now}

    A is A

    B is B

    C is C

    D is D

    Hello, World

    Show me magic!

    " } 34 | end 35 | end 36 | end -------------------------------------------------------------------------------- /CHANGES.markdown: -------------------------------------------------------------------------------- 1 | ## Upcoming ## 2 | 3 | ## v1.0.1, 28th of July 2017 ## 4 | 5 | - Sinatra is at v2.0.0 so checked it works against it and updated the gemspec to allow it to install when using a dependency manager like Bundler. 6 | 7 | ## v1.0.0, 7th of April 2015 ## 8 | 9 | * Dropped support for pre-v2 Ruby. There's no changes within the library itself that should stop it working at this point, but that doesn't mean that it's supported. 10 | * Changes because of updates to other libs. By that, I mean the ever changing RSpec API. 11 | * Release because of http://blog.rubygems.org/2016/04/06/gem-replacement-vulnerability-and-mitigation.html 12 | * Move to 1.0.0 for semver, this gem has been stable for a long time. 13 | 14 | ---- 15 | 16 | 17 | ## v0.4.0 ## 18 | 19 | 10th of December 2012 20 | 21 | * Fixed example in README, re issue#4, thanks to [@moollaza](https://github.com/moollaza) for pointing it out. 22 | * better handling of paths, which helps fix a (hopefully rare) error when a dot is in the path. 23 | * Fix for some errors on 1.8.7 and 1.9.2 builds when run on Travis. Thanks to [@petems](https://github.com/petems)." 24 | 25 | ---- 26 | 27 | 28 | ## v0.3.2 ## 29 | 30 | 23rd of August 2012 31 | 32 | * Updated the examples to use a setting instead of a constant (because JRuby didn't like it, and because it is a bit weird). 33 | * Ran specs against Rubinius and JRuby(1.9 API) and they passed, so they've been added to the Travis CI as well. 34 | * Updated the README to make the build status a bit clearer. 35 | 36 | 7th of June 2012 37 | 38 | * Fixes to README. 39 | 40 | ---- 41 | 42 | 43 | ## v0.3.1 ## 44 | 45 | 28th of May 2012 46 | 47 | * Fixed a bug where partials called within a route would not have layout set to false by default. To be honest, I think it's a change in the Sinatra codebase, but it was easily fixed by setting layout to false with the partial method. This does, however, mean that partial can't be called to run a layout, but if you're using it that way then you're using it wrong! Try just calling `haml` or `erb`. 48 | * Improved the examples by adding a config.rb and config.ru. Not only does it mean the examples can be run from the command line easier, but I think it's a good way to set up an app to help with testing. 49 | 50 | ---- 51 | 52 | 53 | ## v0.3.0 ## 54 | 55 | 23rd of April 2012 56 | 57 | * Improved specs. 58 | * Examples are slightly more complex, since the specs required it, which also helps to clarify use. 59 | * Tested and passing for Ruby 1.8.7, 1.9.2 and 1.9.3. 60 | * Project added to Travis CI. 61 | * More documentation. 62 | * Better organised development (at last!) 63 | * A Rake file has arrived! 64 | 65 | ---- 66 | 67 | 68 | ## v0.2.1 ## 69 | 70 | 10th of April 2012 71 | 72 | Sam Elliott provided a lot of helpful code to add in features that were lost from his gist, so many thanks to him. 73 | 74 | * Different template engines other than Haml may be specified 75 | * Leading underscores (a la Rails) can be specified for partials too. 76 | * The lib is now a Sinatra Extension so the template engine and leading underscores can be configured for the application as a whole (and still overriden at call time). 77 | * Examples have been added to the examples directory 78 | * The code docs are much more extensive. 79 | 80 | ---- 81 | 82 | 83 | ## v0.1.1 ## 84 | 85 | 9th of December 2011 86 | 87 | * Improved the examples in the Readme file. A lot. 88 | 89 | ---- 90 | 91 | 92 | ## v0.1.0 ## 93 | 94 | 4th of July 2011 95 | 96 | * The locals hash doesn't get clobbered if passing a collection now, but you do get the chance to clobber the default of passing the collection local if you so wish. With great power comes great responsibility! 97 | -------------------------------------------------------------------------------- /lib/sinatra/partial.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | 3 | require 'sinatra/base' 4 | 5 | module Sinatra 6 | module Partial 7 | 8 | # This is here to make testing the private code easier while not including it in the helpers. 9 | module Private 10 | 11 | # This gets the path to the template, taking into account whether leading underscores are needed. 12 | # @private 13 | # param [String] partial_path 14 | # param [true,false,nil] underscores Defaults to false 15 | def self.partial_expand_path(partial_path, underscores=false) 16 | underscores ||= false 17 | dirs, base = File.dirname(partial_path), File.basename(partial_path) 18 | base.insert(0, "_") if underscores 19 | xs = dirs == "." ? [base] : [dirs, base] 20 | File.join(xs).to_sym 21 | end 22 | 23 | # This takes the name of the local from the template's name, and corrects local by removing leading underscore if it's there. 24 | # @private 25 | # param [String] partial_path 26 | def self.partial_local(partial_path) 27 | partial_path = partial_path[1..-1] if partial_path.start_with? "_" 28 | File.basename(partial_path).to_sym 29 | end 30 | end 31 | 32 | 33 | module Helpers 34 | # Renders a partial to a string. 35 | # 36 | # @param [#to_s] partial_name The partial to render. 37 | # @param [Hash] options The options to render the partial with. 38 | # @option options [Hash] :locals Local variables to render with 39 | # @option options [Array] :collection Renders the template once per object in this array. 40 | # @option options [Symbol] :template_engine The template engine to use. Haml by default. 41 | # @option options [true,false] :underscores Set to true if you wish to follow the Rails convention of partial files having a leading underscore. 42 | # 43 | # @return [String] The rendered template contents. 44 | # 45 | # @example simply render a partial 46 | # partial(:meta, :locals => {meta: meta}) 47 | # # => renders views/_meta.haml 48 | # 49 | # @example render a partial in a subfolder 50 | # partial("meta/news", :locals => {news: []}) 51 | # # => renders views/meta/_news.haml 52 | # 53 | # @example render a collection of objects with one partial 54 | # partial(:"meta/news", :collection => []) 55 | # # => renders views/meta/_news.haml once per item in :collection, 56 | # with the local variable `news` being the current item in the iteration 57 | def partial(partial_name, options={}) 58 | options.merge! :layout => false 59 | partial_location = partial_name.to_s 60 | engine = options.fetch(:template_engine, settings.partial_template_engine) 61 | underscores = options.fetch(:underscores, settings.partial_underscores) 62 | 63 | template = Private.partial_expand_path(partial_location, underscores) 64 | 65 | if collection = options.delete(:collection) 66 | member_local = Private.partial_local(partial_location) 67 | 68 | locals = options.fetch(:locals, {}) 69 | 70 | collection.inject([]) do |buffer, member| 71 | new_locals = {member_local => member}.merge(locals) 72 | buffer << self.method(engine).call(template, options.merge(:locals => new_locals)) 73 | end.join("\n") 74 | else 75 | # TODO benchmark this and see if caching the method 76 | # speeds things up 77 | self.method(engine).call(template, options) 78 | end 79 | end 80 | 81 | end # of Helpers 82 | 83 | # This is here to allow configuration options to be set. 84 | # @private 85 | def self.registered(app) 86 | app.helpers(Partial::Helpers) 87 | 88 | # Configuration 89 | app.set :partial_underscores, false 90 | app.set :partial_template_engine, :haml 91 | end 92 | 93 | end # Partial 94 | register(Sinatra::Partial) 95 | end 96 | 97 | 98 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | ## Sinatra Partial ## 2 | 3 | Partials for Sinatra! 4 | 5 | ### Build status ### 6 | 7 | Master branch: 8 | [![Build Status](https://secure.travis-ci.org/yb66/Sinatra-Partial.png?branch=master)](http://travis-ci.org/yb66/Sinatra-Partial) 9 | 10 | Develop branch: 11 | [![Build Status for development branch](https://secure.travis-ci.org/yb66/Sinatra-Partial.png?branch=develop)](http://travis-ci.org/yb66/Sinatra-Partial) 12 | 13 | ### Quick note ### 14 | 15 | If you do decide to use this gem, please let me know if it isn't working for you - make a contribution! Github makes it so simple..! See the [Contribution section](#Contributing) for more. 16 | 17 | Back to our previously scheduled programming... 18 | 19 | ### Por qué? ### 20 | 21 | You may say "why is this needed?". 22 | 23 | Go on then. 24 | 25 | _huff_ "Why is this needed?" 26 | 27 | Because I was forever copying the code I took from http://www.sinatrarb.com/faq.html#partials into each and every project. It may well be that this is included in some other gem full of useful helpers, but I haven't found it yet, and besides _this is what I really want_. The whole point of Sinatra is not to get a lot of stuff you didn't really need anyway. 28 | 29 | So here it is, partials, and that's it. 30 | 31 | ### Installation ### 32 | 33 | gem install sinatra-partial 34 | 35 | ### Getting started ### 36 | 37 | At the top of your app.rb: 38 | 39 | require 'sinatra/partial' 40 | 41 | For a classic app, that's all you need to do. For a modular app you should register it too: 42 | 43 | class Blah < Sinatra::Base 44 | register Sinatra::Partial 45 | 46 | 47 | ### Configuration options ### 48 | 49 | The default templating engine is haml. If you wish to use something else, you can set in the config options: 50 | 51 | set :partial_template_engine, :erb 52 | 53 | If you wish, you can also pass this in with the options hash to partial (if you do, it will override the above setting for that call): 54 | 55 | partial(:"meta/news", :template_engine => :erb) 56 | 57 | If you like the Rails convention of adding an underscore to the beginning of a partial, set it here: 58 | 59 | enable :partial_underscores 60 | 61 | Otherwise, the default is for no underscore (if you like Rails you know where to get it;) 62 | 63 | *Note:* 64 | 65 | If you're using [Slim](https://rubygems.org/gems/slim) then there are examples in the examples directory, but the output is slightly different for some reason and [the project maintainers don't wish to be helpful](https://github.com/stonean/slim/issues/328). I don't use Slim, if you do then feel free to contribute and find out how to get the specs to pass, but I won't be pursuing this. 66 | 67 | ### Some examples ### 68 | 69 | The docs are good to look at (big thanks to Sam Elliot for improving them a lot), just follow the docs link from this page if you can't find them: 70 | 71 | https://rubygems.org/gems/sinatra-partial 72 | 73 | or use yard/rdoc to generate them. 74 | 75 | 76 | #### Inside a route #### 77 | 78 | get "/" do 79 | output = "" 80 | output << partial( :top ) 81 | output << partial( :middle ) 82 | output << partial( :bottom ) 83 | output 84 | end 85 | 86 | -# top.haml 87 | %h2 88 | The is the top 89 | 90 | -# middle.haml 91 | %p 92 | Can you guess what I am yet? 93 | 94 | -# bottom.haml 95 | %p 96 | Is it worse to be at the bottom or the foot? 97 | 98 | 99 | #### Local variables #### 100 | 101 | get "/" do 102 | output = "" 103 | @title = "My contrived example" 104 | username = current_user.username 105 | output << partial( :left_col ) 106 | output << partial( :middle, :locals => { username: username} ) 107 | output << partial( :right ) 108 | output 109 | end 110 | 111 | -# middle.haml 112 | %p 113 | Wow, here is that #{username} you just passed me! 114 | :-o 115 | 116 | 117 | #### Here's one using views #### 118 | 119 | Remember that since this is a helper method it can be called inside routes and views - use it where you need it! 120 | 121 | -# welcome_message.haml 122 | %h2 123 | Welcome back #{username} 124 | 125 | -# content.haml 126 | Blah Blah Blah 127 | 128 | -# footer.haml 129 | You've reached the bottom of the page! 130 | 131 | -# layout.haml 132 | %html 133 | %head 134 | %body 135 | #header 136 | = partial :welcome_message, locals: {username: "Iain" } 137 | 138 | #main 139 | = partial :content 140 | 141 | = yield 142 | 143 | #footer 144 | = partial :footer 145 | 146 | 147 | ### Collections ### 148 | 149 | Here's how to use a collection, in this case to render a menu: 150 | 151 | # app.rb 152 | 153 | before do 154 | @menu = [ 155 | ["home", uri("/")], 156 | ["login", uri("/login")], 157 | ["contact_us", uri("/contact-us")], 158 | ["about", uri("/about")], 159 | ] 160 | end 161 | 162 | 163 | -# menu.haml 164 | #nav 165 | %ul 166 | = partial :menu_item, collection: menu 167 | 168 | -# menu_item.haml 169 | - display_name, url = menu_item 170 | - atts ||= {} 171 | -# set the class of the list item for the current page to 'active' 172 | - (atts[:class] = atts[:class].nil? ? "active" : "#{atts[:class]} active") if request.url == url 173 | 174 | %li{ atts } 175 | %a{ class: "nav", href: menu_item.last } 176 | = menu_item.first 177 | 178 | 179 | -# layout.haml 180 | %html 181 | %head 182 | %title= @title 183 | %body 184 | = yield 185 | 186 | = partial :menu, locals: { menu: @menu } 187 | 188 | 189 | You'll get a menu built for you. 190 | 191 | 192 | ### Examples ### 193 | 194 | Look in the examples directory for some very simple examples. 195 | 196 | 197 | ### Thanks ### 198 | 199 | Thanks to Chris Schneider and Sam Elliott for sharing their code, and for sharing further updates. 200 | 201 | 202 | ### Contributing ### 203 | 204 | Most of all, remember that **any** contribution you can make will be valuable, whether that is putting in a ticket for a feature request (or a bug, but they don't happen here;), cleaning up some grammar, writing some documentation (or even a blog post, let me know!) or a full blooded piece of code - it's **all** welcome and encouraged. 205 | 206 | To contribute some code: 207 | 208 | 1. Fork this. 209 | * `git clone git@github.com:YOUR_USERNAME/Sinatra-Partial.git` 210 | * `git remote add upstream git://github.com/yb66/Sinatra-Partial.git` 211 | * `git fetch upstream` 212 | * `git checkout develop` 213 | * Decide on the feature you wish to add. 214 | - Give it a snazzy name, such as kitchen_sink. 215 | - `git checkout -b kitchen_sink` 216 | * Install Bundler. 217 | - `gem install bundler -r --no-ri --no-rdoc` 218 | * Install gems from Gemfile. 219 | - `bundle install --binstubs --path vendor` 220 | - Any further updates needed, just run `bundle install`, it'll remember the rest. 221 | * Write some specs. 222 | * Write some code. (Yes, I believe that is the correct order, and you'll never find me doing any different;) 223 | * Write some documentation using Yard comments - see http://rubydoc.info/docs/yard/file/docs/GettingStarted.md 224 | - Use real English (i.e. full stops and commas, no l33t or LOLZ). I'll accept American English even though it's ugly. Don't be surprised if I 'correct' it. 225 | - Code without comments won't get in, I don't have the time to work out what you've done if you're not prepared to spend some time telling me (and everyone else). 226 | * Run `reek PATH_TO_FILE_WITH_YOUR_CHANGES` and see if it gives you any good advice. You don't have to do what it says, just consider it. 227 | * Run specs to make sure you've not broken anything. If it doesn't pass all the specs it doesn't get in. 228 | - Have a look at coverage/index.htm and see if all your code was checked. We're trying for 100% code coverage. 229 | - If your commit changes the way things work or adds a feature then add an example in the examples dir. The specs run off the examples to make sure the library works with a real project while keeping the examples up to date, so make sure you add something there if needs be. 230 | * Run `bin/rake docs` to generate documentation. 231 | - Open up docs/index.html and check your documentation has been added and is clear. 232 | * Add a short summary of your changes to the top of CHANGES file. Add your name and a link to your bio/website if you like too. **Don't** add a version number, I'll handle that. 233 | * Send me a pull request. 234 | - Don't merge into the develop branch! 235 | - Don't merge into the master branch! 236 | - see http://nvie.com/posts/a-successful-git-branching-model/ for more on how this is supposed to work. 237 | * Wait for worldwide fame. 238 | * Shrug and get on with you life when it doesn't arrive, but know you helped quite a few people in their life, even in a small way - 1000 raindrops will fill a bucket! --------------------------------------------------------------------------------