├── example ├── log │ └── .gitkeep ├── app │ ├── mailers │ │ └── .gitkeep │ ├── models │ │ ├── .gitkeep │ │ ├── category.rb │ │ └── post.rb │ ├── views │ │ ├── posts │ │ │ ├── new.html.haml │ │ │ ├── index.html.haml │ │ │ └── show.html.haml │ │ ├── pages │ │ │ └── index.html.haml │ │ └── layouts │ │ │ └── application.html.haml │ ├── helpers │ │ ├── pages_helper.rb │ │ ├── post_helper.rb │ │ └── application_helper.rb │ ├── assets │ │ ├── images │ │ │ └── rails.png │ │ ├── stylesheets │ │ │ ├── post.css.scss │ │ │ ├── application.css │ │ │ └── layout.css.sass │ │ └── javascripts │ │ │ ├── pages.js.coffee │ │ │ ├── post.js.coffee │ │ │ └── application.js │ └── controllers │ │ ├── pages_controller.rb │ │ ├── application_controller.rb │ │ └── posts_controller.rb ├── lib │ ├── assets │ │ └── .gitkeep │ └── tasks │ │ └── .gitkeep ├── public │ ├── favicon.ico │ ├── robots.txt │ ├── 422.html │ ├── 404.html │ └── 500.html ├── vendor │ ├── plugins │ │ └── .gitkeep │ └── assets │ │ └── stylesheets │ │ └── .gitkeep ├── .rspec ├── .gitignore ├── config │ ├── routes.rb │ ├── environment.rb │ ├── boot.rb │ ├── locales │ │ └── en.yml │ ├── initializers │ │ ├── mime_types.rb │ │ ├── inflections.rb │ │ ├── backtrace_silencers.rb │ │ ├── session_store.rb │ │ ├── secret_token.rb │ │ └── wrap_parameters.rb │ ├── database.yml │ ├── environments │ │ ├── development.rb │ │ ├── test.rb │ │ └── production.rb │ └── application.rb ├── spec │ ├── controllers │ │ └── posts_controller_spec.rb │ └── spec_helper.rb ├── config.ru ├── db │ ├── migrate │ │ ├── 20111104104040_add_category_id_to_posts.rb │ │ ├── 20111104103150_create_posts.rb │ │ └── 20111104103738_create_categories.rb │ ├── seeds.rb │ └── schema.rb ├── doc │ └── README_FOR_APP ├── Rakefile ├── script │ └── rails ├── Gemfile ├── README.md ├── .rvmrc └── Gemfile.lock ├── init.rb ├── Gemfile ├── .gitignore ├── .travis.yml ├── lib ├── crummy │ ├── version.rb │ ├── railtie.rb │ ├── action_view.rb │ ├── action_controller.rb │ └── standard_renderer.rb └── crummy.rb ├── gemfiles ├── rails3_2.gemfile └── rails4_0.gemfile ├── Appraisals ├── Rakefile ├── MIT-LICENSE ├── crummy.gemspec ├── CHANGELOG ├── .rvmrc ├── README.md └── test └── standard_renderer_test.rb /example/log/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/app/mailers/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/app/models/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/lib/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /init.rb: -------------------------------------------------------------------------------- 1 | require 'crummy' 2 | -------------------------------------------------------------------------------- /example/vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/vendor/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/app/views/posts/new.html.haml: -------------------------------------------------------------------------------- 1 | … -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gemspec -------------------------------------------------------------------------------- /example/.rspec: -------------------------------------------------------------------------------- 1 | --color --format documentation 2 | -------------------------------------------------------------------------------- /example/app/helpers/pages_helper.rb: -------------------------------------------------------------------------------- 1 | module PagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /example/app/helpers/post_helper.rb: -------------------------------------------------------------------------------- 1 | module PostHelper 2 | end 3 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | db/*.sqlite3 3 | log/*.log 4 | tmp/ 5 | .sass-cache/ 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | rdoc 2 | nbproject 3 | *.gem 4 | .bundle 5 | pkg/* 6 | Gemfile.lock 7 | *.gemfile.lock 8 | .idea 9 | -------------------------------------------------------------------------------- /example/app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zachinglis/crummy/HEAD/example/app/assets/images/rails.png -------------------------------------------------------------------------------- /example/app/controllers/pages_controller.rb: -------------------------------------------------------------------------------- 1 | class PagesController < ApplicationController 2 | def index 3 | end 4 | 5 | end 6 | -------------------------------------------------------------------------------- /example/app/views/pages/index.html.haml: -------------------------------------------------------------------------------- 1 | - add_crumb "Welcome" 2 | 3 | %h1 Welcome 4 | %p This is a dummy app to keep Crummy tested. 5 | -------------------------------------------------------------------------------- /example/config/routes.rb: -------------------------------------------------------------------------------- 1 | CrummyTest::Application.routes.draw do 2 | resources :posts 3 | 4 | root :to => "pages#index" 5 | end 6 | -------------------------------------------------------------------------------- /example/app/views/posts/index.html.haml: -------------------------------------------------------------------------------- 1 | %h1 Posts 2 | %ul 3 | - @posts.each do |post| 4 | %li 5 | = link_to post.title, post 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 1.9.3 4 | - 2.0.0 5 | gemfile: 6 | - gemfiles/rails3_2.gemfile 7 | - gemfiles/rails4_0.gemfile 8 | -------------------------------------------------------------------------------- /lib/crummy/version.rb: -------------------------------------------------------------------------------- 1 | module Crummy 2 | MAJOR = 1 3 | MINOR = 8 4 | PATCH = 0 5 | VERSION = [MAJOR, MINOR, PATCH].join('.') 6 | end 7 | -------------------------------------------------------------------------------- /example/app/models/category.rb: -------------------------------------------------------------------------------- 1 | class Category < ActiveRecord::Base 2 | belongs_to :category 3 | 4 | has_many :categories 5 | has_many :posts 6 | end 7 | -------------------------------------------------------------------------------- /example/spec/controllers/posts_controller_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe PostsController do 4 | it "exists! (and RSpec works)" do 5 | # nop 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /example/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run CrummyTest::Application 5 | -------------------------------------------------------------------------------- /example/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the rails application 5 | CrummyTest::Application.initialize! 6 | -------------------------------------------------------------------------------- /example/db/migrate/20111104104040_add_category_id_to_posts.rb: -------------------------------------------------------------------------------- 1 | class AddCategoryIdToPosts < ActiveRecord::Migration 2 | def change 3 | add_column :posts, :category_id, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /gemfiles/rails3_2.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", ">= 3.0", "< 4" 6 | gem "actionpack", ">= 3.0", "< 4" 7 | 8 | gemspec :path=>"../" -------------------------------------------------------------------------------- /example/app/assets/stylesheets/post.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the Post controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /example/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | def page_title 3 | if @page_title 4 | "Crummy Test - #{@page_title}" 5 | else 6 | "Crummy Test" 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /gemfiles/rails4_0.gemfile: -------------------------------------------------------------------------------- 1 | # This file was generated by Appraisal 2 | 3 | source "http://rubygems.org" 4 | 5 | gem "activesupport", ">= 4.0.0.beta", "< 5" 6 | gem "actionpack", ">= 4.0.0.beta", "< 5" 7 | 8 | gemspec :path=>"../" -------------------------------------------------------------------------------- /example/config/boot.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | 3 | # Set up gems listed in the Gemfile. 4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 5 | 6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) 7 | -------------------------------------------------------------------------------- /example/doc/README_FOR_APP: -------------------------------------------------------------------------------- 1 | Use this README file to introduce your application and point to useful places in the API for learning more. 2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries. 3 | -------------------------------------------------------------------------------- /example/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-Agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /example/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | add_crumb("Homepage") { |instance| instance.send :root_url } 3 | add_crumb("Customer Dashboard", '/') 4 | 5 | protect_from_forgery 6 | end 7 | -------------------------------------------------------------------------------- /example/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | hello: "Hello world" 6 | -------------------------------------------------------------------------------- /example/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /example/db/migrate/20111104103150_create_posts.rb: -------------------------------------------------------------------------------- 1 | class CreatePosts < ActiveRecord::Migration 2 | def change 3 | create_table :posts do |t| 4 | t.string :title 5 | t.string :slug 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /Appraisals: -------------------------------------------------------------------------------- 1 | appraise "rails3_2" do 2 | gem 'activesupport', '>= 3.0', '< 4' 3 | gem 'actionpack', '>= 3.0', '< 4' 4 | end 5 | 6 | appraise "rails4_0" do 7 | gem 'activesupport', '>= 4.0.0.beta', '< 5' 8 | gem 'actionpack', '>= 4.0.0.beta', '< 5' 9 | end 10 | -------------------------------------------------------------------------------- /example/app/assets/javascripts/pages.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /example/app/assets/javascripts/post.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ 4 | -------------------------------------------------------------------------------- /example/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | CrummyTest::Application.load_tasks 8 | -------------------------------------------------------------------------------- /example/script/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. 3 | 4 | APP_PATH = File.expand_path('../../config/application', __FILE__) 5 | require File.expand_path('../../config/boot', __FILE__) 6 | require 'rails/commands' 7 | -------------------------------------------------------------------------------- /example/db/migrate/20111104103738_create_categories.rb: -------------------------------------------------------------------------------- 1 | class CreateCategories < ActiveRecord::Migration 2 | def change 3 | create_table :categories do |t| 4 | t.string :title 5 | t.string :slug 6 | 7 | t.string :category_id # Can have a category as a parent 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /example/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory 3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at 4 | * the top of the compiled file, but it's generally better to create a new file per style scope. 5 | *= require_self 6 | *= require_tree . 7 | */ -------------------------------------------------------------------------------- /example/app/models/post.rb: -------------------------------------------------------------------------------- 1 | class Post < ActiveRecord::Base 2 | belongs_to :category 3 | 4 | def categories 5 | category = self.category 6 | categories = [] 7 | 8 | while category.present? 9 | categories << category 10 | category = category.category 11 | end 12 | 13 | categories.reverse 14 | end 15 | 16 | def to_s 17 | title 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /example/app/controllers/posts_controller.rb: -------------------------------------------------------------------------------- 1 | class PostsController < ApplicationController 2 | add_crumb "Posts", :posts_url, :except => [:new] 3 | 4 | def index 5 | @posts = Post.all 6 | end 7 | 8 | def show 9 | @post = Post.find params[:id] 10 | 11 | @post.categories.each do |category| 12 | add_crumb category.title, "#" 13 | end 14 | end 15 | 16 | def new 17 | add_crumb "Forever Alone" 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /example/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format 4 | # (all these examples are active by default): 5 | # ActiveSupport::Inflector.inflections do |inflect| 6 | # inflect.plural /^(ox)$/i, '\1en' 7 | # inflect.singular /^(ox)en/i, '\1' 8 | # inflect.irregular 'person', 'people' 9 | # inflect.uncountable %w( fish sheep ) 10 | # end 11 | -------------------------------------------------------------------------------- /example/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /example/app/views/layouts/application.html.haml: -------------------------------------------------------------------------------- 1 | !!! 2 | %html 3 | %head 4 | %title= page_title 5 | = stylesheet_link_tag "application" 6 | = javascript_include_tag "application" 7 | = csrf_meta_tags 8 | %body 9 | #wrapper 10 | %header 11 | .title Crummy 12 | .crumbs= render_crumbs.html_safe 13 | %section#main 14 | = yield 15 | %footer 16 | .crumbs= render_crumbs(:seperator => " | ").html_safe 17 | -------------------------------------------------------------------------------- /example/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | CrummyTest::Application.config.session_store :cookie_store, :key => '_crummy-test_session' 4 | 5 | # Use the database for sessions instead of the cookie-based default, 6 | # which shouldn't be used to store highly confidential information 7 | # (create the session table with "rails generate session_migration") 8 | # CrummyTest::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /example/app/views/posts/show.html.haml: -------------------------------------------------------------------------------- 1 | - add_crumb @post 2 | %h1= @post.title 3 | %p Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. 4 | -------------------------------------------------------------------------------- /example/app/assets/stylesheets/layout.css.sass: -------------------------------------------------------------------------------- 1 | p 2 | font-size: 15px 3 | line-height: 22px 4 | 5 | 6 | #wrapper 7 | margin: 10% 20% 8 | font-family: "Helvetica Nueue", Helvetica, Arial, sans-serif 9 | 10 | .title 11 | font-size: 3rem 12 | font-weight: bold 13 | 14 | .crumbs 15 | border-top: 2px solid black 16 | border-bottom: 1px solid black 17 | padding: 10px 0 18 | margin: 10px 0 19 | 20 | a 21 | font-weight: bold 22 | color: purple 23 | 24 | footer 25 | .crumbs 26 | font-size: 11px 27 | -------------------------------------------------------------------------------- /example/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into including all the files listed below. 2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically 3 | // be included in the compiled file accessible from http://example.com/assets/application.js 4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 5 | // the compiled file. 6 | // 7 | //= require jquery 8 | //= require jquery_ujs 9 | //= require_tree . 10 | -------------------------------------------------------------------------------- /example/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | # Make sure the secret is at least 30 characters and all random, 6 | # no regular words or you'll be exposed to dictionary attacks. 7 | CrummyTest::Application.config.secret_token = '2d7d27ce1894b9d894b07b80d805e7322dcbc4b1f219c6570a29624e620957e399097f343f88a05be49c21ca4555fcd948bb1a1275928eb1187f0a420ec645e2' 8 | -------------------------------------------------------------------------------- /lib/crummy/railtie.rb: -------------------------------------------------------------------------------- 1 | require 'crummy' 2 | require 'rails' 3 | 4 | module Crummy 5 | class Railtie < Rails::Railtie 6 | initializer "crummy.action_controller" do |app| 7 | if defined?(ActionController) 8 | require 'crummy/action_controller' 9 | ActionController::Base.send :include, Crummy::ControllerMethods 10 | end 11 | end 12 | 13 | initializer "crummy.action_view" do |app| 14 | require 'crummy/action_view' 15 | ActionView::Base.send :include, Crummy::ViewMethods 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /example/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | # 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters :format => [:json] 9 | end 10 | 11 | # Disable root element in JSON by default. 12 | ActiveSupport.on_load(:active_record) do 13 | self.include_root_in_json = false 14 | end 15 | -------------------------------------------------------------------------------- /example/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'rails', '3.1.1' 4 | 5 | # Bundle edge Rails instead: 6 | # gem 'rails', :git => 'git://github.com/rails/rails.git' 7 | 8 | gem 'sqlite3' 9 | 10 | # Gems used only for assets and not required 11 | # in production environments by default. 12 | group :assets do 13 | gem 'sass-rails', '~> 3.1.4' 14 | gem 'coffee-rails', '~> 3.1.1' 15 | gem 'uglifier', '>= 1.0.3' 16 | end 17 | 18 | gem 'jquery-rails' 19 | 20 | gem 'haml' 21 | gem 'crummy', :path => '../' 22 | 23 | group :test do 24 | # Pretty printed test output 25 | gem 'turn', :require => false 26 | end 27 | 28 | group :test, :development do 29 | gem "rspec-rails", "~> 2.0" 30 | end 31 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | require 'appraisal' 4 | 5 | desc 'Default: run unit tests.' 6 | task :default => :test 7 | 8 | require 'rake/testtask' 9 | desc 'Test the crummy plugin.' 10 | Rake::TestTask.new(:test) do |t| 11 | t.libs << 'lib' 12 | t.pattern = 'test/**/*_test.rb' 13 | t.verbose = true 14 | end 15 | 16 | require 'rdoc/task' 17 | 18 | desc 'Generate documentation for the crummy plugin.' 19 | Rake::RDocTask.new(:rdoc) do |rdoc| 20 | rdoc.rdoc_dir = 'rdoc' 21 | rdoc.title = 'Crummy: Tasty Breadcrumbs' 22 | rdoc.options << '--line-numbers' << '--inline-source' 23 | rdoc.rdoc_files.include('README.textile') 24 | rdoc.rdoc_files.include('lib/**/*.rb') 25 | end 26 | -------------------------------------------------------------------------------- /example/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The change you wanted was rejected.

23 |

Maybe you tried to change something you didn't have access to.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /example/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

The page you were looking for doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /example/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 17 | 18 | 19 | 20 | 21 |
22 |

We're sorry, but something went wrong.

23 |

We've been notified about this issue and we'll take a look at it shortly.

24 |
25 | 26 | 27 | -------------------------------------------------------------------------------- /example/db/seeds.rb: -------------------------------------------------------------------------------- 1 | # This file should contain all the record creation needed to seed the database with its default values. 2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). 3 | # 4 | # Examples: 5 | # 6 | # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) 7 | # Mayor.create(name: 'Emanuel', city: cities.first) 8 | 9 | movies = Category.create :title => "Movies", :slug => "movies" 10 | star_wars = Category.create :title => "Star Wars", :slug => "star-wars", :category => movies 11 | time = Category.create :title => "What time Is It?", :slug => "time" 12 | 13 | Post.create :title => "A Long Long Time Ago", :slug => "a-long-long-time-ago", :category => star_wars 14 | Post.create :title => "It's Hammer Time", :slug => "its-hammer-time", :category => time 15 | Post.create :title => "Test", :slug => "test" 16 | -------------------------------------------------------------------------------- /lib/crummy/action_view.rb: -------------------------------------------------------------------------------- 1 | module Crummy 2 | module ViewMethods 3 | # List the crumbs as an array 4 | def crumbs 5 | @_crumbs ||= [] # Give me something to push to 6 | end 7 | 8 | # Add a crumb to the +crumbs+ array 9 | def add_crumb(name, url=nil, options={}) 10 | crumbs.push [name, url, options] 11 | end 12 | 13 | # Render the list of crumbs using renderer 14 | # 15 | def render_crumbs(options = {}) 16 | raise ArgumentError, "Renderer and block given" if options.has_key?(:renderer) && block_given? 17 | return yield(crumbs, options) if block_given? 18 | 19 | @_renderer ||= if options.has_key?(:renderer) 20 | options.delete(:renderer) 21 | else 22 | require 'crummy/standard_renderer' 23 | Crummy::StandardRenderer.new 24 | end 25 | 26 | @_renderer.render_crumbs(crumbs, options) 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Zach Inglis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /example/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | CrummyTest::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Log error messages when you accidentally call methods on nil. 10 | config.whiny_nils = true 11 | 12 | # Show full error reports and disable caching 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger 20 | config.active_support.deprecation = :log 21 | 22 | # Only use best-standards-support built into browsers 23 | config.action_dispatch.best_standards_support = :builtin 24 | 25 | # Do not compress assets 26 | config.assets.compress = false 27 | 28 | # Expands the lines which load the assets 29 | config.assets.debug = true 30 | end 31 | -------------------------------------------------------------------------------- /crummy.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "crummy/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "crummy" 7 | s.version = Crummy::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.licenses = ['MIT'] 10 | 11 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 12 | s.authors = ["Zach Inglis", "Andrew Nesbitt"] 13 | s.summary = "Tasty breadcrumbs!" 14 | s.description = "Crummy is a simple and tasty way to add breadcrumbs to your Rails applications." 15 | s.email = "zach+crummy@londonmade.co.uk" 16 | s.extra_rdoc_files = ["README.md"] 17 | 18 | s.files = `git ls-files`.split("\n") 19 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 20 | 21 | s.homepage = "http://github.com/zachinglis/crummy" 22 | s.require_paths = [%q{lib}] 23 | s.rubygems_version = %q{1.8.8} 24 | 25 | s.add_development_dependency 'rake' 26 | s.add_development_dependency 'bundler', '~> 1.0' 27 | s.add_development_dependency 'activesupport' 28 | s.add_development_dependency 'actionpack' 29 | s.add_development_dependency 'appraisal' 30 | s.add_development_dependency 'test-unit' 31 | end 32 | -------------------------------------------------------------------------------- /example/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended to check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(:version => 20111104104040) do 15 | 16 | create_table "categories", :force => true do |t| 17 | t.string "title" 18 | t.string "slug" 19 | t.string "category_id" 20 | t.datetime "created_at" 21 | t.datetime "updated_at" 22 | end 23 | 24 | create_table "posts", :force => true do |t| 25 | t.string "title" 26 | t.string "slug" 27 | t.datetime "created_at" 28 | t.datetime "updated_at" 29 | t.integer "category_id" 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # Crummy Test 2 | 3 | ## Introduction 4 | 5 | This is a test application for [Crummy][crummy], and also a good place where you can see it in action. 6 | 7 | [crummy]: http://github.com/zachinglis/crummy 8 | 9 | ## Usage 10 | 11 | I recommend you to use [RVM][rvm] in order to keep this application gemset distinct from the gem one. Here we use a full Rails stack, which is not true when developping the gem. I you only want to see Crummy in action, you might not care about that. Anyways RVM is not required, but if you use it you'll find an `.rvmrc` file for each context: `example/.rvmrc` and `.rvmrc` respectively for the example app and the gem. Using them is easy and only requires to take care of the directory from where you `bundle install`: if from `example`, you'll update the app bundle, else the gem bundle. 12 | 13 | [rvm]: https://rvm.io 14 | 15 | To quickly start the example app: 16 | 17 | ```bash 18 | # Enter the example directory and trust the .rvmrc file 19 | cd crummy/example 20 | 21 | # Install the bundle 22 | bundle install 23 | # Create the database 24 | bundle exec rake db:schema:load 25 | bundle exec rake db:seed 26 | # Create the test database 27 | bundle exec rake db:test:clone 28 | 29 | # Get the tests green 30 | bundle exec rake 31 | 32 | # Start the server 33 | rails server 34 | ``` 35 | 36 | Your app waits for you at [http://localhost:3000](http://localhost:3000). 37 | 38 | * * * 39 | 40 | I hope this makes the example application a better place to test the gem. 41 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 1.8.0 2 | * [ADDED] You can now set each parameters individually for each crumb 3 | * [ADDED] You can now set each crumb on right or left side 4 | * [ADDED] You can now use a html in a crumb name 5 | * [REFACTORED] Don't render empty html_options for tags. 6 | 7 | 1.7.2 8 | * [ADDED] :truncate option to shorten text in breadcrumbs 9 | * [ADDED] Added ability to pass html link options through to renderer 10 | 11 | 1.7.1 12 | * [ADDED] :last_crumb_linked option to disable linking crumb on current page 13 | 14 | 1.7.0 15 | * [ADDED] Added option for google microdata 16 | * [REFACTORED] Cleaned up development internals 17 | 18 | 1.6.0 19 | * [FIXED] A fix for the escaped html problem in :html_list 20 | 21 | 1.5 22 | * [ADDED] Global configuration options 23 | * [REFACTORED] HTML now uses content_tags 24 | 25 | 1.3.6 26 | * [FIXED] :li_class fixed in StandardRenderer#crumb_to_html_list 27 | 28 | 1.3.5 29 | * [FIXED] Spacing in name argument was causing errors. 30 | * [FIXED] Bug where everything was getting parsed as an Array. 31 | 32 | 1.3 33 | * [FIXED] html_safe! is no longer called by default. That's the user's prerogative to do now. 34 | * [ADDED] Allow record to respond to to_s even if you pass a url or block. 35 | * [ADDED] Allow name to be a proc or lambda method 36 | * [ADDED] clear crumbs as before filter 37 | 38 | 1.2 39 | * [ADDED] html_list format option 40 | * [FIXED] Bug with Passenger and REE deployments 41 | 42 | 1.1.1 43 | 44 | * [FIXED] issue with undefined method escape_once for Rails 3. 45 | * [FIXED] spelling of separator 46 | 47 | 1.1.0 48 | -------------------------------------------------------------------------------- /example/spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] ||= 'test' 3 | require File.expand_path("../../config/environment", __FILE__) 4 | require 'rspec/rails' 5 | require 'rspec/autorun' 6 | 7 | # Requires supporting ruby files with custom matchers and macros, etc, 8 | # in spec/support/ and its subdirectories. 9 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 10 | 11 | RSpec.configure do |config| 12 | # ## Mock Framework 13 | # 14 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 15 | # 16 | # config.mock_with :mocha 17 | # config.mock_with :flexmock 18 | # config.mock_with :rr 19 | 20 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 21 | config.fixture_path = "#{::Rails.root}/spec/fixtures" 22 | 23 | # If you're not using ActiveRecord, or you'd prefer not to run each of your 24 | # examples within a transaction, remove the following line or assign false 25 | # instead of true. 26 | config.use_transactional_fixtures = true 27 | 28 | # If true, the base class of anonymous controllers will be inferred 29 | # automatically. This will be the default behavior in future versions of 30 | # rspec-rails. 31 | config.infer_base_class_for_anonymous_controllers = false 32 | 33 | # Run specs in random order to surface order dependencies. If you find an 34 | # order dependency and want to debug it, you can fix the order by providing 35 | # the seed, which is printed after each run. 36 | # --seed 1234 37 | config.order = "random" 38 | end 39 | -------------------------------------------------------------------------------- /example/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | CrummyTest::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Configure static asset server for tests with Cache-Control for performance 11 | config.serve_static_assets = true 12 | config.static_cache_control = "public, max-age=3600" 13 | 14 | # Log error messages when you accidentally call methods on nil 15 | config.whiny_nils = true 16 | 17 | # Show full error reports and disable caching 18 | config.consider_all_requests_local = true 19 | config.action_controller.perform_caching = false 20 | 21 | # Raise exceptions instead of rendering exception templates 22 | config.action_dispatch.show_exceptions = false 23 | 24 | # Disable request forgery protection in test environment 25 | config.action_controller.allow_forgery_protection = false 26 | 27 | # Tell Action Mailer not to deliver emails to the real world. 28 | # The :test delivery method accumulates sent emails in the 29 | # ActionMailer::Base.deliveries array. 30 | config.action_mailer.delivery_method = :test 31 | 32 | # Use SQL instead of Active Record's schema dumper when creating the test database. 33 | # This is necessary if your schema can't be completely dumped by the schema dumper, 34 | # like if you have constraints or database-specific column types 35 | # config.active_record.schema_format = :sql 36 | 37 | # Print deprecation notices to the stderr 38 | config.active_support.deprecation = :stderr 39 | end 40 | -------------------------------------------------------------------------------- /lib/crummy.rb: -------------------------------------------------------------------------------- 1 | module Crummy 2 | 3 | def self.configuration 4 | @configuration ||= Configuration.new 5 | end 6 | 7 | def self.configure 8 | yield configuration 9 | end 10 | 11 | class Configuration 12 | attr_accessor :format 13 | attr_accessor :links 14 | attr_accessor :skip_if_blank 15 | attr_accessor :html_separator 16 | attr_accessor :html_right_separator 17 | attr_accessor :xml_separator 18 | attr_accessor :xml_right_separator 19 | attr_accessor :html_list_separator 20 | attr_accessor :html_list_right_separator 21 | attr_accessor :first_class 22 | attr_accessor :last_class 23 | attr_accessor :ol_id 24 | attr_accessor :ol_class 25 | attr_accessor :li_class 26 | attr_accessor :microdata 27 | attr_accessor :last_crumb_linked 28 | attr_accessor :truncate 29 | attr_accessor :right_side 30 | 31 | def initialize 32 | @format = :html 33 | @html_separator = " » ".html_safe 34 | @html_right_separator = " » ".html_safe 35 | @xml_separator = "crumb" 36 | @xml_right_separator = "crumb" 37 | @html_list_separator = '' 38 | @html_list_right_separator = '' 39 | @skip_if_blank = true 40 | @links = true 41 | @first_class = '' 42 | @last_class = '' 43 | @ol_id = '' 44 | @ol_class = '' 45 | @li_class = '' 46 | @microdata = false 47 | @last_crumb_linked = true 48 | @truncate = nil 49 | @right_side = false 50 | end 51 | 52 | def active_li_class=(class_name) 53 | puts "CRUMMY: The 'active_li_class' option is DEPRECATED and will be removed from a future version" 54 | end 55 | 56 | def active_li_class 57 | puts "CRUMMY: The 'active_li_class' option is DEPRECATED and will be removed from a future version" 58 | end 59 | end 60 | 61 | if defined?(Rails::Railtie) 62 | require 'crummy/railtie' 63 | else 64 | require 'crummy/action_controller' 65 | require 'crummy/action_view' 66 | ActionController::Base.send :include, Crummy::ControllerMethods 67 | ActionView::Base.send :include, Crummy::ViewMethods 68 | end 69 | end 70 | -------------------------------------------------------------------------------- /.rvmrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This is an RVM Project .rvmrc file, used to automatically load the ruby 4 | # development environment upon cd'ing into the directory 5 | 6 | # First we specify our desired [@], the @gemset name is optional, 7 | # Only full ruby name is supported here, for short names use: 8 | # echo "rvm use 1.9.3" > .rvmrc 9 | environment_id="ruby-1.9.3-head@crummy" 10 | 11 | # Uncomment the following lines if you want to verify rvm version per project 12 | # rvmrc_rvm_version="1.17.7 (stable)" # 1.10.1 seams as a safe start 13 | # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { 14 | # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." 15 | # return 1 16 | # } 17 | 18 | # First we attempt to load the desired environment directly from the environment 19 | # file. This is very fast and efficient compared to running through the entire 20 | # CLI and selector. If you want feedback on which environment was used then 21 | # insert the word 'use' after --create as this triggers verbose mode. 22 | if [[ -d "${rvm_path:-$HOME/.rvm}/environments" 23 | && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] 24 | then 25 | \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" 26 | [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && 27 | \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true 28 | else 29 | # If the environment file has not yet been created, use the RVM CLI to select. 30 | rvm --create "$environment_id" || { 31 | echo "Failed to create RVM environment '${environment_id}'." 32 | return 1 33 | } 34 | fi 35 | 36 | # If you use bundler, this might be useful to you: 37 | # if [[ -s Gemfile ]] && { 38 | # ! builtin command -v bundle >/dev/null || 39 | # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null 40 | # } 41 | # then 42 | # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n" 43 | # gem install bundler 44 | # fi 45 | # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null 46 | # then 47 | # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete' 48 | # fi 49 | -------------------------------------------------------------------------------- /example/.rvmrc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This is an RVM Project .rvmrc file, used to automatically load the ruby 4 | # development environment upon cd'ing into the directory 5 | 6 | # First we specify our desired [@], the @gemset name is optional, 7 | # Only full ruby name is supported here, for short names use: 8 | # echo "rvm use 1.9.3" > .rvmrc 9 | environment_id="ruby-1.9.3-head@crummy-test" 10 | 11 | # Uncomment the following lines if you want to verify rvm version per project 12 | # rvmrc_rvm_version="1.17.7 (stable)" # 1.10.1 seams as a safe start 13 | # eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { 14 | # echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." 15 | # return 1 16 | # } 17 | 18 | # First we attempt to load the desired environment directly from the environment 19 | # file. This is very fast and efficient compared to running through the entire 20 | # CLI and selector. If you want feedback on which environment was used then 21 | # insert the word 'use' after --create as this triggers verbose mode. 22 | if [[ -d "${rvm_path:-$HOME/.rvm}/environments" 23 | && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] 24 | then 25 | \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" 26 | [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && 27 | \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true 28 | else 29 | # If the environment file has not yet been created, use the RVM CLI to select. 30 | rvm --create "$environment_id" || { 31 | echo "Failed to create RVM environment '${environment_id}'." 32 | return 1 33 | } 34 | fi 35 | 36 | # If you use bundler, this might be useful to you: 37 | # if [[ -s Gemfile ]] && { 38 | # ! builtin command -v bundle >/dev/null || 39 | # builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null 40 | # } 41 | # then 42 | # printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n" 43 | # gem install bundler 44 | # fi 45 | # if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null 46 | # then 47 | # bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete' 48 | # fi 49 | -------------------------------------------------------------------------------- /example/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | if defined?(Bundler) 6 | # If you precompile assets before deploying to production, use this line 7 | Bundler.require(*Rails.groups(:assets => %w(development test))) 8 | # If you want your assets lazily compiled in production, use this line 9 | # Bundler.require(:default, :assets, Rails.env) 10 | end 11 | 12 | module CrummyTest 13 | class Application < Rails::Application 14 | # Settings in config/environments/* take precedence over those specified here. 15 | # Application configuration should go into files in config/initializers 16 | # -- all .rb files in that directory are automatically loaded. 17 | 18 | # Custom directories with classes and modules you want to be autoloadable. 19 | # config.autoload_paths += %W(#{config.root}/extras) 20 | 21 | # Only load the plugins named here, in the order given (default is alphabetical). 22 | # :all can be used as a placeholder for all plugins not explicitly named. 23 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 24 | 25 | # Activate observers that should always be running. 26 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer 27 | 28 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 29 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 30 | # config.time_zone = 'Central Time (US & Canada)' 31 | 32 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 33 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 34 | # config.i18n.default_locale = :de 35 | 36 | # Configure the default encoding used in templates for Ruby 1.9. 37 | config.encoding = "utf-8" 38 | 39 | # Configure sensitive parameters which will be filtered from the log file. 40 | config.filter_parameters += [:password] 41 | 42 | # Enable the asset pipeline 43 | config.assets.enabled = true 44 | 45 | # Version of your assets, change this if you want to expire all your assets 46 | config.assets.version = '1.0' 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /example/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | CrummyTest::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Full error reports are disabled and caching is turned on 8 | config.consider_all_requests_local = false 9 | config.action_controller.perform_caching = true 10 | 11 | # Disable Rails's static asset server (Apache or nginx will already do this) 12 | config.serve_static_assets = false 13 | 14 | # Compress JavaScripts and CSS 15 | config.assets.compress = true 16 | 17 | # Don't fallback to assets pipeline if a precompiled asset is missed 18 | config.assets.compile = false 19 | 20 | # Generate digests for assets URLs 21 | config.assets.digest = true 22 | 23 | # Defaults to Rails.root.join("public/assets") 24 | # config.assets.manifest = YOUR_PATH 25 | 26 | # Specifies the header that your server uses for sending files 27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 29 | 30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 31 | # config.force_ssl = true 32 | 33 | # See everything in the log (default is :info) 34 | # config.log_level = :debug 35 | 36 | # Use a different logger for distributed setups 37 | # config.logger = SyslogLogger.new 38 | 39 | # Use a different cache store in production 40 | # config.cache_store = :mem_cache_store 41 | 42 | # Enable serving of images, stylesheets, and JavaScripts from an asset server 43 | # config.action_controller.asset_host = "http://assets.example.com" 44 | 45 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 46 | # config.assets.precompile += %w( search.js ) 47 | 48 | # Disable delivery errors, bad email addresses will be ignored 49 | # config.action_mailer.raise_delivery_errors = false 50 | 51 | # Enable threaded mode 52 | # config.threadsafe! 53 | 54 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 55 | # the I18n.default_locale when a translation can not be found) 56 | config.i18n.fallbacks = true 57 | 58 | # Send deprecation notices to registered listeners 59 | config.active_support.deprecation = :notify 60 | end 61 | -------------------------------------------------------------------------------- /lib/crummy/action_controller.rb: -------------------------------------------------------------------------------- 1 | module Crummy 2 | module ControllerMethods 3 | module ClassMethods 4 | # Add a crumb to the crumbs array. 5 | # 6 | # add_crumb("Home", "/") 7 | # add_crumb(lambda { |instance| instance.business_name }, "/") 8 | # add_crumb("Business") { |instance| instance.business_path } 9 | # 10 | # Works like a before_filter so +:only+ and +except+ both work. 11 | def add_crumb(name, *args) 12 | options = args.extract_options! 13 | url = args.first 14 | raise ArgumentError, "Need more arguments" unless name or options[:record] or block_given? 15 | raise ArgumentError, "Cannot pass url and use block" if url && block_given? 16 | before_filter(options) do |instance| 17 | url = yield instance if block_given? 18 | url = instance.send url if url.is_a? Symbol 19 | 20 | if url.present? 21 | if url.kind_of? Array 22 | url.map! do |name| 23 | name.is_a?(Symbol) ? instance.instance_variable_get("@#{name}") : name 24 | end 25 | end 26 | if not url.kind_of? String 27 | url = instance.send :url_for, url 28 | end 29 | end 30 | 31 | # Get the return value of the name if its a proc. 32 | name = name.call(instance) if name.is_a?(Proc) 33 | 34 | _record = instance.instance_variable_get("@#{name}") unless name.kind_of?(String) 35 | if _record and _record.respond_to? :to_param 36 | instance.add_crumb(_record.to_s, url || instance.url_for(_record), options) 37 | else 38 | instance.add_crumb(name, url, options) 39 | end 40 | 41 | # FIXME: url = instance.url_for(name) if name.respond_to?("to_param") && url.nil? 42 | # FIXME: Add ||= for the name, url above 43 | end 44 | end 45 | 46 | def clear_crumbs 47 | before_filter do |instance| 48 | instance.clear_crumbs 49 | end 50 | end 51 | end 52 | 53 | module InstanceMethods 54 | # Add a crumb to the crumbs array. 55 | # 56 | # add_crumb("Home", "/") 57 | # add_crumb("Business") { |instance| instance.business_path } 58 | # 59 | def add_crumb(name, url=nil, options={}) 60 | crumbs.push [name, url, options] 61 | end 62 | 63 | def clear_crumbs 64 | crumbs.clear 65 | end 66 | 67 | # Lists the crumbs as an array 68 | def crumbs 69 | get_or_set_ivar "@_crumbs", [] 70 | end 71 | 72 | def get_or_set_ivar(var, value) # :nodoc: 73 | instance_variable_set var, instance_variable_get(var) || value 74 | end 75 | private :get_or_set_ivar 76 | end 77 | 78 | def self.included(receiver) # :nodoc: 79 | receiver.extend ClassMethods 80 | receiver.send :include, InstanceMethods 81 | end 82 | end 83 | end 84 | -------------------------------------------------------------------------------- /example/Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: ../ 3 | specs: 4 | crummy (1.7.1) 5 | 6 | GEM 7 | remote: http://rubygems.org/ 8 | specs: 9 | actionmailer (3.1.1) 10 | actionpack (= 3.1.1) 11 | mail (~> 2.3.0) 12 | actionpack (3.1.1) 13 | activemodel (= 3.1.1) 14 | activesupport (= 3.1.1) 15 | builder (~> 3.0.0) 16 | erubis (~> 2.7.0) 17 | i18n (~> 0.6) 18 | rack (~> 1.3.2) 19 | rack-cache (~> 1.1) 20 | rack-mount (~> 0.8.2) 21 | rack-test (~> 0.6.1) 22 | sprockets (~> 2.0.2) 23 | activemodel (3.1.1) 24 | activesupport (= 3.1.1) 25 | builder (~> 3.0.0) 26 | i18n (~> 0.6) 27 | activerecord (3.1.1) 28 | activemodel (= 3.1.1) 29 | activesupport (= 3.1.1) 30 | arel (~> 2.2.1) 31 | tzinfo (~> 0.3.29) 32 | activeresource (3.1.1) 33 | activemodel (= 3.1.1) 34 | activesupport (= 3.1.1) 35 | activesupport (3.1.1) 36 | multi_json (~> 1.0) 37 | ansi (1.3.0) 38 | arel (2.2.1) 39 | builder (3.0.0) 40 | coffee-rails (3.1.1) 41 | coffee-script (>= 2.2.0) 42 | railties (~> 3.1.0) 43 | coffee-script (2.2.0) 44 | coffee-script-source 45 | execjs 46 | coffee-script-source (1.1.2) 47 | diff-lcs (1.2.1) 48 | erubis (2.7.0) 49 | execjs (1.2.9) 50 | multi_json (~> 1.0) 51 | haml (3.1.3) 52 | hike (1.2.1) 53 | i18n (0.6.0) 54 | jquery-rails (1.0.16) 55 | railties (~> 3.0) 56 | thor (~> 0.14) 57 | json (1.6.1) 58 | mail (2.3.0) 59 | i18n (>= 0.4.0) 60 | mime-types (~> 1.16) 61 | treetop (~> 1.4.8) 62 | mime-types (1.17.2) 63 | multi_json (1.0.3) 64 | polyglot (0.3.3) 65 | rack (1.3.5) 66 | rack-cache (1.1) 67 | rack (>= 0.4) 68 | rack-mount (0.8.3) 69 | rack (>= 1.0.0) 70 | rack-ssl (1.3.2) 71 | rack 72 | rack-test (0.6.1) 73 | rack (>= 1.0) 74 | rails (3.1.1) 75 | actionmailer (= 3.1.1) 76 | actionpack (= 3.1.1) 77 | activerecord (= 3.1.1) 78 | activeresource (= 3.1.1) 79 | activesupport (= 3.1.1) 80 | bundler (~> 1.0) 81 | railties (= 3.1.1) 82 | railties (3.1.1) 83 | actionpack (= 3.1.1) 84 | activesupport (= 3.1.1) 85 | rack-ssl (~> 1.3.2) 86 | rake (>= 0.8.7) 87 | rdoc (~> 3.4) 88 | thor (~> 0.14.6) 89 | rake (0.9.2.2) 90 | rdoc (3.11) 91 | json (~> 1.4) 92 | rspec-core (2.13.0) 93 | rspec-expectations (2.13.0) 94 | diff-lcs (>= 1.1.3, < 2.0) 95 | rspec-mocks (2.13.0) 96 | rspec-rails (2.13.0) 97 | actionpack (>= 3.0) 98 | activesupport (>= 3.0) 99 | railties (>= 3.0) 100 | rspec-core (~> 2.13.0) 101 | rspec-expectations (~> 2.13.0) 102 | rspec-mocks (~> 2.13.0) 103 | sass (3.1.10) 104 | sass-rails (3.1.4) 105 | actionpack (~> 3.1.0) 106 | railties (~> 3.1.0) 107 | sass (>= 3.1.4) 108 | sprockets (~> 2.0.0) 109 | tilt (~> 1.3.2) 110 | sprockets (2.0.3) 111 | hike (~> 1.2) 112 | rack (~> 1.0) 113 | tilt (~> 1.1, != 1.3.0) 114 | sqlite3 (1.3.4) 115 | thor (0.14.6) 116 | tilt (1.3.3) 117 | treetop (1.4.10) 118 | polyglot 119 | polyglot (>= 0.3.1) 120 | turn (0.8.3) 121 | ansi 122 | tzinfo (0.3.30) 123 | uglifier (1.0.4) 124 | execjs (>= 0.3.0) 125 | multi_json (>= 1.0.2) 126 | 127 | PLATFORMS 128 | ruby 129 | 130 | DEPENDENCIES 131 | coffee-rails (~> 3.1.1) 132 | crummy! 133 | haml 134 | jquery-rails 135 | rails (= 3.1.1) 136 | rspec-rails (~> 2.0) 137 | sass-rails (~> 3.1.4) 138 | sqlite3 139 | turn 140 | uglifier (>= 1.0.3) 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **Warning** 2 | > This is no longer maintained and hasn't been for quite some time. I no longer spend any time in the Ruby world. If you would like to maintain it, do reach out and ask. 3 | 4 | # Crummy 5 | 6 | [![Gem Version](https://badge.fury.io/rb/crummy.png)](http://badge.fury.io/rb/crummy) 7 | [![Build Status](https://secure.travis-ci.org/zachinglis/crummy.png)](http://travis-ci.org/zachinglis/crummy) 8 | [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/zachinglis/crummy) 9 | 10 | Crummy is a simple and tasty way to add breadcrumbs to your Rails applications. 11 | 12 | ## Install 13 | 14 | Simply add the dependency to your Gemfile: 15 | 16 | ```ruby 17 | gem "crummy", "~> 1.8.0" 18 | ``` 19 | 20 | # Example 21 | 22 | In your controllers you may add\_crumb either like a before\_filter or 23 | within a method (It is also available to views). 24 | 25 | ```ruby 26 | class ApplicationController 27 | add_crumb "Home", '/' 28 | end 29 | 30 | class BusinessController < ApplicationController 31 | add_crumb("Businesses") { |instance| instance.send :businesses_path } 32 | add_crumb("Comments", only: "comments") { |instance| instance.send :businesses_comments_path } 33 | before_filter :load_comment, only: "show" 34 | add_crumb :comment, only: "show" 35 | 36 | # Example for nested routes: 37 | add_crumb(:document) { [:account, :document] } 38 | 39 | def show 40 | add_crumb @business.display_name, @business 41 | end 42 | 43 | def load_comment 44 | @comment = Comment.find(params[:id]) 45 | end 46 | end 47 | ``` 48 | 49 | Then in your view: 50 | 51 | ```erb 52 | <%= render_crumbs %> 53 | ``` 54 | 55 | ## Html options for breadcrumb link 56 | 57 | You can set the html options with *link_html_options*. 58 | These are added to the *a* tag. 59 | 60 | ```ruby 61 | add_crumb "Home", '/', link_html_options: {title: "my link title"} 62 | ``` 63 | 64 | ##You can set html instead text in first parameter. 65 | If tag a present in this html, tag a not be a wrapper. 66 | 67 | ```ruby 68 | add_crumb "Support".html_safe, "", {} 69 | ``` 70 | 71 | ## Options for render\_crumbs 72 | 73 | `render_crumbs` renders the list of crumbs as either html or xml 74 | 75 | The output format. Can either be :xml or :html or :html\_list. Defaults 76 | to :html 77 | 78 | ```ruby 79 | format: (:html|:html_list|:xml) 80 | ``` 81 | 82 | The separator text. It does not assume you want spaces on either side so 83 | you must specify. Defaults to `»` for :html and 84 | `` for :xml 85 | 86 | ```ruby 87 | separator: string 88 | ``` 89 | 90 | Render links in the output. Defaults to *true* 91 | 92 | ```ruby 93 | links: false 94 | ``` 95 | 96 | Render 97 | [Richsnipet](http:/support.google.com/webmasters/bin/answer.py?hl=en&answer=99170&topic=1088472&ctx=topic/) 98 | Default to *false* 99 | 100 | ```ruby 101 | microdata: true 102 | ``` 103 | 104 | Optionally disable linking of the last crumb, Defaults to *true* 105 | 106 | ```ruby 107 | last_crumb_linked: false 108 | ``` 109 | 110 | With this option, output will be blank if there are no breadcrumbs. 111 | 112 | ```ruby 113 | skip_if_blank: true 114 | ``` 115 | 116 | ### Examples 117 | 118 | ```ruby 119 | render_crumbs #=> Home » Businesses 120 | render_crumbs separator: ' | ' #=> Home | Businesses 121 | render_crumbs format: :xml #=> HomeBusinesses 122 | render_crumbs format: :html_list #=>
  1. Home
  2. Businesses
123 | render_crumbs format: :html_list, :microdata => true 124 | #=>
  1. 125 | #
126 | add_crumb support_link, {:right_side => true, :links => "/support", :li_right_class => "pull-right hidden-phone"} 127 | #=>
  • 128 | #=> 129 | #=> Support 130 | #=> 131 | #=>
  • 132 | #=>
  • 133 | ``` 134 | 135 | A crumb with a nil argument for the link will output an unlinked crumb. 136 | 137 | With `format: :html_list` you can specify additional `params: :li_class, :ol_class, :ol_id` 138 | 139 | ### App-wide configuration 140 | 141 | You have the option to pre-configure any of the Crummy options in an 142 | application-wide configuration. The options above are available to 143 | configure, with the exception of `:separator`, as well as many others. 144 | 145 | The biggest difference is that `:separator` is not an option. Instead, 146 | you have format-specific configuration options: `:html_separator`, 147 | `:xml_separator`, and `:html_list_separator`. `:separator` can still be 148 | overridden in the view. 149 | 150 | Insert the following in a file named `config/initializers/crummy.rb`: 151 | 152 | ```ruby 153 | Crummy.configure do |config| 154 | config.format = :xml 155 | end 156 | ``` 157 | 158 | Possible parameters for configuration are: 159 | 160 | ```ruby 161 | :format 162 | :links 163 | :skip_if_blank 164 | :html_separator 165 | :xml_separator 166 | :html_list_separator 167 | :html_list_right_separator 168 | :first_class 169 | :last_class 170 | :ol_id 171 | :ol_class 172 | :li_class 173 | :li_right_class 174 | :microdata 175 | :last_crumb_linked 176 | :truncate 177 | :right_side 178 | ``` 179 | 180 | See `lib/crummy.rb` for a list of these parameters and their defaults. 181 | 182 | ###Individually for each crumb configuration: 183 | ```ruby 184 | add_crumb support_link, {:right_side => true, :links => "/support", : li_class => "my_class", :li_right_class => "pull-right hidden-phone"} 185 | ``` 186 | Simple add that parameter to options hash. 187 | 188 | 189 | ## Live example application 190 | 191 | An example application is available right inside this gem. That application is documented, see `example/README` for details about usage. 192 | 193 | ## Todo 194 | 195 | - Accept collections of models as a single argument 196 | - Accept instances of models as a single argument 197 | - Allow for variables in names. (The workaround is to do your own 198 | before\_filter for that currently) 199 | - Make a crumbs? type method 200 | 201 | ## Credits 202 | 203 | - [Zach Inglis](http://zachinglis.com) of [Superhero Studios](http://superhero-studios.com) 204 | - [Andrew Nesbitt](http://github.com/andrew) 205 | - [Rein Henrichs](http://reinh.com) 206 | - [Les Hill](http://blog.leshill.org/) 207 | - [Sandro Turriate](http://turriate.com/) 208 | - [Przemysław 209 | Kowalczyk](http://szeryf.wordpress.com/2008/06/13/easy-and-flexible-breadcrumbs-for-rails/) 210 | - feature ideas 211 | - [Sharad Jain](http://github.com/sjain) 212 | - [Max Riveiro](http://github.com/kavu) 213 | - [Kamil K. Lemański](http://kml.jogger.pl) 214 | - [Brian Cobb](http://bcobb.net/) 215 | - [Kir Shatrov](http://github.com/shatrov) ([Evrone 216 | company](http://evrone.com)) 217 | - [sugilog](http://github.com/sugilog) 218 | - [Trond Arve Nordheim](http://github.com/tanordheim) 219 | - [Jan Szumiec](http://github.com/jasiek) 220 | - [Jeff Browning](http://github.com/jbrowning) 221 | - [Bill Turner](http://github.com/billturner) 222 | 223 | **Copyright 2008-2013 Zach Inglis, released under the MIT license** 224 | -------------------------------------------------------------------------------- /lib/crummy/standard_renderer.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | module Crummy 4 | class StandardRenderer 5 | include ActionView::Helpers::UrlHelper 6 | include ActionView::Helpers::TagHelper unless self.included_modules.include?(ActionView::Helpers::TagHelper) 7 | ActionView::Helpers::TagHelper::BOOLEAN_ATTRIBUTES.merge([:itemscope].to_set) 8 | 9 | # Render the list of crumbs as either html or xml 10 | # 11 | # Takes 3 options: 12 | # The output format. Can either be xml or html. Default :html 13 | # :format => (:html|:xml) 14 | # The separator text. It does not assume you want spaces on either side so you must specify. Default +»+ for :html and +crumb+ for xml 15 | # :separator => string 16 | # Render links in the output. Default +true+ 17 | # :link => boolean 18 | # 19 | # Examples: 20 | # render_crumbs #=> Home » Businesses 21 | # render_crumbs :separator => ' | ' #=> Home | Businesses 22 | # render_crumbs :format => :xml #=> HomeBusinesses 23 | # render_crumbs :format => :html_list #=>
    1. Home
    2. Businesses
    24 | # 25 | # With :format => :html_list you can specify additional params: li_class, ol_class, ol_id 26 | # The only argument is for the separator text. It does not assume you want spaces on either side so you must specify. Defaults to +»+ 27 | # 28 | # render_crumbs(" . ") #=> Home . Businesses 29 | # 30 | def render_crumbs(crumbs, options = {}) 31 | 32 | options[:skip_if_blank] ||= Crummy.configuration.skip_if_blank 33 | return '' if options[:skip_if_blank] && crumbs.count < 1 34 | options[:format] ||= Crummy.configuration.format 35 | options[:separator] ||= Crummy.configuration.send(:"#{options[:format]}_separator") 36 | options[:right_separator] ||= Crummy.configuration.send(:"#{options[:format]}_right_separator") 37 | options[:links] ||= Crummy.configuration.links 38 | options[:first_class] ||= Crummy.configuration.first_class 39 | options[:last_class] ||= Crummy.configuration.last_class 40 | options[:microdata] ||= Crummy.configuration.microdata if options[:microdata].nil? 41 | options[:truncate] ||= Crummy.configuration.truncate if options[:truncate] 42 | options[:last_crumb_linked] = Crummy.configuration.last_crumb_linked if options[:last_crumb_linked].nil? 43 | options[:right_side] ||= Crummy.configuration.right_side 44 | 45 | last_hash = lambda {|o|k=o.map{|c| 46 | c.is_a?(Hash) ? (c.empty? ? nil: c) : nil}.compact 47 | k.empty? ? {} : k.last 48 | } 49 | local_global = lambda {|crumb, global_options, param_name| last_hash.call(crumb).has_key?(param_name.to_sym) ? last_hash.call(crumb)[param_name.to_sym] : global_options[param_name.to_sym]} 50 | 51 | case options[:format] 52 | when :html 53 | crumb_string = crumbs.map{|crumb|local_global.call(crumb, options, :right_side) ? nil : 54 | crumb_to_html(crumb, 55 | local_global.call(crumb, options, :links), 56 | local_global.call(crumb, options, :first_class), 57 | local_global.call(crumb, options, :last_class), 58 | (crumb == crumbs.first), 59 | (crumb == crumbs.last), 60 | local_global.call(crumb, options, :microdata), 61 | local_global.call(crumb, options, :last_crumb_linked), 62 | local_global.call(crumb, options, :truncate))}.compact.join(options[:separator]).html_safe 63 | crumb_string 64 | when :html_list 65 | # Let's set values for special options of html_list format 66 | options[:li_class] ||= Crummy.configuration.li_class 67 | options[:ol_class] ||= Crummy.configuration.ol_class 68 | options[:ol_id] ||= Crummy.configuration.ol_id 69 | options[:ol_id] = nil if options[:ol_id].blank? 70 | 71 | crumb_string = crumbs.map{|crumb|local_global.call(crumb, options, :right_side) ? nil : 72 | crumb_to_html_list(crumb, 73 | local_global.call(crumb, options, :links), 74 | local_global.call(crumb, options, :li_class), 75 | local_global.call(crumb, options, :first_class), 76 | local_global.call(crumb, options, :last_class), 77 | (crumb == crumbs.first), 78 | (crumb == crumbs.find_all{|crumb| 79 | !last_hash.call(crumb).fetch(:right_side,false)}.compact.last), 80 | local_global.call(crumb, options, :microdata), 81 | local_global.call(crumb, options, :last_crumb_linked), 82 | local_global.call(crumb, options, :truncate), 83 | local_global.call(crumb, options, :separator))}.compact.join.html_safe 84 | crumb_right_string = crumbs.reverse.map{|crumb|!local_global.call(crumb, options, :right_side) ? nil : 85 | 86 | crumb_to_html_list(crumb, 87 | local_global.call(crumb, options, :links), 88 | local_global.call(crumb, options, :li_right_class), 89 | local_global.call(crumb, options, :first_class), 90 | local_global.call(crumb, options, :last_class), 91 | (crumb == crumbs.first), 92 | (crumb == crumbs.find_all{|crumb|!local_global.call(crumb, options, :right_side)}.compact.last), 93 | local_global.call(crumb, options, :microdata), 94 | local_global.call(crumb, options, :last_crumb_linked), 95 | local_global.call(crumb, options, :truncate), 96 | local_global.call(crumb, options, :right_separator))}.compact.join.html_safe 97 | crumb_string = content_tag(:ol, 98 | crumb_string+crumb_right_string, 99 | :class => options[:ol_class], 100 | :id => options[:ol_id]) 101 | crumb_string 102 | when :xml 103 | crumbs.collect do |crumb| 104 | crumb_to_xml(crumb, 105 | local_global.call(crumb, options, :links), 106 | local_global.call(crumb, options, :separator), 107 | (crumb == crumbs.first), 108 | (crumb == crumbs.last)) 109 | end * '' 110 | else 111 | raise ArgumentError, "Unknown breadcrumb output format" 112 | end 113 | end 114 | 115 | private 116 | 117 | def crumb_to_html(crumb, links, first_class, last_class, is_first, is_last, with_microdata, last_crumb_linked, truncate) 118 | html_classes = [] 119 | html_classes << first_class if is_first 120 | html_classes << last_class if is_last 121 | name, url, options = crumb 122 | options = {} unless options.is_a?(Hash) 123 | can_link = url && links && (!is_last || last_crumb_linked) 124 | link_html_options = options[:link_html_options] || {} 125 | link_html_options[:class] = html_classes 126 | if with_microdata 127 | item_title = content_tag(:span, (truncate.present? ? name.truncate(truncate) : name), :itemprop => "title") 128 | html_options = {:itemscope => true, :itemtype => data_definition_url("Breadcrumb")} 129 | link_html_options[:itemprop] = "url" 130 | html_content = can_link ? link_to(item_title, url, link_html_options) : item_title 131 | content_tag(:div, html_content, html_options) 132 | else 133 | can_link ? link_to((truncate.present? ? name.truncate(truncate) : name), url, link_html_options) : (truncate.present? ? name.truncate(truncate) : name) 134 | end 135 | end 136 | 137 | def crumb_to_html_list(crumb, links, li_class, first_class, last_class, is_first, is_last, with_microdata, last_crumb_linked, truncate, separator='') 138 | name, url, options = crumb 139 | options = {} unless options.is_a?(Hash) 140 | can_link = url && links && (!is_last || last_crumb_linked) && !(/<\/a/ =~ name) 141 | html_classes = [] 142 | html_classes << first_class if is_first && !first_class.empty? 143 | html_classes << last_class if is_last && !last_class.empty? 144 | html_classes << li_class unless li_class.empty? 145 | html_options = html_classes.size > 0 ? {:class => html_classes.join(' ').strip} : {} 146 | 147 | if with_microdata 148 | html_options[:itemscope] = true 149 | html_options[:itemtype] = data_definition_url("Breadcrumb") 150 | item_title = content_tag(:span, (truncate.present? ? name.truncate(truncate) : name), :itemprop => "title") 151 | link_html_options = options[:link_html_options] || {} 152 | link_html_options[:itemprop] = "url" 153 | html_content = can_link ? link_to(item_title, url, link_html_options) : item_title 154 | else 155 | html_content = can_link ? link_to((truncate.present? ? name.truncate(truncate) : name), url, options[:link_html_options]) : content_tag(:span, (truncate.present? ? name.truncate(truncate) : name)) 156 | end 157 | content_tag(:li, html_content, html_options)+(/<\/li/ =~ separator ? 158 | separator : content_tag(:li, separator) unless separator.blank? || is_last) 159 | end 160 | 161 | def crumb_to_xml(crumb, links, separator, is_first, is_last) 162 | name, url = crumb 163 | content_tag(separator, name, :href => (url && links ? url : nil)) 164 | end 165 | 166 | def data_definition_url(type) 167 | "http://data-vocabulary.org/#{type}" 168 | end 169 | end 170 | end 171 | -------------------------------------------------------------------------------- /test/standard_renderer_test.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'bundler' 3 | Bundler.require(:test) 4 | require 'test/unit' 5 | 6 | require 'action_controller' 7 | require 'active_support/core_ext/string/output_safety' 8 | require 'action_dispatch/testing/assertions' 9 | require 'crummy' 10 | require 'crummy/standard_renderer' 11 | 12 | class StandardRendererTest < Test::Unit::TestCase 13 | include ActionDispatch::Assertions 14 | include Crummy 15 | 16 | def test_classes 17 | renderer = StandardRenderer.new 18 | assert_dom_equal('name', 19 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html)) 20 | assert_equal('
    1. name
    ', 21 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html_list)) 22 | assert_equal('name', 23 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :xml)) 24 | 25 | assert_dom_equal('name1 » name2', 26 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :html)) 27 | assert_equal('
    1. name1
    2. name2
    3. name3
    ', 28 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list)) 29 | assert_equal('
    1. name1
    2. /
    3. name2
    4. /
    5. name3
    ', 30 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :separator => " / ")) 31 | assert_equal('name1name2', 32 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :xml)) 33 | 34 | assert_dom_equal('', 35 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html, :microdata => true)) 36 | assert_equal('
    ', 37 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html_list, :microdata => true)) 38 | assert_equal('
    1. name
    ', 39 | renderer.render_crumbs([['name', 'url']], :format => :html_list, :ol_id => "crumbid", :ol_class => "crumbclass", :li_class => "liclass")) 40 | end 41 | 42 | def test_classes_last_crumb_not_linked 43 | renderer = StandardRenderer.new 44 | assert_equal('name', 45 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false)) 46 | assert_equal('
    1. name
    ', 47 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html_list, :last_crumb_linked => false)) 48 | assert_equal('name', 49 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :xml, :last_crumb_linked => false)) 50 | 51 | assert_dom_equal('name1 » name2', 52 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false)) 53 | assert_equal('
    1. name1
    2. name2
    3. name3
    ', 54 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :last_crumb_linked => false)) 55 | assert_equal('
    1. name1
    2. /
    3. name2
    4. /
    5. name3
    ', 56 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2'], ['name3', 'url3']], :li_class => "li_class", :first_class => 'first', :last_class => 'last', :format => :html_list, :separator => " / ", :last_crumb_linked => false)) 57 | assert_equal('name1name2', 58 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :first_class => 'first', :last_class => 'last', :format => :xml, :last_crumb_linked => false)) 59 | 60 | assert_equal('
    name
    ', 61 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html, :microdata => true, :last_crumb_linked => false)) 62 | assert_equal('
    1. name
    ', 63 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html_list, :microdata => true, :last_crumb_linked => false)) 64 | assert_equal('
    1. name
    ', 65 | renderer.render_crumbs([['name', 'url']], :format => :html_list, :ol_id => "crumbid", :ol_class => "crumbclass", :li_class => "liclass", :last_crumb_linked => false)) 66 | end 67 | 68 | def test_input_object_mutation 69 | renderer = StandardRenderer.new 70 | Crummy.configure do |config| 71 | config.microdata = false 72 | end 73 | 74 | name1 = 'name1' 75 | url1 = nil 76 | name2 = 'name2' 77 | url2 = nil 78 | 79 | renderer.render_crumbs([[name1, url1], [name2, url2]], :format => :html, :microdata => false) 80 | 81 | # Rendering the crumbs shouldn't alter the input objects. 82 | assert_equal('name1', name1); 83 | assert_equal(nil, url2); 84 | assert_equal('name2', name2); 85 | assert_equal(nil, url2); 86 | end 87 | 88 | def test_link_html_options 89 | renderer = StandardRenderer.new 90 | Crummy.configure do |config| 91 | config.microdata = false 92 | end 93 | 94 | assert_dom_equal('name', 95 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html)) 96 | 97 | assert_equal('name', 98 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false)) 99 | 100 | assert_equal('
    1. name
    ', 101 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html_list)) 102 | 103 | assert_equal('
    1. name
    ', 104 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html_list, :last_crumb_linked => false)) 105 | end 106 | 107 | def test_link_html_options_with_microdata 108 | renderer = StandardRenderer.new 109 | Crummy.configure do |config| 110 | config.microdata = true 111 | end 112 | 113 | assert_dom_equal('', 114 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html)) 115 | 116 | assert_equal('
    name
    ', 117 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false)) 118 | 119 | assert_equal('
    ', 120 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html_list)) 121 | 122 | assert_equal('
    1. name
    ', 123 | renderer.render_crumbs([['name', 'url', {:link_html_options => {:title => 'link title'}}]], :first_class => 'first', :last_class => 'last', :format => :html_list, :last_crumb_linked => false)) 124 | end 125 | 126 | def test_inline_configuration 127 | renderer = StandardRenderer.new 128 | Crummy.configure do |config| 129 | config.microdata = true 130 | config.last_crumb_linked = true 131 | end 132 | 133 | assert_no_match(/itemscope/, renderer.render_crumbs([['name', 'url']], :microdata => false)) 134 | assert_match(/href/, renderer.render_crumbs([['name', 'url']], :last_crumb_linked => true)) 135 | 136 | Crummy.configure do |config| 137 | config.microdata = false 138 | config.last_crumb_linked = true 139 | end 140 | 141 | assert_match(/itemscope/, renderer.render_crumbs([['name', 'url']], :microdata => true)) 142 | assert_no_match(/href/, renderer.render_crumbs([['name', 'url']], :last_crumb_linked => false)) 143 | end 144 | 145 | def test_configuration 146 | renderer = StandardRenderer.new 147 | # check defaults 148 | assert_equal " » ", Crummy.configuration.html_separator 149 | # adjust configuration 150 | Crummy.configure do |config| 151 | config.html_separator = " / " 152 | end 153 | assert_equal " / ", Crummy.configuration.html_separator 154 | end 155 | 156 | def test_configured_renderer 157 | renderer = StandardRenderer.new 158 | Crummy.configure do |config| 159 | config.html_separator = " / " 160 | end 161 | # using configured separator 162 | assert_dom_equal('name1 / name2', 163 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']])) 164 | # overriding configured separator 165 | assert_dom_equal('name1 | name2', 166 | renderer.render_crumbs([['name1', 'url1'], ['name2', 'url2']], :separator => " | ")) 167 | end 168 | 169 | def test_configured_renderer_with_microdata 170 | renderer = StandardRenderer.new 171 | Crummy.configure do |config| 172 | config.microdata = true 173 | end 174 | # using configured microdata setting 175 | assert_dom_equal('', 176 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html)) 177 | # last crumb not linked 178 | assert_equal('
    name
    ', 179 | renderer.render_crumbs([['name', 'url']], :first_class => 'first', :last_class => 'last', :format => :html, :last_crumb_linked => false)) 180 | end 181 | 182 | end 183 | --------------------------------------------------------------------------------