├── lib ├── tasks │ ├── .gitkeep │ └── cookbook.rake └── api_doc_loader.rb ├── public ├── favicon.ico ├── flash │ ├── flowplayer-3.1.5.swf │ └── flowplayer.controls-3.1.5.swf ├── robots.txt ├── 422.html ├── 404.html └── 500.html ├── vendor └── plugins │ └── .gitkeep ├── gitorials ├── index.markdown ├── screencast.markdown ├── two-minutes.markdown ├── gitorial.markdown └── subsite.markdown ├── manual └── generators │ ├── .gitkeep │ ├── i18n.markdown │ ├── assets.markdown │ ├── routes.markdown │ ├── resource.markdown │ ├── user_resource.markdown │ ├── controller.markdown │ ├── user_mailer.markdown │ ├── user_controller.markdown │ ├── user_model.markdown │ ├── test_framework.markdown │ ├── subsite_taglib.markdown │ ├── model.markdown │ ├── install_plugin.markdown │ ├── front_controller.markdown │ ├── subsite.markdown │ ├── admin_subsite.markdown │ ├── migration.markdown │ └── setup_wizard.markdown ├── app ├── assets │ ├── javascripts │ │ ├── admin │ │ │ └── .gitkeep │ │ ├── front │ │ │ └── .gitkeep │ │ ├── application │ │ │ ├── .gitkeep │ │ │ ├── highlighters │ │ │ │ ├── diff.js │ │ │ │ ├── css.js │ │ │ │ ├── ruby.js │ │ │ │ ├── javascript.js │ │ │ │ └── dryml.js │ │ │ ├── switcher.js │ │ │ └── code_highlighter.js │ │ ├── admin.js │ │ ├── application.js │ │ └── front.js │ ├── stylesheets │ │ ├── admin │ │ │ └── .gitkeep │ │ ├── front │ │ │ └── .gitkeep │ │ ├── application │ │ │ └── .gitkeep │ │ ├── admin.css │ │ ├── application.css.orig │ │ ├── front.css │ │ └── application.css │ └── images │ │ ├── rss.png │ │ ├── rails.png │ │ ├── body_bg.png │ │ ├── search_bg.png │ │ ├── app_name_bg.png │ │ ├── comment_bg.png │ │ ├── nicEditorIcons.gif │ │ ├── page_header_bg.png │ │ └── manual │ │ └── friendship-lifecycle.png ├── helpers │ ├── front_helper.rb │ ├── users_helper.rb │ ├── answers_helper.rb │ ├── images_helper.rb │ ├── manual_helper.rb │ ├── recipes_helper.rb │ ├── comments_helper.rb │ ├── questions_helper.rb │ ├── api_tag_defs_helper.rb │ ├── api_taglibs_helper.rb │ ├── application_helper.rb │ └── api_tag_comments_helper.rb ├── views │ ├── users │ │ ├── login.dryml │ │ └── show.dryml │ ├── questions │ │ ├── answered.dryml │ │ ├── open.dryml │ │ ├── index_for_recipe.dryml │ │ ├── new_for_user.dryml │ │ ├── atom.builder │ │ ├── index.dryml │ │ └── show.dryml │ ├── recipes │ │ ├── index.dryml │ │ ├── atom.builder │ │ ├── new_for_user.dryml │ │ ├── show.dryml │ │ └── edit.dryml │ ├── user_mailer │ │ └── forgot_password.erb │ ├── taglibs │ │ └── themes │ │ │ ├── clean │ │ │ └── clean.dryml │ │ │ └── clean-sidemenu │ │ │ └── clean-sidemenu.dryml │ ├── tutorials │ │ ├── index.dryml │ │ └── show.dryml │ ├── manual │ │ ├── index.dryml │ │ ├── manual_section.dryml │ │ └── manual_subsection.dryml │ ├── api_plugins │ │ ├── index.dryml │ │ └── show.dryml │ ├── api_taglibs │ │ └── show.dryml │ ├── comments │ │ └── atom.builder │ ├── api_tag_defs │ │ ├── show.dryml │ │ └── tagdef.dryml │ └── front │ │ └── index.dryml ├── controllers │ ├── api_taglibs_controller.rb │ ├── answers_controller.rb │ ├── api_tag_comments_controller.rb │ ├── api_plugins_controller.rb │ ├── front_controller.rb │ ├── images_controller.rb │ ├── users_controller.rb │ ├── agility_controller.rb │ ├── application_controller.rb │ ├── api_tag_defs_controller.rb │ ├── comments_controller.rb │ ├── recipes_controller.rb │ ├── questions_controller.rb │ ├── tutorials_controller.rb │ └── manual_controller.rb ├── models │ ├── comment.rb │ ├── user_mailer.rb │ ├── answer.rb │ ├── guest.rb │ ├── api_tag_comment.rb │ ├── question.rb │ ├── owned_model.rb │ ├── tagging.rb │ ├── recipe.rb │ ├── tag.rb │ ├── image.rb │ ├── api_taglib.rb │ ├── api_plugin.rb │ ├── api_tag_def.rb │ ├── user.rb │ └── gitorial.rb └── rich_types │ └── optional_markdown.rb ├── taglibs └── paperclip_with_hobo ├── test ├── fixtures │ ├── images.yml │ ├── tags.yml │ ├── answers.yml │ ├── api_taglibs.yml │ ├── api_tags.yml │ ├── comments.yml │ ├── questions.yml │ ├── recipes.yml │ ├── taggings.yml │ ├── api_tag_comments.yml │ └── users.yml ├── unit │ ├── tag_test.rb │ ├── answer_test.rb │ ├── image_test.rb │ ├── recipe_test.rb │ ├── user_test.rb │ ├── api_tag_test.rb │ ├── comment_test.rb │ ├── question_test.rb │ ├── tagging_test.rb │ ├── api_taglib_test.rb │ └── api_tag_comment_test.rb ├── functional │ ├── manual_controller_test.rb │ ├── images_controller_test.rb │ ├── users_controller_test.rb │ ├── answers_controller_test.rb │ ├── api_tags_controller_test.rb │ ├── comments_controller_test.rb │ ├── recipes_controller_test.rb │ ├── api_taglibs_controller_test.rb │ ├── questions_controller_test.rb │ ├── api_tag_comments_controller_test.rb │ └── front_controller_test.rb ├── performance │ └── browsing_test.rb └── test_helper.rb ├── .gitignore ├── config ├── environment.rb ├── boot.rb ├── initializers │ ├── mime_types.rb │ ├── hobo.rb │ ├── inflections.rb │ ├── backtrace_silencers.rb │ ├── secret_token.rb │ ├── session_store.rb │ └── new_rails_defaults.rb ├── database.yml ├── locales │ └── en.yml ├── setup_load_paths.rb ├── environments │ ├── development-old.rb │ ├── production-old.rb │ ├── test-old.rb │ ├── development.rb │ ├── test.rb │ └── production.rb ├── deploy.rb ├── application.rb ├── boot-old.rb ├── environment-old.rb └── routes.rb ├── doc └── README_FOR_APP ├── db ├── migrate │ ├── 20090512210544_add_library_to_taglibs.rb │ ├── 20081024151700_add_source_code_to_tag_defs.rb │ ├── 20081021144306_change_tag_name_field_to_tag.rb │ ├── 20120311165826_add_position_to_plugins.rb │ ├── 20081017074334_allow_optional_markdown_in_answers.rb │ ├── 20090112154358_add_short_description_to_taglibs.rb │ ├── 20081024131133_add_short_description_to_tag_defs.rb │ ├── 20081016075217_add_subject_to_questions_and_body_to_answers.rb │ ├── 20091029175503_hobo_migration_image_file_size_to_integer.rb │ ├── 20081021160838_add_description_to_taglibs_and_rename_on_tagdefs.rb │ ├── 20081024161219_add_comments_for_api_tags.rb │ ├── 20081027152829_add_paperclip_fields_for_images.rb │ ├── 20081021123705_adding_models_for_api_referece.rb │ ├── 20120311060921_add_missing_indices.rb │ ├── 20120311061300_move_tag_defs_to_14.rb │ └── 20081015130022_initial_models.rb ├── seeds.rb └── schema.rb ├── script └── rails ├── .project ├── Rakefile ├── .gitmodules ├── README ├── Gemfile └── Gemfile.lock /lib/tasks/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /vendor/plugins/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gitorials/index.markdown: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /manual/generators/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/admin/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/front/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/admin/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/front/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/helpers/front_helper.rb: -------------------------------------------------------------------------------- 1 | module FrontHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/answers_helper.rb: -------------------------------------------------------------------------------- 1 | module AnswersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/images_helper.rb: -------------------------------------------------------------------------------- 1 | module ImagesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/manual_helper.rb: -------------------------------------------------------------------------------- 1 | module ManualHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/recipes_helper.rb: -------------------------------------------------------------------------------- 1 | module RecipesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/comments_helper.rb: -------------------------------------------------------------------------------- 1 | module CommentsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/questions_helper.rb: -------------------------------------------------------------------------------- 1 | module QuestionsHelper 2 | end 3 | -------------------------------------------------------------------------------- /taglibs/paperclip_with_hobo: -------------------------------------------------------------------------------- 1 | ../vendor/plugins/paperclip_with_hobo -------------------------------------------------------------------------------- /app/helpers/api_tag_defs_helper.rb: -------------------------------------------------------------------------------- 1 | module ApiTagDefsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api_taglibs_helper.rb: -------------------------------------------------------------------------------- 1 | module ApiTaglibsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/api_tag_comments_helper.rb: -------------------------------------------------------------------------------- 1 | module ApiTagCommentsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/assets/images/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/rss.png -------------------------------------------------------------------------------- /app/views/users/login.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/rails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/rails.png -------------------------------------------------------------------------------- /app/assets/images/body_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/body_bg.png -------------------------------------------------------------------------------- /app/assets/images/search_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/search_bg.png -------------------------------------------------------------------------------- /app/assets/images/app_name_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/app_name_bg.png -------------------------------------------------------------------------------- /app/assets/images/comment_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/comment_bg.png -------------------------------------------------------------------------------- /public/flash/flowplayer-3.1.5.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/public/flash/flowplayer-3.1.5.swf -------------------------------------------------------------------------------- /app/assets/images/nicEditorIcons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/nicEditorIcons.gif -------------------------------------------------------------------------------- /app/assets/images/page_header_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/page_header_bg.png -------------------------------------------------------------------------------- /public/flash/flowplayer.controls-3.1.5.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/public/flash/flowplayer.controls-3.1.5.swf -------------------------------------------------------------------------------- /test/fixtures/images.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/tags.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/answers.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/api_taglibs.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/api_tags.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/comments.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/questions.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/recipes.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /test/fixtures/taggings.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /app/assets/images/manual/friendship-lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tslocke/hobocookbook/HEAD/app/assets/images/manual/friendship-lifecycle.png -------------------------------------------------------------------------------- /app/views/questions/answered.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Answered Questions 4 | -------------------------------------------------------------------------------- /test/fixtures/api_tag_comments.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | two: 6 | id: 2 7 | -------------------------------------------------------------------------------- /app/views/questions/open.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Open Questions - Please Answer! 4 | -------------------------------------------------------------------------------- /app/views/questions/index_for_recipe.dryml: -------------------------------------------------------------------------------- 1 | 2 | Questions that link to this Recipe 3 | -------------------------------------------------------------------------------- /app/views/recipes/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | 3 | # one: 4 | # column: value 5 | # 6 | # two: 7 | # column: value 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle 2 | db/*.sqlite3 3 | log/*.log 4 | tmp/ 5 | 6 | .DS_Store 7 | vendor/plugins/footnotes-edge 8 | tmtags 9 | app/views/taglibs/auto 10 | public/img/* 11 | rails3app 12 | .idea/ -------------------------------------------------------------------------------- /app/controllers/api_taglibs_controller.rb: -------------------------------------------------------------------------------- 1 | class ApiTaglibsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | caches_page :show 6 | 7 | auto_actions :show 8 | 9 | end 10 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the rails application 2 | require File.expand_path('../application', __FILE__) 3 | require 'thread' 4 | 5 | # Initialize the rails application 6 | Hobocookbook::Application.initialize! 7 | -------------------------------------------------------------------------------- /test/unit/tag_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class TagTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/unit/answer_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class AnswerTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/image_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ImageTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/recipe_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class RecipeTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/user_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class UserTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/answers_controller.rb: -------------------------------------------------------------------------------- 1 | class AnswersController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions_for :question, :create 6 | 7 | auto_actions_for :user, :index 8 | 9 | end 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/functional/manual_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ManualControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/api_tag_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTagTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/comment_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class CommentTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/question_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class QuestionTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/tagging_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class TaggingTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/unit/api_taglib_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTaglibTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/unit/api_tag_comment_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTagCommentTest < ActiveSupport::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /app/controllers/api_tag_comments_controller.rb: -------------------------------------------------------------------------------- 1 | class ApiTagCommentsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :update, :destroy 6 | 7 | auto_actions_for :api_tag_def, [:create] 8 | 9 | end 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/functional/images_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ImagesControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/users_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class UsersControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/answers_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class AnswersControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/api_tags_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTagsControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/comments_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class CommentsControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/recipes_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class RecipesControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/api_taglibs_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTaglibsControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/questions_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class QuestionsControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/functional/api_tag_comments_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | 3 | class ApiTagCommentsControllerTest < ActionController::TestCase 4 | # Replace this with your real tests. 5 | def test_truth 6 | assert true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20090512210544_add_library_to_taglibs.rb: -------------------------------------------------------------------------------- 1 | class AddLibraryToTaglibs < ActiveRecord::Migration 2 | def self.up 3 | add_column :api_taglibs, :library, :string 4 | end 5 | 6 | def self.down 7 | remove_column :api_taglibs, :library 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20081024151700_add_source_code_to_tag_defs.rb: -------------------------------------------------------------------------------- 1 | class AddSourceCodeToTagDefs < ActiveRecord::Migration 2 | def self.up 3 | add_column :api_tag_defs, :source, :text 4 | end 5 | 6 | def self.down 7 | remove_column :api_tag_defs, :source 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20081021144306_change_tag_name_field_to_tag.rb: -------------------------------------------------------------------------------- 1 | class ChangeTagNameFieldToTag < ActiveRecord::Migration 2 | def self.up 3 | rename_column :api_tag_defs, :name, :tag 4 | end 5 | 6 | def self.down 7 | rename_column :api_tag_defs, :tag, :name 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20120311165826_add_position_to_plugins.rb: -------------------------------------------------------------------------------- 1 | class AddPositionToPlugins < ActiveRecord::Migration 2 | def self.up 3 | add_column :api_plugins_14, :position, :integer 4 | end 5 | 6 | def self.down 7 | remove_column :api_plugins_14, :position 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/controllers/api_plugins_controller.rb: -------------------------------------------------------------------------------- 1 | class ApiPluginsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | caches_page :index, :show 6 | 7 | auto_actions :index, :show 8 | 9 | def index 10 | hobo_index(:order => "position") 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20081017074334_allow_optional_markdown_in_answers.rb: -------------------------------------------------------------------------------- 1 | class AllowOptionalMarkdownInAnswers < ActiveRecord::Migration 2 | def self.up 3 | add_column :answers, :markdown, :boolean 4 | end 5 | 6 | def self.down 7 | remove_column :answers, :markdown 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /config/initializers/hobo.rb: -------------------------------------------------------------------------------- 1 | #require 'maruku' 2 | 3 | # Load Hobo from the gem if is not already loaded 4 | # (i.e. if the plugin is not present) 5 | 6 | unless defined? Hobo 7 | gem 'hobo' 8 | require 'hobo' 9 | end 10 | 11 | #Hobo::ModelRouter.reload_routes_on_every_request = true 12 | -------------------------------------------------------------------------------- /test/performance/browsing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'rails/performance_test_help' 3 | 4 | # Profiling results for each test method are written to tmp/performance. 5 | class BrowsingTest < ActionDispatch::PerformanceTest 6 | def test_homepage 7 | get '/' 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/comment.rb: -------------------------------------------------------------------------------- 1 | class Comment < ActiveRecord::Base 2 | 3 | hobo_model # Don't put anything above this 4 | 5 | fields do 6 | body :optional_markdown 7 | markdown :boolean 8 | timestamps 9 | end 10 | 11 | belongs_to :recipe 12 | 13 | include OwnedModel 14 | 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20090112154358_add_short_description_to_taglibs.rb: -------------------------------------------------------------------------------- 1 | class AddShortDescriptionToTaglibs < ActiveRecord::Migration 2 | def self.up 3 | add_column :api_taglibs, :short_description, :text 4 | end 5 | 6 | def self.down 7 | remove_column :api_taglibs, :short_description 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20081024131133_add_short_description_to_tag_defs.rb: -------------------------------------------------------------------------------- 1 | class AddShortDescriptionToTagDefs < ActiveRecord::Migration 2 | def self.up 3 | add_column :api_tag_defs, :short_description, :text 4 | end 5 | 6 | def self.down 7 | remove_column :api_tag_defs, :short_description 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/models/user_mailer.rb: -------------------------------------------------------------------------------- 1 | class UserMailer < ActionMailer::Base 2 | 3 | def forgot_password(user, key) 4 | @user, @key = user, key 5 | mail( :subject => "#{app_name} -- forgotten password", 6 | :to => user.email_address, 7 | :from => "no-reply@#{host}") 8 | end 9 | 10 | end 11 | -------------------------------------------------------------------------------- /app/models/answer.rb: -------------------------------------------------------------------------------- 1 | class Answer < ActiveRecord::Base 2 | 3 | hobo_model # Don't put anything above this 4 | 5 | fields do 6 | body OptionalMarkdown 7 | markdown :boolean 8 | timestamps 9 | end 10 | 11 | belongs_to :recipe 12 | belongs_to :question 13 | 14 | include OwnedModel 15 | 16 | end 17 | -------------------------------------------------------------------------------- /app/views/user_mailer/forgot_password.erb: -------------------------------------------------------------------------------- 1 | <%= @user %>, 2 | 3 | If you have forgotten your password for <%= @app_name %>, you can chose 4 | a new one by clicking on this link: 5 | 6 | <%= user_reset_password_url :host => @host, :id => @user, :key => @key %> 7 | 8 | Thanks very much, 9 | 10 | The <%= @app_name %> team. 11 | -------------------------------------------------------------------------------- /app/assets/stylesheets/admin.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the stylesheet manifest file for the admin subsite. 3 | * Files or plugins referenced from here or placed in the admin/ 4 | * directory will be included. 5 | * 6 | *= require_self 7 | *= require application 8 | *= require hobo_clean_admin 9 | *= require_tree ./admin 10 | */ 11 | -------------------------------------------------------------------------------- /app/controllers/front_controller.rb: -------------------------------------------------------------------------------- 1 | class FrontController < ApplicationController 2 | 3 | hobo_controller 4 | 5 | skip_before_filter :verify_authenticity_token, :only => [:search] 6 | 7 | def index; end 8 | 9 | def search 10 | if params[:query] 11 | site_search(params[:query]) 12 | end 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /script/rails: -------------------------------------------------------------------------------- 1 | #!~/.rvm/rubies/ruby-1.8.7-p334/bin/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 | -------------------------------------------------------------------------------- /app/views/taglibs/themes/clean/clean.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/highlighters/diff.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("diff", { 2 | add: { 3 | exp : /(\n|^)([+].*)(?=\n|$)/ 4 | }, 5 | remove: { 6 | exp : /(\n|^)([-].*)(?=\n|$)/ 7 | }, 8 | line_number: { 9 | exp : /(\n|^)(@@.*)(?=\n|$)/ 10 | }, 11 | file: { 12 | exp : /(\n|^)([:]{3}.*)(?=\n|$)/ 13 | }, 14 | }); -------------------------------------------------------------------------------- /app/models/guest.rb: -------------------------------------------------------------------------------- 1 | class Guest < Hobo::Model::Guest 2 | 3 | def can_update?(obj, field) 4 | false 5 | end 6 | 7 | def can_delete?(obj) 8 | false 9 | end 10 | 11 | def can_create?(obj) 12 | false 13 | end 14 | 15 | def can_view?(obj, field) 16 | true 17 | end 18 | 19 | def administrator? 20 | false 21 | end 22 | 23 | end 24 | -------------------------------------------------------------------------------- /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 => 'Daley', :city => cities.first) 8 | -------------------------------------------------------------------------------- /app/controllers/images_controller.rb: -------------------------------------------------------------------------------- 1 | class ImagesController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :create, :destroy 6 | 7 | def create 8 | # The iframe based image uploader is not recognised as an ajax request, 9 | # so we have to manually force the ajax response 10 | hobo_create { hobo_ajax_response } 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css.orig: -------------------------------------------------------------------------------- 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 | */ -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: sqlite3 3 | database: db/development.sqlite3 4 | timeout: 5000 5 | # adapter: mysql 6 | # database: hobocookbook_development 7 | # encoding: utf8 8 | 9 | test: 10 | adapter: sqlite3 11 | database: db/test.sqlite3 12 | timeout: 5000 13 | 14 | production: 15 | adapter: mysql 16 | database: hobocookbook_production 17 | encoding: utf8 18 | -------------------------------------------------------------------------------- /db/migrate/20081016075217_add_subject_to_questions_and_body_to_answers.rb: -------------------------------------------------------------------------------- 1 | class AddSubjectToQuestionsAndBodyToAnswers < ActiveRecord::Migration 2 | def self.up 3 | add_column :answers, :body, :text 4 | 5 | add_column :questions, :subject, :string 6 | end 7 | 8 | def self.down 9 | remove_column :answers, :body 10 | 11 | remove_column :questions, :subject 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/assets/stylesheets/front.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the stylesheet manifest file for the front subsite (which 3 | * is your whole application if you don't have any subsites). Files 4 | * or plugins referenced from here or placed in the front/ directory 5 | * will be included. 6 | * 7 | *= require_self 8 | *= require hobo_clean 9 | *= require jquery-ui/redmond 10 | *= require application 11 | *= require_tree ./front 12 | */ 13 | -------------------------------------------------------------------------------- /app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is the global stylesheet manifest file. Files or plugins 3 | * referenced from here or placed in the application/ directory will be 4 | * included in all subsites. This file is included by front.css and all 5 | * subsites. 6 | * 7 | *= require_self 8 | *= require hobo_rapid 9 | *= require hobo_jquery 10 | *= require hobo_jquery_ui 11 | *= require_tree ./application 12 | */ 13 | -------------------------------------------------------------------------------- /app/models/api_tag_comment.rb: -------------------------------------------------------------------------------- 1 | class ApiTagComment < ActiveRecord::Base 2 | 3 | # so we can coexist with other 4 | # versions of the cookbook 5 | set_table_name "api_tag_comments_14" 6 | 7 | hobo_model # Don't put anything above this 8 | 9 | fields do 10 | body :optional_markdown 11 | markdown :boolean 12 | timestamps 13 | end 14 | 15 | belongs_to :api_tag_def 16 | 17 | include OwnedModel 18 | 19 | end 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /db/migrate/20091029175503_hobo_migration_image_file_size_to_integer.rb: -------------------------------------------------------------------------------- 1 | class HoboMigrationImageFileSizeToInteger < ActiveRecord::Migration 2 | def self.up 3 | add_column :images, :image_updated_at, :datetime 4 | change_column :images, :image_file_size, :integer, :limit => 4 5 | end 6 | 7 | def self.down 8 | remove_column :images, :image_updated_at 9 | change_column :images, :image_file_size, :string 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/switcher.js: -------------------------------------------------------------------------------- 1 | jQuery(document).ready(function($) { 2 | $("#version-switcher").val("1.4").on("change", function() { 3 | if($(this).val() == "1.0") { 4 | window.location = "http://cookbook-1.0.hobocentral.net"+window.location.pathname; 5 | } else if($(this).val() == "1.3") { 6 | window.location = "http://cookbook-1.3.hobocentral.net"+window.location.pathname; 7 | } 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /app/views/tutorials/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

Hobo Tutorials

9 | 10 |

<-- look over there!

11 |
12 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /db/migrate/20081021160838_add_description_to_taglibs_and_rename_on_tagdefs.rb: -------------------------------------------------------------------------------- 1 | class AddDescriptionToTaglibsAndRenameOnTagdefs < ActiveRecord::Migration 2 | def self.up 3 | rename_column :api_tag_defs, :comment, :description 4 | 5 | add_column :api_taglibs, :description, :text 6 | end 7 | 8 | def self.down 9 | rename_column :api_tag_defs, :description, :comment 10 | 11 | remove_column :api_taglibs, :description 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/question.rb: -------------------------------------------------------------------------------- 1 | class Question < ActiveRecord::Base 2 | 3 | hobo_model # Don't put anything above this 4 | 5 | fields do 6 | subject :string, :name => true 7 | description :optional_markdown 8 | markdown :boolean 9 | timestamps 10 | end 11 | 12 | has_many :answers, :dependent => :destroy 13 | has_many :recipes, :through => :answers, :uniq => true 14 | 15 | children :answers 16 | 17 | include OwnedModel 18 | 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20081024161219_add_comments_for_api_tags.rb: -------------------------------------------------------------------------------- 1 | class AddCommentsForApiTags < ActiveRecord::Migration 2 | def self.up 3 | create_table :api_tag_comments do |t| 4 | t.text :body 5 | t.boolean :markdown 6 | t.datetime :created_at 7 | t.datetime :updated_at 8 | t.integer :api_tag_def_id 9 | t.integer :user_id 10 | end 11 | end 12 | 13 | def self.down 14 | drop_table :api_tag_comments 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | 3 | hobo_user_controller 4 | 5 | auto_actions :all, :except => [ :new, :create ] 6 | 7 | def do_signup 8 | unless verify_recaptcha 9 | self.this = User::Lifecycle.creators[:signup].candidate(current_user, params[:user]) 10 | verify_recaptcha this 11 | render :action => :signup 12 | return 13 | end 14 | hobo_do_signup 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /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 | Hobocookbook::Application.config.secret_token = 'REPLACE_ME_WITH_A_REAL_SECRET_BLAH_BLAH_BLAH_BLAH_BLAH_BLAH' 8 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Hobocookbook::Application.config.session_store :cookie_store, :key => '_hobocookbook_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 | # Hobocookbook::Application.config.session_store :active_record_store 9 | -------------------------------------------------------------------------------- /app/views/manual/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 |

The Hobo Manual

9 | 10 |

Being very much a work in progress...

11 |

<-- look over there!

12 |
13 |
14 | 15 |
16 | -------------------------------------------------------------------------------- /app/views/api_plugins/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |
10 |
11 | 12 |

<%= this.name.titleize %>

13 | 14 | 15 |
16 |
17 |
18 | 19 |
20 | -------------------------------------------------------------------------------- /db/migrate/20081027152829_add_paperclip_fields_for_images.rb: -------------------------------------------------------------------------------- 1 | class AddPaperclipFieldsForImages < ActiveRecord::Migration 2 | def self.up 3 | add_column :images, :image_file_name, :string 4 | add_column :images, :image_content_type, :string 5 | add_column :images, :image_file_size, :string 6 | end 7 | 8 | def self.down 9 | remove_column :images, :image_file_name 10 | remove_column :images, :image_content_type 11 | remove_column :images, :image_file_size 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | hobocookbook 4 | 5 | 6 | 7 | 8 | 9 | com.aptana.ide.core.unifiedBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.radrails.rails.core.railsnature 16 | com.aptana.ruby.core.rubynature 17 | 18 | 19 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Sample localization file for English. Add more files in this directory for other locales. 2 | # See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. 3 | 4 | en: 5 | activerecord: 6 | attributes: 7 | answer: 8 | body: 9 | recipe: Enter keywords from the name of a recipe 10 | api_tag_comment: 11 | body: 12 | 13 | attribute_help: 14 | answer: 15 | recipe: Enter keywords from the name of a recipe 16 | -------------------------------------------------------------------------------- /config/setup_load_paths.rb: -------------------------------------------------------------------------------- 1 | 2 | if ENV['MY_RUBY_HOME'] && ENV['MY_RUBY_HOME'].include?('rvm') 3 | begin 4 | rvm_path = File.dirname(File.dirname(ENV['MY_RUBY_HOME'])) 5 | rvm_lib_path = File.join(rvm_path, 'lib') 6 | $LOAD_PATH.unshift rvm_lib_path 7 | require 'rvm' 8 | RVM.use_from_path! File.dirname(File.dirname(__FILE__)) 9 | rescue LoadError 10 | # RVM is unavailable at this point. 11 | raise "RVM ruby lib is currently unavailable." 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /gitorials/screencast.markdown: -------------------------------------------------------------------------------- 1 | Watch Hobo in action! (Full-screen recommended) 4 | 5 | 7 | 8 | 9 | Higher quality: quicktime | vimeo 10 | 11 | -------------------------------------------------------------------------------- /app/controllers/agility_controller.rb: -------------------------------------------------------------------------------- 1 | class AgilityController < ApplicationController 2 | 3 | def show 4 | filename = "gitorials/agility.markdown" 5 | @page = (params[:page]).to_i 6 | markdown = File.read("#{Rails.root}/#{filename}") 7 | m2 = markdown.match(/^gitorial-#{'%03i' % (@page-1)}.*?$(.*)^gitorial-#{'%03i' % @page}/m) 8 | m2 = m2.nil? ? markdown.match(/^gitorial-#{'%03i' % (@page-2)}.*?$(.*)^gitorial-#{'%03i' % @page}/m)[1] : m2[1] 9 | @content = HoboFields::MarkdownString.new(m2) 10 | end 11 | 12 | end 13 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/highlighters/css.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("css", { 2 | comment : { 3 | exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\// 4 | }, 5 | keywords : { 6 | exp : /@\w[\w\s]*/ 7 | }, 8 | selectors : { 9 | exp : "([\\w-:\\[.#][^{};>]*)(?={)" 10 | }, 11 | properties : { 12 | exp : "([\\w-]+)(?=\\s*:)" 13 | }, 14 | units : { 15 | exp : /([0-9])(em|en|px|%|pt)\b/, 16 | replacement : "$1$2" 17 | }, 18 | urls : { 19 | exp : /url\([^\)]*\)/ 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /app/views/recipes/atom.builder: -------------------------------------------------------------------------------- 1 | atom_feed do |feed| 2 | feed.title("HoboCookbook - recipes") 3 | feed.updated(@recipes.first.created_at) 4 | 5 | @recipes.each do |recipe| 6 | feed.entry(recipe) do |entry| 7 | entry.title("#{recipe.name}#{' (pending moderation)' if recipe.user.state=='pending'}") 8 | entry.content(recipe.body.to_html, :type => 'html') 9 | entry.updated(recipe.updated_at) 10 | 11 | entry.author do |author| 12 | author.name(recipe.user.username) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/highlighters/ruby.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("ruby",{ 2 | comment : { 3 | exp : /#[^\n]+/ 4 | }, 5 | brackets : { 6 | exp : /\(|\)/ 7 | }, 8 | string : { 9 | exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"/ 10 | }, 11 | keywords : { 12 | exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise)\b/ 13 | }, 14 | /* Added by Shelly Fisher (shelly@agileevolved.com) */ 15 | symbol : { 16 | exp : /([^:])(:[A-Za-z0-9_!?]+)/ 17 | } 18 | }); -------------------------------------------------------------------------------- /app/assets/javascripts/admin.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file for the admin subsite. It will be 2 | // compiled into including all the files listed below. Add new 3 | // JavaScript/Coffee code in separate files in the admin 4 | // directory and they'll automatically be included in the compiled 5 | // file accessible from http://example.com/assets/admin.js It's 6 | // not advisable to add code directly here, but if you do, it'll 7 | // appear at the bottom of the the compiled file. 8 | // 9 | //= require application 10 | //= require hobo_clean_admin 11 | //= require_tree ./admin 12 | -------------------------------------------------------------------------------- /app/models/owned_model.rb: -------------------------------------------------------------------------------- 1 | OwnedModel = classy_module do 2 | 3 | belongs_to :user, :creator => true 4 | 5 | 6 | def create_permitted? 7 | acting_user.signed_up? && user == acting_user 8 | end 9 | 10 | def update_permitted? 11 | acting_user.administrator? || (acting_user == user && !user_changed?) 12 | end 13 | 14 | def destroy_permitted? 15 | acting_user.administrator? || acting_user == user 16 | end 17 | 18 | def view_permitted?(attribute) 19 | acting_user == user || acting_user.administrator? || user.state=="active" 20 | end 21 | 22 | end 23 | -------------------------------------------------------------------------------- /app/views/api_taglibs/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

<%= this.name.titleize %>

10 |
11 |
12 |
13 | Edit this page 14 |
15 | 16 | 17 | 18 |
19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /test/functional/front_controller_test.rb: -------------------------------------------------------------------------------- 1 | require File.dirname(__FILE__) + '/../test_helper' 2 | require 'front_controller' 3 | 4 | # Re-raise errors caught by the controller. 5 | class FrontController; def rescue_action(e) raise e end; end 6 | 7 | class FrontControllerTest < Test::Unit::TestCase 8 | def setup 9 | @controller = FrontController.new 10 | @request = ActionController::TestRequest.new 11 | @response = ActionController::TestResponse.new 12 | end 13 | 14 | # Replace this with your real tests. 15 | def test_truth 16 | assert true 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/views/api_plugins/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

<%= this.name.titleize %>

10 |
11 |
12 |
13 | Edit this page 14 |
15 | 16 | 17 | 18 |
19 |
20 | 21 |
22 | -------------------------------------------------------------------------------- /manual/generators/i18n.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/i18n.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:i18n [en it ...] 10 | 11 | 12 | ## Runtime options 13 | 14 | 15 | 16 | -q, [--quiet] # Suppress status output 17 | -s, [--skip] # Skip files that already exist 18 | -f, [--force] # Overwrite files that already exist 19 | -p, [--pretend] # Run but do not make any changes 20 | 21 | 22 | ## Description 23 | 24 | 25 | 26 | 27 | Copies the locale files for the specified locales. 28 | -------------------------------------------------------------------------------- /app/models/tagging.rb: -------------------------------------------------------------------------------- 1 | # NOTE- Tagging is not implemnted 2 | 3 | class Tagging < ActiveRecord::Base 4 | 5 | hobo_model # Don't put anything above this 6 | 7 | fields do 8 | timestamps 9 | end 10 | 11 | belongs_to :tag 12 | belongs_to :recipe 13 | 14 | # --- Hobo Permissions --- # 15 | 16 | def create_permitted? 17 | acting_user.administrator? 18 | end 19 | 20 | def update_permitted? 21 | acting_user.administrator? 22 | end 23 | 24 | def destroy_permitted? 25 | acting_user.administrator? 26 | end 27 | 28 | def view_permitted?(attribute) 29 | true 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /app/models/recipe.rb: -------------------------------------------------------------------------------- 1 | class Recipe < ActiveRecord::Base 2 | 3 | hobo_model # Don't put anything above this 4 | 5 | fields do 6 | name :string 7 | body :markdown 8 | timestamps 9 | end 10 | 11 | has_many :comments, :dependent => :destroy 12 | has_many :images, :dependent => :destroy 13 | has_many :answers, :dependent => :destroy 14 | has_many :questions, :through => :answers, :uniq => true 15 | 16 | children :comments, :images 17 | 18 | set_default_order "updated_at desc" 19 | 20 | # has_many :taggings 21 | # has_many :tags, :through => :taggings 22 | 23 | include OwnedModel 24 | 25 | end 26 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | require 'rake' 6 | 7 | Hobocookbook::Application.load_tasks 8 | 9 | 10 | 11 | require(File.join(File.dirname(__FILE__), 'config', 'boot')) 12 | 13 | # from previous version 14 | 15 | #require 'thread' 16 | #require 'rake' 17 | #require 'rake/testtask' 18 | #require 'rake/rdoctask' 19 | # 20 | #require 'tasks/rails' 21 | require 'vlad' 22 | #require 'vlad-git' 23 | Vlad.load(:app => nil, :scm => :git) 24 | -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This file is included in all sites and subsites. This is a 2 | // manifest file that'll be compiled into including all the files 3 | // listed below. Add new JavaScript/Coffee code in separate files in 4 | // the application directory and they'll automatically be included. 5 | // It's not advisable to add code directly here, but if you do, it'll 6 | // appear at the bottom of the the compiled file. 7 | // 8 | //= require jquery 9 | //= require jquery_ujs 10 | //= require jquery-ui 11 | //= require hobo_rapid 12 | //= require hobo_jquery 13 | //= require hobo_jquery_ui 14 | //= require_tree ./application 15 | -------------------------------------------------------------------------------- /app/views/manual/manual_section.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | Last updated:
12 | Edit this page 13 |
14 | 15 |
16 |
17 | 18 |
19 | -------------------------------------------------------------------------------- /app/views/questions/new_for_user.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ask and You Shall Receive. Well... You might. 4 | 5 |

If you have an idea for a recipe that you think would be generally useful to Hobo programmers, please post your request 6 | here. If you have a more specific question about something you're stuck with, the 7 | Hobo Users group is probably the best place for that.

8 |
9 | 10 |
-------------------------------------------------------------------------------- /app/views/tutorials/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | Last updated:
12 | Edit this page 13 |
14 | 15 |
16 |
17 | 18 |
19 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | protect_from_forgery 3 | 4 | # helper :all # include all helpers, all the time 5 | 6 | 7 | before_filter :login_required, :only => [:new, :edit] 8 | 9 | private 10 | 11 | def last_update(filename) 12 | Dir.chdir(File.open("#{Rails.root}/git-path").read.chomp) do 13 | head = File.open("#{Rails.root}/git-version").read.chomp 14 | commit = `git rev-list #{head} #{filename} | head -n 1` 15 | date_s = `git show --pretty=format:%cD #{commit} | head -n 1` 16 | date_s ? Date.parse(date_s) : "" 17 | end 18 | end 19 | end 20 | 21 | -------------------------------------------------------------------------------- /app/views/questions/atom.builder: -------------------------------------------------------------------------------- 1 | atom_feed do |feed| 2 | feed.title("HoboCookbook - questions") 3 | feed.updated(@questions.first.created_at) 4 | 5 | @questions.each do |question| 6 | feed.entry(question) do |entry| 7 | entry.title("#{question.subject}#{' (pending moderation)' if question.user.state=='pending'}") 8 | if question.markdown? 9 | entry.content(question.description.to_html_from_markdown.html_safe, :type => 'html') 10 | else 11 | entry.content(question.description) 12 | end 13 | 14 | entry.author do |author| 15 | author.name(question.user.username) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/recipes/new_for_user.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Post your recipe 4 | 5 | Use markdown syntax 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Images

18 |

To upload an image, you first need to "Save and continue editing"

19 |
20 | 21 |
-------------------------------------------------------------------------------- /app/assets/javascripts/front.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file for the front subsite (which is your whole 2 | // application if you don't have any subsites). It will be compiled 3 | // into including all the files listed below. Add new 4 | // JavaScript/Coffee code in separate files in the front directory and 5 | // they'll automatically be included in the compiled file accessible 6 | // from http://example.com/assets/front.js It's not advisable to add 7 | // code directly here, but if you do, it'll appear at the bottom of 8 | // the the compiled file. 9 | // 10 | //= require application 11 | // 12 | // The default Hobo theme 13 | //= require hobo_clean 14 | //= require_tree ./front 15 | -------------------------------------------------------------------------------- /app/views/manual/manual_subsection.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
11 | Last updated:
12 | Edit this page 13 |
14 | 15 |
16 |
17 | 18 |
19 | -------------------------------------------------------------------------------- /manual/generators/assets.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/assets.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:assets 10 | 11 | 12 | ## Runtime options 13 | 14 | 15 | 16 | -q, [--quiet] # Suppress status output 17 | -s, [--skip] # Skip files that already exist 18 | -f, [--force] # Overwrite files that already exist 19 | -p, [--pretend] # Run but do not make any changes 20 | 21 | 22 | ## Description 23 | 24 | 25 | 26 | 27 | This generator copies the files `application.dryml`, 28 | `application.css`, `dryml-support.js`, 29 | `config/initializers/dryml_taglibs.rb`, `app/models/guest.rb`. 30 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/highlighters/javascript.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("javascript",{ 2 | comment : { 3 | exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/ 4 | }, 5 | brackets : { 6 | exp : /\(|\)/ 7 | }, 8 | string : { 9 | exp : /'[^'\\]*(\\.[^'\\]*)*'|"[^"\\]*(\\.[^"\\]*)*"/ 10 | }, 11 | keywords : { 12 | exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/ 13 | }, 14 | global : { 15 | exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity)\b/ 16 | } 17 | }); -------------------------------------------------------------------------------- /app/views/recipes/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

5 | Posted by . 6 | This recipe answers 7 |
8 | 9 | User contributed notes 10 | 11 | Add your own note 12 | 13 | 14 |

The notes are a place for users to contribute to the documention. If you have a question, bug report, feature request or a general 15 | comment, please use the Hobo Users group.

16 | 17 |
18 |
-------------------------------------------------------------------------------- /app/views/questions/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | All answered questions 10 | 11 |
12 | 13 |
14 | 15 | All open questions 16 | 17 |
18 |
19 |
20 |
-------------------------------------------------------------------------------- /app/assets/javascripts/application/highlighters/dryml.js: -------------------------------------------------------------------------------- 1 | CodeHighlighter.addStyle("dryml", { 2 | paramdec : { 3 | exp : /param(='[^']*'|"[^"]*"|\b)/ 4 | }, 5 | comment : { 6 | exp: /<!\s*(--([^-]|[\r\n]|-[^-])*--\s*)>/ 7 | }, 8 | parameter : { 9 | exp: /(<\/?)([a-zA-Z-]+:)([^a-z_])/, 10 | replacement: "$1$2$3" 11 | }, 12 | tag : { 13 | exp: /(<\/?)([a-zA-Z-0-9]+\s?)/, 14 | replacement: "$1$2" 15 | }, 16 | string : { 17 | exp : /'[^']*'|"[^"]*"/ 18 | }, 19 | attribute : { 20 | exp: /\b([a-zA-Z-:]+)(=|>|\/)/, 21 | replacement: "$1$2" 22 | }, 23 | doctype : { 24 | exp: /<!DOCTYPE([^&]|&[^g]|&g[^t])*>/ 25 | } 26 | }); -------------------------------------------------------------------------------- /app/models/tag.rb: -------------------------------------------------------------------------------- 1 | # NOTE- Tagging is not implemnted 2 | 3 | class Tag < ActiveRecord::Base 4 | 5 | hobo_model # Don't put anything above this 6 | 7 | fields do 8 | name :string 9 | timestamps 10 | end 11 | 12 | has_many :taggings 13 | has_many :recipes, :through => :taggings 14 | 15 | #named_scope :popular, :limit => "20" # To Do! 16 | 17 | scope :popular, limit(20) 18 | 19 | # --- Hobo Permissions --- # 20 | 21 | def create_permitted? 22 | acting_user.administrator? 23 | end 24 | 25 | def update_permitted? 26 | acting_user.administrator? 27 | end 28 | 29 | def destroy_permitted? 30 | acting_user.administrator? 31 | end 32 | 33 | def view_permitted?(attribute) 34 | true 35 | end 36 | 37 | end 38 | 39 | -------------------------------------------------------------------------------- /app/views/comments/atom.builder: -------------------------------------------------------------------------------- 1 | atom_feed do |feed| 2 | feed.title("HoboCookbook - comments") 3 | feed.updated(@comments.first._?.created_at) 4 | 5 | @comments.each do |comment| 6 | feed.entry(comment, :url => recipe_path(comment.recipe)) do |entry| 7 | entry.title("Comment on #{comment.recipe.name}#{' (pending moderation)' if comment.user.state=='pending'}") 8 | if comment.markdown? 9 | # FIXME hack, I shouldn't need OptionalComment.new 10 | entry.content(OptionalMarkdown.new(comment.body).to_html_from_markdown.html_safe, :type => 'html') 11 | else 12 | entry.content(comment.body) 13 | end 14 | 15 | entry.author do |author| 16 | author.name(comment.user.username) 17 | end 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/views/questions/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Question: 4 | Asks 5 | 6 | Discussion 7 | No one has responded yet 8 | Your response 9 | 10 |

If you have a quick answer you can post it here. Better still, post a new 11 | recipe, then return here and link to it below.

12 |
13 | 14 | 15 |
-------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vendor/plugins/paperclip_with_hobo"] 2 | path = vendor/plugins/paperclip_with_hobo 3 | url = git://github.com/tablatom/paperclip_with_hobo.git 4 | [submodule "taglibs/hoboyui"] 5 | path = taglibs/hoboyui 6 | url = git://github.com/tablatom/hoboyui.git 7 | [submodule "taglibs/hobo-contrib"] 8 | path = taglibs/hobo-contrib 9 | url = git://github.com/bryanlarsen/hobo-contrib.git 10 | [submodule "taglibs/imaginary-dryml"] 11 | path = taglibs/imaginary-dryml 12 | url = git://github.com/imaginary-cloud/Imaginary-DRYML.git 13 | [submodule "gitorials/agility"] 14 | path = gitorials/agility 15 | url = git://github.com/Hobo/agility-gitorial.git 16 | [submodule "public/patches/agility"] 17 | path = public/patches/agility 18 | url = git://github.com/Hobo/agility-gitorial-patches.git 19 | -------------------------------------------------------------------------------- /app/models/image.rb: -------------------------------------------------------------------------------- 1 | class Image < ActiveRecord::Base 2 | 3 | hobo_model # Don't put anything above this 4 | 5 | fields do 6 | timestamps 7 | end 8 | 9 | has_attached_file :image, :styles => { :thumbnail => "100x100#" }, 10 | :path => ":rails_root/public/img/:id/:style_:basename.:extension", 11 | :url => "/img/:id/:style_:basename.:extension" 12 | 13 | belongs_to :recipe 14 | 15 | # --- Hobo Permissions --- # 16 | 17 | def create_permitted? 18 | acting_user.administrator? 19 | end 20 | 21 | def update_permitted? 22 | acting_user.administrator? 23 | end 24 | 25 | def destroy_permitted? 26 | acting_user.administrator? 27 | end 28 | 29 | def view_permitted?(attribute) 30 | true 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /config/initializers/new_rails_defaults.rb: -------------------------------------------------------------------------------- 1 | # These settings change the behavior of Rails 2 apps and will be defaults 2 | # for Rails 3. You can remove this initializer when Rails 3 is released. 3 | 4 | if defined?(ActiveRecord) 5 | # Include Active Record class name as root for JSON serialized output. 6 | ActiveRecord::Base.include_root_in_json = true 7 | 8 | # Store the full class name (including module namespace) in STI type column. 9 | ActiveRecord::Base.store_full_sti_class = true 10 | end 11 | 12 | # Use ISO 8601 format for JSON serialized times and dates. 13 | ActiveSupport.use_standard_json_time_format = true 14 | 15 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper. 16 | # if you're including raw json in an HTML page. 17 | ActiveSupport.escape_html_entities_in_json = false -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/environments/development-old.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # In the development environment your application's code is reloaded on 4 | # every request. This slows down response time but is perfect for development 5 | # since you don't have to restart the webserver when you make code changes. 6 | config.cache_classes = false 7 | 8 | # Log error messages when you accidentally call methods on nil. 9 | config.whiny_nils = true 10 | 11 | # Show full error reports and disable caching 12 | config.action_controller.consider_all_requests_local = true 13 | config.action_view.debug_rjs = 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 -------------------------------------------------------------------------------- /manual/generators/routes.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/routes.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:routes [options] 10 | 11 | 12 | ## Runtime options 13 | 14 | 15 | 16 | -q, [--quiet] # Suppress status output 17 | -s, [--skip] # Skip files that already exist 18 | -f, [--force] # Overwrite files that already exist 19 | -p, [--pretend] # Run but do not make any changes 20 | 21 | 22 | ## Description 23 | 24 | 25 | 26 | This generator prepares the auto routes for your Application. 27 | It is automatically used internally, so you should not use it manually 28 | 29 | 30 | ## Example 31 | 32 | 33 | 34 | rails generate hobo:routes 35 | 36 | This will create: 37 | config/hobo_routes.rb 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /app/controllers/api_tag_defs_controller.rb: -------------------------------------------------------------------------------- 1 | class ApiTagDefsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :show, :index 6 | 7 | auto_actions_for :taglib, [:index] 8 | 9 | caches_page :show, :tagdef 10 | 11 | def show 12 | conditions = {:tag => params[:id]} 13 | conditions[:for_type] = params[:for] 14 | conditions[:taglib_id] = ApiTaglib.find_by_name(params[:taglib]).id if params[:taglib] 15 | self.this = ApiTagDef.find(:first, :conditions => conditions) 16 | redirect_to tagdef_path(:plugin => this.taglib.plugin.name, :taglib => this.taglib.name, :tag => this.tag) 17 | end 18 | 19 | def tagdef 20 | self.this = ApiPlugin.find_by_name(params[:plugin]).taglibs.find_by_name(params[:taglib]).tags.find_by_tag_and_for_type(params[:tag], params[:for]) 21 | hobo_show 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /db/migrate/20081021123705_adding_models_for_api_referece.rb: -------------------------------------------------------------------------------- 1 | class AddingModelsForApiReferece < ActiveRecord::Migration 2 | def self.up 3 | create_table :api_tag_defs do |t| 4 | t.string :name 5 | t.boolean :extension 6 | t.boolean :polymorphic 7 | t.string :for_type 8 | t.text :comment 9 | t.text :tag_attributes 10 | t.text :tag_parameters 11 | t.string :merge_attrs 12 | t.string :merge_params 13 | t.datetime :created_at 14 | t.datetime :updated_at 15 | t.integer :taglib_id 16 | end 17 | 18 | create_table :api_taglibs do |t| 19 | t.string :name 20 | t.datetime :created_at 21 | t.datetime :updated_at 22 | end 23 | end 24 | 25 | def self.down 26 | drop_table :api_tag_defs 27 | drop_table :api_taglibs 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /manual/generators/resource.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/resource.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:resource NAME [field:type field:type] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--timestamps] # Indicates when to generate timestamps 17 | [--skip-namespace] # Skip namespace (affects only isolated applications) 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | 20 | 21 | ## Runtime options 22 | 23 | 24 | 25 | -q, [--quiet] # Suppress status output 26 | -s, [--skip] # Skip files that already exist 27 | -f, [--force] # Overwrite files that already exist 28 | -p, [--pretend] # Run but do not make any changes 29 | 30 | 31 | ## Description 32 | 33 | 34 | 35 | Create hobo files for resource generator. 36 | -------------------------------------------------------------------------------- /config/environments/production-old.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The production environment is meant for finished, "live" apps. 4 | # Code is not reloaded between requests 5 | config.cache_classes = true 6 | 7 | # Use a different logger for distributed setups 8 | # config.logger = SyslogLogger.new 9 | 10 | # Full error reports are disabled and caching is turned on 11 | config.action_controller.consider_all_requests_local = false 12 | config.action_controller.perform_caching = true 13 | 14 | # Use a different cache store in production 15 | # config.cache_store = :mem_cache_store 16 | 17 | # Enable serving of images, stylesheets, and javascripts from an asset server 18 | # config.action_controller.asset_host = "http://assets.example.com" 19 | 20 | # Disable delivery errors, bad email addresses will be ignored 21 | # config.action_mailer.raise_delivery_errors = false 22 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | # Hobo Cookbook! 2 | 3 | This is the open-source code that implements the site at http://cookbook.hobocentral.net 4 | 5 | # How to run locally 6 | 7 | The cookbook does not run under Ruby 1.9.2, it requires Ruby 1.8.7. 8 | This should be easy to fix if anybody wants to take a crack at it. 9 | 10 | We're using Vlad for deployment, but it messes with our rake tasks at 11 | other times, so the first step is to comment out the call to Vlad.load 12 | in Rakefile. 13 | 14 | As for many rails3 apps: 15 | 16 | $ git submodule update --init 17 | $ bundle install 18 | $ vi config/database.yml # and adjust as required 19 | $ bundle exec rake db:migrate 20 | 21 | Unique to the cookbook: 22 | 23 | $ pwd > git-path 24 | $ echo 'master' > git-version 25 | 26 | Run this command now and whenever you want to update/rebuild any of the external dependencies such as hobo, the plugins or the tutorials. 27 | 28 | $ bundle exec rake cookbook:update 29 | 30 | -------------------------------------------------------------------------------- /app/rich_types/optional_markdown.rb: -------------------------------------------------------------------------------- 1 | class HoboFields::Types::MarkdownString < HoboFields::Types::RawMarkdownString 2 | 3 | def to_html(xmldoctype = true) 4 | return "" if blank? 5 | # the underscore fix, stolen from GitHub Flavored Markdown 6 | # which was buggy as all hell, so I had to fix it. grrr. 7 | s=self.gsub(/^(?! {4}|\t).*$/) do |line| 8 | line.gsub(/\w+_\w+_\w[\w_]*/) do |x| 9 | x.gsub('_', '\_') if x.split('').sort.to_s[0..1] == '__' 10 | end 11 | end 12 | begin 13 | s=Maruku.new(s).to_html 14 | rescue 15 | "Uh oh - looks like there was a problem rendering that markdown." 16 | end 17 | HoboFields::SanitizeHtml.sanitize(s) 18 | end 19 | 20 | end 21 | 22 | class OptionalMarkdown < HoboFields::Types::Text 23 | 24 | HoboFields.register_type(:optional_markdown, self) 25 | 26 | def to_html_from_markdown 27 | HoboFields::Types::MarkdownString.new(self).to_html 28 | end 29 | 30 | end 31 | 32 | -------------------------------------------------------------------------------- /manual/generators/user_resource.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/user\_resource.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:user_resource [NAME=user] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--skip-namespace] # Skip namespace (affects only isolated applications) 17 | -i, [--invite-only] # Add features for an invite only website 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | [--activation-email] # Send an email to activate the account 20 | 21 | 22 | ## Runtime options 23 | 24 | 25 | 26 | -q, [--quiet] # Suppress status output 27 | -s, [--skip] # Skip files that already exist 28 | -f, [--force] # Overwrite files that already exist 29 | -p, [--pretend] # Run but do not make any changes 30 | 31 | 32 | ## Description 33 | 34 | 35 | 36 | Create hobo files for user_resource generator. 37 | -------------------------------------------------------------------------------- /app/controllers/comments_controller.rb: -------------------------------------------------------------------------------- 1 | class CommentsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :update, :destroy 6 | 7 | auto_actions_for :recipe, [:create] 8 | 9 | index_action :atom, :atom_with_spam 10 | caches_page :atom, :atom_with_spam 11 | 12 | def create_for_recipe 13 | expire_page :action => :atom 14 | expire_page :action => :atom_with_spam 15 | hobo_create_for :recipe 16 | end 17 | 18 | def update 19 | expire_page :action => :atom 20 | expire_page :action => :atom_with_spam 21 | hobo_update 22 | end 23 | 24 | def destroy 25 | expire_page :action => :atom 26 | expire_page :action => :atom_with_spam 27 | hobo_destroy 28 | end 29 | 30 | def atom 31 | @comments=Comment.includes(:user).includes(:recipe).where("users.state='active'").order("comments.created_at").reverse_order 32 | end 33 | 34 | def atom_with_spam 35 | @comments=Comment.includes(:user).includes(:recipe).order(:created_at).reverse_order 36 | render :atom 37 | end 38 | 39 | end 40 | -------------------------------------------------------------------------------- /app/views/taglibs/themes/clean-sidemenu/clean-sidemenu.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 |
15 | 16 | 17 | 18 | 19 | 22 | 25 | 26 |
23 |
24 |
27 |
28 | 29 |
30 |
31 | -------------------------------------------------------------------------------- /config/environments/test-old.rb: -------------------------------------------------------------------------------- 1 | # Settings specified here will take precedence over those in config/environment.rb 2 | 3 | # The test environment is used exclusively to run your application's 4 | # test suite. You never need to work with it otherwise. Remember that 5 | # your test database is "scratch space" for the test suite and is wiped 6 | # and recreated between test runs. Don't rely on the data there! 7 | config.cache_classes = true 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.action_controller.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Disable request forgery protection in test environment 17 | config.action_controller.allow_forgery_protection = false 18 | 19 | # Tell Action Mailer not to deliver emails to the real world. 20 | # The :test delivery method accumulates sent emails in the 21 | # ActionMailer::Base.deliveries array. 22 | config.action_mailer.delivery_method = :test 23 | -------------------------------------------------------------------------------- /manual/generators/controller.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/controller.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:controller NAME 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--helpers] # Generates helper files 19 | # Default: true 20 | [--skip-namespace] # Skip namespace (affects only isolated applications) 21 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 22 | 23 | 24 | ## Runtime options 25 | 26 | 27 | 28 | -q, [--quiet] # Suppress status output 29 | -s, [--skip] # Skip files that already exist 30 | -f, [--force] # Overwrite files that already exist 31 | -p, [--pretend] # Run but do not make any changes 32 | 33 | 34 | ## Description 35 | 36 | 37 | 38 | 39 | Creates a Hobo model controller. Called from the Hobo `resource` generator. 40 | -------------------------------------------------------------------------------- /manual/generators/user_mailer.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/user\_mailer.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:user_mailer [NAME=user] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | [--activation-email] # Send an email to activate the account 20 | -i, [--invite-only] # Add features for an invite only website 21 | [--skip-namespace] # Skip namespace (affects only isolated applications) 22 | 23 | 24 | ## Runtime options 25 | 26 | 27 | 28 | -q, [--quiet] # Suppress status output 29 | -s, [--skip] # Skip files that already exist 30 | -f, [--force] # Overwrite files that already exist 31 | -p, [--pretend] # Run but do not make any changes 32 | 33 | 34 | ## Description 35 | 36 | 37 | 38 | This generator is used by the user_resource generator to generate user_mailer.rb. 39 | -------------------------------------------------------------------------------- /app/models/api_taglib.rb: -------------------------------------------------------------------------------- 1 | class ApiTaglib < ActiveRecord::Base 2 | 3 | # so we can coexist with other 4 | # versions of the cookbook 5 | set_table_name "api_taglibs_14" 6 | 7 | hobo_model # Don't put anything above this 8 | 9 | def self.find(*args) 10 | if args.first.is_a?(String) && args.first =~ /[a-zA-Z0-9_-]+/ 11 | find_by_name args.first 12 | else 13 | super 14 | end 15 | end 16 | 17 | def to_param 18 | to_s 19 | end 20 | 21 | fields do 22 | name :string, :index => true 23 | short_description :html 24 | description :html 25 | edit_link :string 26 | timestamps 27 | end 28 | 29 | belongs_to :plugin, :class_name => "ApiPlugin" 30 | has_many :tags, :class_name => "ApiTagDef", :foreign_key => "taglib_id" 31 | 32 | set_default_order "name" 33 | 34 | # --- Hobo Permissions --- # 35 | 36 | def create_permitted? 37 | acting_user.administrator? 38 | end 39 | 40 | def update_permitted? 41 | acting_user.administrator? 42 | end 43 | 44 | def destroy_permitted? 45 | acting_user.administrator? 46 | end 47 | 48 | def view_permitted?(attribute) 49 | true 50 | end 51 | 52 | end 53 | -------------------------------------------------------------------------------- /app/models/api_plugin.rb: -------------------------------------------------------------------------------- 1 | class ApiPlugin < ActiveRecord::Base 2 | 3 | set_table_name "api_plugins_14" 4 | 5 | hobo_model # Don't put anything above this 6 | 7 | def self.find(*args) 8 | if args.first.is_a?(String) && args.first =~ /[a-zA-Z0-9_-]+/ 9 | find_by_name args.first 10 | else 11 | super 12 | end 13 | end 14 | 15 | def to_param 16 | to_s 17 | end 18 | 19 | fields do 20 | name :string, :index => true 21 | short_description :html 22 | description :html 23 | edit_link_base :string 24 | edit_link :string 25 | position :integer 26 | timestamps 27 | end 28 | 29 | attr_accessor :dir 30 | 31 | has_many :taglibs, :class_name => "ApiTaglib", :foreign_key => "plugin_id" 32 | 33 | set_default_order "name" 34 | 35 | 36 | # --- Hobo Permissions --- # 37 | 38 | def create_permitted? 39 | acting_user.administrator? 40 | end 41 | 42 | def update_permitted? 43 | acting_user.administrator? 44 | end 45 | 46 | def destroy_permitted? 47 | acting_user.administrator? 48 | end 49 | 50 | def view_permitted?(attribute) 51 | true 52 | end 53 | 54 | end 55 | -------------------------------------------------------------------------------- /app/controllers/recipes_controller.rb: -------------------------------------------------------------------------------- 1 | class RecipesController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :index, :show, :edit, :update, :destroy 6 | 7 | auto_actions_for :user, [:new, :create, :index] 8 | 9 | autocomplete 10 | 11 | index_action :atom, :atom_with_spam 12 | caches_page :atom, :atom_with_spam 13 | 14 | 15 | def create_for_user 16 | expire_page :action => :atom 17 | expire_page :action => :atom_with_spam 18 | hobo_create do 19 | redirect_to this, :edit if valid? && params[:stay_here] 20 | end 21 | end 22 | 23 | def update 24 | expire_page :action => :atom 25 | expire_page :action => :atom_with_spam 26 | hobo_update do 27 | redirect_to this, :edit if valid? && params[:stay_here] 28 | end 29 | end 30 | 31 | def destroy 32 | expire_page :action => :atom 33 | expire_page :action => :atom_with_spam 34 | hobo_destroy 35 | end 36 | 37 | def atom 38 | @recipes=Recipe.includes(:user).where("users.state='active'").order("recipes.created_at").reverse_order 39 | end 40 | 41 | def atom_with_spam 42 | @recipes=Recipe.includes(:user).order(:created_at).reverse_order 43 | render :atom 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /manual/generators/user_controller.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/user\_controller.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:user_controller [NAME=users] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--skip-namespace] # Skip namespace (affects only isolated applications) 19 | [--helpers] # Generates helper files 20 | # Default: true 21 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 22 | -i, [--invite-only] # Add features for an invite only website 23 | 24 | 25 | ## Runtime options 26 | 27 | 28 | 29 | -q, [--quiet] # Suppress status output 30 | -s, [--skip] # Skip files that already exist 31 | -f, [--force] # Overwrite files that already exist 32 | -p, [--pretend] # Run but do not make any changes 33 | 34 | 35 | ## USAGE 36 | 37 | 38 | 39 | This generator is used by the user_resource generator to generate 40 | app/controllers/users_controller.rb 41 | -------------------------------------------------------------------------------- /app/controllers/questions_controller.rb: -------------------------------------------------------------------------------- 1 | class QuestionsController < ApplicationController 2 | 3 | hobo_model_controller 4 | 5 | auto_actions :edit, :update, :destroy, :show 6 | 7 | auto_actions_for :user, [:index, :new, :create] 8 | 9 | auto_actions_for :recipes, :index 10 | 11 | index_action :atom, :atom_with_spam 12 | caches_page :atom, :atom_with_spam 13 | 14 | def index; end 15 | 16 | index_action :answered, :scope => :with_answers 17 | index_action :open, :scope => :without_answers 18 | 19 | def create_for_user 20 | expire_page :action => :atom 21 | expire_page :action => :atom_with_spam 22 | hobo_create_for :user 23 | end 24 | 25 | def update 26 | expire_page :action => :atom 27 | expire_page :action => :atom_with_spam 28 | hobo_update 29 | end 30 | 31 | def destroy 32 | expire_page :action => :atom 33 | expire_page :action => :atom_with_spam 34 | hobo_destroy 35 | end 36 | 37 | def atom 38 | @questions=Question.includes(:user).where("users.state='active'").order("questions.created_at").reverse_order 39 | end 40 | 41 | def atom_with_spam 42 | @questions=Question.includes(:user).order(:created_at).reverse_order 43 | render :atom 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /app/views/users/show.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Questions 11 |

With answers

12 | more 13 | 14 | 15 | 16 | 17 | Questions 18 |

Without answers

19 | more 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
33 | -------------------------------------------------------------------------------- /app/views/recipes/edit.dryml: -------------------------------------------------------------------------------- 1 | <% 2 | paths = comma_split(scripts).map {|s| "#{version}/build/#{s}.js"}.join('&') 3 | %> 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Use markdown syntax 14 | 15 | 16 | 17 |

Images

18 | 19 | 20 | 21 | 22 | 23 | 24 |

Upload image

25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Hobocookbook::Application.configure do 2 | # Hobo: tell ActiveReload about dryml 3 | config.watchable_dirs[File.join(config.root, 'app/view')] = ['dryml'] 4 | 5 | # Settings specified here will take precedence over those in config/application.rb 6 | 7 | # In the development environment your application's code is reloaded on 8 | # every request. This slows down response time but is perfect for development 9 | # since you don't have to restart the webserver when you make code changes. 10 | config.cache_classes = false 11 | 12 | # Log error messages when you accidentally call methods on nil. 13 | config.whiny_nils = true 14 | 15 | # Show full error reports and disable caching 16 | config.consider_all_requests_local = true 17 | config.action_controller.perform_caching = false 18 | 19 | # Don't care if the mailer can't send 20 | config.action_mailer.raise_delivery_errors = false 21 | 22 | # Print deprecation notices to the Rails logger 23 | config.active_support.deprecation = :log 24 | 25 | # Only use best-standards-support built into browsers 26 | config.action_dispatch.best_standards_support = :builtin 27 | 28 | # Do not compress assets 29 | config.assets.compress = false 30 | 31 | # Expands the lines which load the assets 32 | config.assets.debug = true 33 | end 34 | 35 | #Debugger.start 36 | 37 | -------------------------------------------------------------------------------- /manual/generators/user_model.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/user\_model.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:user_model [NAME=user] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--skip-namespace] # Skip namespace (affects only isolated applications) 17 | -i, [--invite-only] # Add features for an invite only website 18 | [--timestamps] # Indicates when to generate timestamps 19 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 20 | [--admin-subsite-name=ADMIN_SUBSITE_NAME] # Admin Subsite Name 21 | # Default: admin 22 | [--activation-email] # Send an email to activate the account 23 | 24 | 25 | ## Runtime options 26 | 27 | 28 | 29 | -q, [--quiet] # Suppress status output 30 | -s, [--skip] # Skip files that already exist 31 | -f, [--force] # Overwrite files that already exist 32 | -p, [--pretend] # Run but do not make any changes 33 | 34 | 35 | ## Description 36 | 37 | 38 | 39 | 40 | This generator is used by the user_resource generator to generate a 41 | user model file into app/models. 42 | 43 | -------------------------------------------------------------------------------- /gitorials/two-minutes.markdown: -------------------------------------------------------------------------------- 1 | # Hobo in Two Minutes 2 | 3 | To build a Hobo 2.0 app you need to have a working Rails setup. If you can 4 | create a Rails app and have it connect to a database, you're all set. 5 | You need at least version 3.2.5 of Rails: 6 | 7 | $ rails -v 8 | 9 | First install Hobo (currently we need to specify --pre, since Hobo 10 | 2.0.0 is not the official release yet): 11 | 12 | $ gem install hobo --pre 13 | 14 | $ hobo -v 15 | 16 | Now create an app! We've only got two minutes so we'll create an ultra-useful Thing Manager. 17 | 18 | $ hobo new thingybob --setup 19 | 20 | (The `--setup` option tells hobo to use the defaults rather than 21 | asking questions about your application.) 22 | 23 | There will be lots of output produced as Hobo runs the rails command 24 | and runs the setup generator. This process may take a while, depending 25 | on your internet connection and computer speed. 26 | 27 | $ cd thingybob 28 | $ hobo g resource thing name:string body:text 29 | $ hobo g migration 30 | 31 | ...Respond to the prompt with 'm' 32 | ...then press enter to chose the default filename 33 | 34 | $ rails s 35 | 36 | And browse to 37 | 38 | http://localhost:3000 39 | 40 | And there is your app! You should be able to 41 | 42 | * Sign up 43 | * Create and edit Things 44 | * Search for things 45 | 46 | That's it. Why not try another of the tutorials on your left. 47 | -------------------------------------------------------------------------------- /manual/generators/test_framework.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/test\_framework.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:test_framework NAME [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=TEST_FRAMEWORK] # Use a specific test framework 17 | # Default: test_unit 18 | [--skip-namespace] # Skip namespace (affects only isolated applications) 19 | [--fixture-replacement=FIXTURE_REPLACEMENT] # Use a specific fixture replacement 20 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 21 | [--fixtures] # Add the fixture option to the test framework 22 | # Default: true 23 | [--update] # Run bundle update to install the missing gems 24 | 25 | 26 | ## Runtime options 27 | 28 | 29 | 30 | -q, [--quiet] # Suppress status output 31 | -s, [--skip] # Skip files that already exist 32 | -f, [--force] # Overwrite files that already exist 33 | -p, [--pretend] # Run but do not make any changes 34 | 35 | 36 | ## Description 37 | 38 | 39 | 40 | Create hobo files for test_framework generator. 41 | -------------------------------------------------------------------------------- /manual/generators/subsite_taglib.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/subsite\_taglib.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:subsite_taglib NAME [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -i, [--invite-only] # Add features for an invite only website 17 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 18 | [--theme=THEME] # Theme 19 | # Default: clean_admin 20 | [--ui-theme=UI_THEME] # jQuery-UI Theme 21 | # Default: flick 22 | [--user-resource-name=USER_RESOURCE_NAME] # User Resource Name 23 | # Default: user 24 | [--skip-namespace] # Skip namespace (affects only isolated applications) 25 | 26 | 27 | ## Runtime options 28 | 29 | 30 | 31 | -q, [--quiet] # Suppress status output 32 | -s, [--skip] # Skip files that already exist 33 | -f, [--force] # Overwrite files that already exist 34 | -p, [--pretend] # Run but do not make any changes 35 | 36 | 37 | ## Description 38 | 39 | 40 | 41 | This generator is used to generate 42 | app/views/taglibs/_site.dryml, and is used by the 43 | subsite and admin_site generators. Do not use directly. 44 | -------------------------------------------------------------------------------- /app/controllers/tutorials_controller.rb: -------------------------------------------------------------------------------- 1 | class TutorialsController < ApplicationController 2 | 3 | caches_page :index, :show 4 | 5 | TITLES = begin 6 | titles = ActiveSupport::OrderedHash.new 7 | [['two-minutes', ["Thingybob - the two minute Hobo app", "https://github.com/tablatom/hobocookbook/edit/master/gitorials/two-minutes.markdown"]], 8 | ['screencast', ["Screencast", "https://github.com/tablatom/hobocookbook/edit/master/gitorials/screencast.markdown"]], 9 | ['agility', ["Agility - demonstrates all Hobo features", nil]], 10 | ['gitorial', ["Agility git sidebar", nil]], 11 | ['subsite', ["An admin subsite on a generic Rails app", "https://github.com/tablatom/hobocookbook/edit/master/gitorials/subsite.markdown"]], 12 | ['caching', ["How to use the caching tags", "https://github.com/tablatom/hobocookbook/edit/master/gitorials/caching.markdown"]] 13 | ].each do |title, desc| 14 | titles[title]=desc 15 | end 16 | titles 17 | end 18 | 19 | def show 20 | tutorial = params[:tutorial].gsub(/[^a-z_\-]/, '') 21 | filename = "gitorials/#{tutorial}.markdown" 22 | @title = TITLES[tutorial][0] 23 | @content = HoboFields::Types::MarkdownString.new(File.read("#{Rails.root}/#{filename}")) 24 | @last_update = last_update filename 25 | @edit_link = TITLES[tutorial][1] 26 | end 27 | 28 | def self.titles 29 | ActiveSupport::OrderedHash[*TITLES.map {|k,v| [k, v[0]]}.flatten] 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /manual/generators/model.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/model.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:model NAME [field:type field:type] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--timestamps] # Indicates when to generate timestamps 17 | [--skip-namespace] # Skip namespace (affects only isolated applications) 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | 20 | 21 | ## Runtime options 22 | 23 | 24 | 25 | -q, [--quiet] # Suppress status output 26 | -s, [--skip] # Skip files that already exist 27 | -f, [--force] # Overwrite files that already exist 28 | -p, [--pretend] # Run but do not make any changes 29 | 30 | 31 | ## Description 32 | 33 | 34 | 35 | Invokes the active_record:model generator, but the generated 36 | model file contains the fields block, (and the migration option 37 | is false by default). 38 | 39 | 40 | ## Examples 41 | 42 | 43 | 44 | $ rails generate hobo:model account 45 | 46 | creates an Account model, test and fixture: 47 | Model: app/models/account.rb 48 | Test: test/unit/account_test.rb 49 | Fixtures: test/fixtures/accounts.yml 50 | 51 | $ rails generate hobo:model post title:string body:text published:boolean 52 | 53 | creates a Post model with a string title, text body, and published flag. 54 | 55 | After the model is created, and the fields are specified, use hobo:migration 56 | to create the migrations incrementally. 57 | -------------------------------------------------------------------------------- /manual/generators/install_plugin.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/install\_plugin.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:install_plugin NAME [GIT_PATH] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--comments=COMMENTS] # comments to add before require/include 17 | -v, [--version=VERSION] # Gemspec version string 18 | [--skip-dryml] # doesn't add include to [subsite]_site.dryml 19 | [--skip-namespace] # Skip namespace (affects only isolated applications) 20 | -e, [--subsite=SUBSITE] # Subsite name (without '_site') or 'all' 21 | # Default: all 22 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 23 | -M, [--skip-gem] # don't add plugin to Gemfile 24 | -J, [--skip-js] # don't add require to [subsite].js 25 | -C, [--skip-css] # doesn't add require to [subsite].css 26 | 27 | 28 | ## Runtime options 29 | 30 | 31 | 32 | -q, [--quiet] # Suppress status output 33 | -s, [--skip] # Skip files that already exist 34 | -f, [--force] # Overwrite files that already exist 35 | -p, [--pretend] # Run but do not make any changes 36 | 37 | This generator installs a hobo plugin. 38 | 39 | The first argument is the name of the plugin, and the second is where 40 | to get it. If the second argument is not supplied, it is installed 41 | from rubygems.org or any other gem source listed in your Gemfile. If 42 | the second argument contains a colon (:), it is assumed to be a git 43 | URL. Otherwise it is considered to be a path. 44 | -------------------------------------------------------------------------------- /db/migrate/20120311060921_add_missing_indices.rb: -------------------------------------------------------------------------------- 1 | class AddMissingIndices < ActiveRecord::Migration 2 | def self.up 3 | add_index :comments, [:recipe_id] 4 | add_index :comments, [:user_id] 5 | add_index :questions, [:user_id] 6 | add_index :images, [:recipe_id] 7 | add_index :recipes, [:user_id] 8 | add_index :users, [:state] 9 | add_index :taggings, [:tag_id] 10 | add_index :taggings, [:recipe_id] 11 | add_index :answers, [:recipe_id] 12 | add_index :answers, [:question_id] 13 | add_index :answers, [:user_id] 14 | end 15 | 16 | def self.down 17 | remove_index :comments, :name => :index_comments_on_recipe_id rescue ActiveRecord::StatementInvalid 18 | remove_index :comments, :name => :index_comments_on_user_id rescue ActiveRecord::StatementInvalid 19 | remove_index :questions, :name => :index_questions_on_user_id rescue ActiveRecord::StatementInvalid 20 | remove_index :images, :name => :index_images_on_recipe_id rescue ActiveRecord::StatementInvalid 21 | remove_index :recipes, :name => :index_recipes_on_user_id rescue ActiveRecord::StatementInvalid 22 | remove_index :users, :name => :index_users_on_state rescue ActiveRecord::StatementInvalid 23 | remove_index :taggings, :name => :index_taggings_on_tag_id rescue ActiveRecord::StatementInvalid 24 | remove_index :taggings, :name => :index_taggings_on_recipe_id rescue ActiveRecord::StatementInvalid 25 | remove_index :answers, :name => :index_answers_on_recipe_id rescue ActiveRecord::StatementInvalid 26 | remove_index :answers, :name => :index_answers_on_question_id rescue ActiveRecord::StatementInvalid 27 | remove_index :answers, :name => :index_answers_on_user_id rescue ActiveRecord::StatementInvalid 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Hobocookbook::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 | # Log error messages when you accidentally call methods on nil. 11 | config.whiny_nils = true 12 | 13 | # Show full error reports and disable caching 14 | config.consider_all_requests_local = true 15 | config.action_controller.perform_caching = false 16 | 17 | # Raise exceptions instead of rendering exception templates 18 | config.action_dispatch.show_exceptions = false 19 | 20 | # Disable request forgery protection in test environment 21 | config.action_controller.allow_forgery_protection = false 22 | 23 | # Tell Action Mailer not to deliver emails to the real world. 24 | # The :test delivery method accumulates sent emails in the 25 | # ActionMailer::Base.deliveries array. 26 | config.action_mailer.delivery_method = :test 27 | 28 | # Use SQL instead of Active Record's schema dumper when creating the test database. 29 | # This is necessary if your schema can't be completely dumped by the schema dumper, 30 | # like if you have constraints or database-specific column types 31 | # config.active_record.schema_format = :sql 32 | 33 | # Print deprecation notices to the stderr 34 | config.active_support.deprecation = :stderr 35 | 36 | # Configure static asset server for tests with Cache-Control for performance 37 | config.serve_static_assets = true 38 | config.static_cache_control = "public, max-age=3600" 39 | end 40 | -------------------------------------------------------------------------------- /db/migrate/20120311061300_move_tag_defs_to_14.rb: -------------------------------------------------------------------------------- 1 | class MoveTagDefsTo14 < ActiveRecord::Migration 2 | def self.up 3 | create_table :api_taglibs_14 do |t| 4 | t.string :name 5 | t.text :short_description 6 | t.text :description 7 | t.string :edit_link 8 | t.datetime :created_at 9 | t.datetime :updated_at 10 | t.integer :plugin_id 11 | end 12 | add_index :api_taglibs_14, [:plugin_id] 13 | 14 | create_table :api_tag_comments_14 do |t| 15 | t.text :body 16 | t.boolean :markdown 17 | t.datetime :created_at 18 | t.datetime :updated_at 19 | t.integer :api_tag_def_id 20 | t.integer :user_id 21 | end 22 | add_index :api_tag_comments_14, [:api_tag_def_id] 23 | add_index :api_tag_comments_14, [:user_id] 24 | 25 | create_table :api_plugins_14 do |t| 26 | t.string :name 27 | t.text :short_description 28 | t.text :description 29 | t.string :edit_link_base 30 | t.string :edit_link 31 | t.datetime :created_at 32 | t.datetime :updated_at 33 | end 34 | 35 | create_table :api_tag_defs_14 do |t| 36 | t.string :tag 37 | t.boolean :extension 38 | t.boolean :polymorphic 39 | t.string :for_type 40 | t.text :short_description 41 | t.text :description 42 | t.text :tag_attributes 43 | t.text :tag_parameters 44 | t.string :merge_attrs 45 | t.string :merge_params 46 | t.text :source 47 | t.string :edit_link 48 | t.datetime :created_at 49 | t.datetime :updated_at 50 | t.integer :taglib_id 51 | end 52 | add_index :api_tag_defs_14, [:taglib_id] 53 | end 54 | 55 | def self.down 56 | drop_table :api_taglibs_14 57 | drop_table :api_tag_comments_14 58 | drop_table :api_plugins 59 | drop_table :api_tag_defs_14 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV["RAILS_ENV"] = "test" 2 | require File.expand_path(File.dirname(__FILE__) + "/../config/environment") 3 | require 'test_help' 4 | 5 | class Test::Unit::TestCase 6 | # Transactional fixtures accelerate your tests by wrapping each test method 7 | # in a transaction that's rolled back on completion. This ensures that the 8 | # test database remains unchanged so your fixtures don't have to be reloaded 9 | # between every test method. Fewer database queries means faster tests. 10 | # 11 | # Read Mike Clark's excellent walkthrough at 12 | # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting 13 | # 14 | # Every Active Record database supports transactions except MyISAM tables 15 | # in MySQL. Turn off transactional fixtures in this case; however, if you 16 | # don't care one way or the other, switching from MyISAM to InnoDB tables 17 | # is recommended. 18 | # 19 | # The only drawback to using transactional fixtures is when you actually 20 | # need to test transactions. Since your test is bracketed by a transaction, 21 | # any transactions started in your code will be automatically rolled back. 22 | self.use_transactional_fixtures = true 23 | 24 | # Instantiated fixtures are slow, but give you @david where otherwise you 25 | # would need people(:david). If you don't want to migrate your existing 26 | # test cases which use the @david style and don't mind the speed hit (each 27 | # instantiated fixtures translates to a database query per test method), 28 | # then set this back to true. 29 | self.use_instantiated_fixtures = false 30 | 31 | # Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in alphabetical order. 32 | # 33 | # Note: You'll currently still have to declare fixtures explicitly in integration tests 34 | # -- they do not yet inherit this setting 35 | fixtures :all 36 | 37 | # Add more helper methods to be used by all tests here... 38 | end 39 | -------------------------------------------------------------------------------- /app/views/api_tag_defs/show.dryml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | 6 |
7 | 8 |
9 | 10 |
11 |

Parameters

12 | 13 |
14 | 15 | 16 | 17 | 18 |

19 | Show Source 20 |

21 | 24 |
25 |
26 |
27 | 28 | 29 |
    30 |
  • <%= this.first %> 31 | 32 |
  • 33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | Edit this page 45 |
46 | 47 | 48 | 49 | 50 | 51 |
52 |

Comments

53 | 54 | 55 | 56 |
57 |

Add a Comment

58 |
59 | 60 | 61 | 62 |
63 |
64 | 65 |
66 | 67 |
68 | -------------------------------------------------------------------------------- /app/views/api_tag_defs/tagdef.dryml: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |

5 | 6 |
7 | 8 |
9 | 10 |
11 |

Parameters

12 | 13 |
14 | 15 | 16 | 17 | 18 |

19 | Show Source 20 |

21 | 24 |
25 |
26 |
27 | 28 | 29 |
    30 |
  • <%= this.first %> 31 | 32 |
  • 33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | Edit this page 45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | 67 |
68 | -------------------------------------------------------------------------------- /manual/generators/front_controller.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/front\_controller.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:front_controller [NAME=front] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | [--helpers] # Generates helper files 20 | # Default: true 21 | -i, [--invite-only] # Add features for an invite only website 22 | [--add-routes] # Modify config/routes.rb to support the front controller 23 | # Default: true 24 | -d, [--delete-index] # Delete public/index.html 25 | # Default: true 26 | [--skip-namespace] # Skip namespace (affects only isolated applications) 27 | [--user-resource-name=USER_RESOURCE_NAME] # User Resource Name 28 | # Default: user 29 | 30 | 31 | ## Runtime options 32 | 33 | 34 | 35 | -q, [--quiet] # Suppress status output 36 | -s, [--skip] # Skip files that already exist 37 | -f, [--force] # Overwrite files that already exist 38 | -p, [--pretend] # Run but do not make any changes 39 | 40 | 41 | ## Description 42 | 43 | 44 | 45 | 46 | The hobo_front_controller generator creates a basic 'front 47 | controller' and related views to get your app development kick started. 48 | 49 | It takes a single argument -- the name of the controller 50 | 51 | The front controller provides a simple front-page, ready to be 52 | customized, and a search page. 53 | 54 | 55 | -------------------------------------------------------------------------------- /manual/generators/subsite.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/subsite.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:subsite NAME [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--user-resource-name=USER_RESOURCE_NAME] # User Resource Name 19 | # Default: user 20 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 21 | [--theme=THEME] # Theme 22 | # Default: clean_admin 23 | [--ui-theme=UI_THEME] # jQuery-UI Theme 24 | # Default: flick 25 | -i, [--invite-only] # Add features for an invite only website 26 | [--skip-namespace] # Skip namespace (affects only isolated applications) 27 | 28 | 29 | ## Runtime options 30 | 31 | 32 | 33 | -q, [--quiet] # Suppress status output 34 | -s, [--skip] # Skip files that already exist 35 | -f, [--force] # Overwrite files that already exist 36 | -p, [--pretend] # Run but do not make any changes 37 | 38 | 39 | ## Description 40 | 41 | 42 | 43 | 44 | Creates a subsite, a namespaced section of your application. 45 | 46 | Controllers for the subsite are created in 47 | app/controllers// and views are also in their own 48 | subdirectory. This allows you to have two different controllers 49 | and two different sets of views for the same model. 50 | 51 | The subsite will use app/views/taglibs/_site.dryml 52 | for common tags. The assets that the subsite will load are 53 | specified in app/assets/javascripts/.js and 54 | app/assets/stylesheets/.[s]css 55 | 56 | The difference between hobo:admin_site and hobo:subsite is that 57 | hobo:admin_site limits the subsite to use by administrators only. 58 | -------------------------------------------------------------------------------- /db/migrate/20081015130022_initial_models.rb: -------------------------------------------------------------------------------- 1 | class InitialModels < ActiveRecord::Migration 2 | def self.up 3 | create_table :answers do |t| 4 | t.datetime :created_at 5 | t.datetime :updated_at 6 | t.integer :user_id 7 | t.integer :recipe_id 8 | t.integer :question_id 9 | end 10 | 11 | create_table :comments do |t| 12 | t.text :body 13 | t.boolean :markdown 14 | t.datetime :created_at 15 | t.datetime :updated_at 16 | t.integer :user_id 17 | t.integer :recipe_id 18 | end 19 | 20 | create_table :images do |t| 21 | t.datetime :created_at 22 | t.datetime :updated_at 23 | t.integer :recipe_id 24 | end 25 | 26 | create_table :questions do |t| 27 | t.text :description 28 | t.boolean :markdown 29 | t.datetime :created_at 30 | t.datetime :updated_at 31 | t.integer :user_id 32 | end 33 | 34 | create_table :recipes do |t| 35 | t.string :name 36 | t.text :body 37 | t.datetime :created_at 38 | t.datetime :updated_at 39 | t.integer :user_id 40 | end 41 | 42 | create_table :tags do |t| 43 | t.string :name 44 | t.datetime :created_at 45 | t.datetime :updated_at 46 | end 47 | 48 | create_table :taggings do |t| 49 | t.datetime :created_at 50 | t.datetime :updated_at 51 | t.integer :tag_id 52 | t.integer :recipe_id 53 | end 54 | 55 | create_table :users do |t| 56 | t.string :crypted_password, :limit => 40 57 | t.string :salt, :limit => 40 58 | t.string :remember_token 59 | t.datetime :remember_token_expires_at 60 | t.string :username 61 | t.string :email_address 62 | t.boolean :administrator, :default => false 63 | t.datetime :created_at 64 | t.datetime :updated_at 65 | t.string :state, :default => "active" 66 | t.datetime :key_timestamp 67 | end 68 | end 69 | 70 | def self.down 71 | drop_table :answers 72 | drop_table :comments 73 | drop_table :images 74 | drop_table :questions 75 | drop_table :recipes 76 | drop_table :tags 77 | drop_table :taggings 78 | drop_table :users 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /manual/generators/admin_subsite.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/admin\_subsite.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:admin_subsite [NAME=admin] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -t, [--test-framework=NAME] # Test framework to be invoked 17 | # Default: test_unit 18 | [--old-style-hash] # Force using old style hash (:foo => 'bar') on Ruby >= 1.9 19 | -i, [--invite-only] # Add features for an invite only website 20 | [--theme=THEME] # Theme 21 | # Default: clean_admin 22 | [--ui-theme=UI_THEME] # jQuery-UI Theme 23 | # Default: flick 24 | [--skip-namespace] # Skip namespace (affects only isolated applications) 25 | [--user-resource-name=USER_RESOURCE_NAME] # User Resource Name 26 | # Default: user 27 | 28 | 29 | ## Runtime options 30 | 31 | 32 | 33 | -q, [--quiet] # Suppress status output 34 | -s, [--skip] # Skip files that already exist 35 | -f, [--force] # Overwrite files that already exist 36 | -p, [--pretend] # Run but do not make any changes 37 | 38 | 39 | ## Description 40 | 41 | 42 | 43 | 44 | Creates a subsite, a namespaced section of your application. 45 | 46 | Controllers for the subsite are created in 47 | app/controllers// and views are also in their own 48 | subdirectory. This allows you to have two different controllers 49 | and two different sets of views for the same model. 50 | 51 | The subsite will use app/views/taglibs/_site.dryml 52 | for common tags. The assets that the subsite will load are 53 | specified in app/assets/javascripts/.js and 54 | app/assets/stylesheets/.[s]css 55 | 56 | The difference between hobo:admin_site and hobo:subsite is that 57 | hobo:admin_site limits the subsite to use by administrators only. 58 | 59 | -------------------------------------------------------------------------------- /config/deploy.rb: -------------------------------------------------------------------------------- 1 | set :application, "cookbook" 2 | set :domain, "cookbook-staging.hobocentral.net" 3 | # set :domain, "li285-250.members.linode.com" 4 | set :deploy_to, "/home/cookbook14" 5 | set :repository, "git://github.com/tablatom/hobocookbook" 6 | set :revision, "origin/master" 7 | set :skip_scm, false 8 | 9 | set :user, "cookbook" 10 | set :domain, "#{user}@cookbook.hobocentral.net" 11 | 12 | set :bundle_cmd, "/opt/ruby-1.8.7-p334/bin/bundle" 13 | set :rake_cmd, "#{bundle_cmd} exec /opt/ruby-1.8.7-p334/bin/rake" 14 | # set :rake_cmd, "/usr/local/rvm/bin/cookbook_rake" 15 | 16 | namespace :vlad do 17 | desc 'Restart Passenger' 18 | remote_task :start_app, :roles => :app do 19 | run "touch #{current_release}/tmp/restart.txt" 20 | end 21 | 22 | desc 'reload api tags' 23 | remote_task :update_cookbook do 24 | run " cd #{current_release}; RAILS_ENV=production #{rake_cmd} cookbook:load_api_docs" 25 | # run " cd #{current_release}; RAILS_ENV=production #{rake_cmd} cookbook:rebuild_generator_docs" 26 | end 27 | 28 | desc 'update secret in config/environment.rb' 29 | remote_task :update_secret do 30 | secret=`dd if=/dev/urandom bs=64 count=1`.unpack("Q8").map {|i| i.to_s(16)}.join("") 31 | run "cd #{current_release}/config/initializers; sed -i.bak -e's/REPLACE_ME_WITH_A_REAL_SECRET/#{secret}/' secret_token.rb" 32 | end 33 | 34 | desc 'save version' 35 | remote_task :save_version do 36 | run "cd #{scm_path}/repo; git rev-parse HEAD > #{current_release}/git-version" 37 | run "echo #{scm_path}/repo > #{current_release}/git-path" 38 | end 39 | 40 | remote_task :copy_config_files, :roles => :app do 41 | run "cp -r #{shared_path}/config/* #{current_release}/config/" 42 | end 43 | 44 | desc 'bundle install --deployment' 45 | remote_task :bundle_install do 46 | run " cd #{current_release}; RAILS_ENV=production #{bundle_cmd} install --deployment" 47 | end 48 | 49 | desc 'precompile assets' 50 | remote_task :precompile_assets do 51 | run " cd #{current_release}; RAILS_ENV=production #{rake_cmd} assets:precompile" 52 | end 53 | 54 | remote_task :update, :roles => :app do 55 | Rake::Task["vlad:bundle_install"].invoke 56 | Rake::Task["vlad:precompile_assets"].invoke 57 | Rake::Task["vlad:copy_config_files"].invoke 58 | Rake::Task["vlad:save_version"].invoke 59 | Rake::Task["vlad:update_secret"].invoke 60 | Rake::Task["vlad:update_cookbook"].invoke 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Hobocookbook::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb 3 | 4 | # The production environment is meant for finished, "live" apps. 5 | # Code is not reloaded between requests 6 | config.cache_classes = true 7 | 8 | # Full error reports are disabled and caching is turned on 9 | config.consider_all_requests_local = false 10 | config.action_controller.perform_caching = true 11 | 12 | # Disable Rails's static asset server (Apache or nginx will already do this) 13 | config.serve_static_assets = false 14 | 15 | # Compress JavaScripts and CSS 16 | config.assets.compress = true 17 | 18 | # Don't fallback to assets pipeline if a precompiled asset is missed 19 | config.assets.compile = false 20 | 21 | # Generate digests for assets URLs 22 | config.assets.digest = true 23 | # Defaults to Rails.root.join("public/assets") 24 | # config.assets.manifest = YOUR_PATH 25 | # Specifies the header that your server uses for sending files 26 | config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 27 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 28 | 29 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 30 | # config.force_ssl = true 31 | 32 | # See everything in the log (default is :info) 33 | # config.log_level = :debug 34 | 35 | # Use a different logger for distributed setups 36 | # config.logger = SyslogLogger.new 37 | 38 | # Use a different cache store in production 39 | # config.cache_store = :mem_cache_store 40 | 41 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) 42 | # config.assets.precompile += %w( search.js ) 43 | 44 | # Enable serving of images, stylesheets, and javascripts from an asset server 45 | # config.action_controller.asset_host = "http://assets.example.com" 46 | 47 | # Disable delivery errors, bad email addresses will be ignored 48 | # config.action_mailer.raise_delivery_errors = false 49 | 50 | # Enable threaded mode 51 | # config.threadsafe! 52 | 53 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 54 | # the I18n.default_locale when a translation can not be found) 55 | config.i18n.fallbacks = true 56 | 57 | # Send deprecation notices to registered listeners 58 | config.active_support.deprecation = :notify 59 | end 60 | -------------------------------------------------------------------------------- /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 Hobocookbook 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 | # JavaScript files you want as :defaults (application.js is always included). 37 | # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) 38 | 39 | # Configure the default encoding used in templates for Ruby 1.9. 40 | config.encoding = "utf-8" 41 | 42 | # Configure sensitive parameters which will be filtered from the log file. 43 | config.filter_parameters += [:password] 44 | 45 | # Enable the asset pipeline 46 | config.assets.enabled = true 47 | 48 | # Version of your assets, change this if you want to expire all your assets 49 | config.assets.version = '1.0' 50 | 51 | config.assets.precompile += %w(front.css front.js) 52 | 53 | config.action_controller.page_cache_directory = "#{Rails.root}/public/cache" 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /lib/tasks/cookbook.rake: -------------------------------------------------------------------------------- 1 | require "#{Rails.root}/lib/api_doc_loader" 2 | namespace :cookbook do 3 | desc "Load the api by parsing the taglibs in the Hobo plugin" 4 | task :load_api_docs => :environment do 5 | ApiDocLoader.load 6 | end 7 | 8 | desc "Rebuild agility.markdown" 9 | task :rebuild_agility => :environment do 10 | # GitorialsController::TITLES.each do |dir, desc| 11 | Gitorial.new("#{Rails.root}/gitorials/agility", "http://github.com/Hobo/agility-gitorial/commit/", "/patches/agility").process.each do |filename, markdown| 12 | next if markdown=="" 13 | f=open("#{Rails.root}/gitorials/#{filename}", "w") 14 | f.write(markdown) 15 | f.close 16 | end 17 | end 18 | 19 | desc "Rebuild generator documentation" 20 | task :rebuild_generator_docs => :environment do 21 | ManualController::SUBTITLES['generators'].each do |gen, title| 22 | raw = `bundle exec rails g hobo:#{gen} --help` 23 | out = "Generators -- #{title[1].gsub('_', '\_')}\n{: .document-title}\n\n" + 24 | raw.gsub(/^ /," "). 25 | gsub(/^(\w(\w|\s)*):(.*)/) {|s| "\n## #{$1}\n\n #{$3}\n"}. 26 | gsub("#{Rails.root}", ".") 27 | Dir.mkdir("#{Rails.root}/manual/generators") rescue nil 28 | open("#{Rails.root}/manual/generators/#{gen}.markdown", "w") do |f| 29 | f.write(out) 30 | end 31 | end 32 | end 33 | 34 | desc "git pull all plugins/submodules (except for non-Hobo project)" 35 | task :pull_all => :environment do 36 | ['vendor/plugins/paperclip_with_hobo', 'public/patches/agility', 'taglibs/hoboyui', 'taglibs/hobo-contrib', 'taglibs/imaginary-dryml'].each {|sub| 37 | sh "cd #{sub} && git fetch origin && git checkout origin/master" 38 | } 39 | #sh 'cd taglibs/hobo-jquery && git fetch origin && git checkout origin/rails3' 40 | #sh 'cd vendor/hobo13 && git fetch origin && git checkout origin/rails3' 41 | #sh "cd vendor/plugins/hobo && git fetch origin && git checkout origin/1-0-stable" 42 | sh "rm -rf gitorials/agility ; git submodule update gitorials/agility ; cd gitorials/agility && git checkout -f origin/master" 43 | sh " bundle update hobo_support hobo_fields dryml hobo hobo_rapid hobo_clean hobo_clean_admin hobo_jquery hobo_jquery hobo_jquery_ui hobo_tree_table select_one_or_new_dialog hobo_simple_color hobo_tokeninput hobo_data_tables hobo_bootstrap hobo_mapstraction hobo_clean_sidemenu hobo_omniauth --source hobo" 44 | end 45 | 46 | desc "do all update tasks" 47 | task :update => [:environment, :pull_all, :load_api_docs, :rebuild_agility, :rebuild_generator_docs] do 48 | true 49 | end 50 | end 51 | 52 | -------------------------------------------------------------------------------- /app/views/front/index.dryml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 |

Welcome to the Hobo Cookbook!

10 |
11 |

A place to publish, browse, search and request recipes - short how-to guides for using the Hobo framework for Rails. If you can't find a recipe here, try searching the mailing list.

12 |
13 |
14 | 15 |
16 | 17 | 18 |
19 | 20 | 21 | Show all Recipes... 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |

On made a comment on:

31 |

32 | (Pending Moderation) 33 |
34 |
35 |
36 |
37 |
38 |
39 | 40 |
41 | 42 | 43 | Show all Questions... 44 | 45 | 46 | Show all Users... 47 | 48 |
49 |
50 | 51 |
52 |
53 | 54 |
55 | -------------------------------------------------------------------------------- /manual/generators/migration.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/migration.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:migration [NAME] [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | -g, [--generate] # Don't prompt for action - generate the migration 17 | -n, [--default-name] # Don't prompt for a migration name - just pick one 18 | -m, [--migrate] # Don't prompt for action - generate and migrate 19 | -d, [--drop] # Don't prompt with 'drop or rename' - just drop everything 20 | 21 | 22 | ## Runtime options 23 | 24 | 25 | 26 | -q, [--quiet] # Suppress status output 27 | -s, [--skip] # Skip files that already exist 28 | -f, [--force] # Overwrite files that already exist 29 | -p, [--pretend] # Run but do not make any changes 30 | 31 | 32 | ## Description 33 | 34 | 35 | 36 | 37 | This generator compares your existing schema against the 38 | schema declared inside your fields declarations in your 39 | models. 40 | 41 | If the generator finds differences, it will display the 42 | migration it has created, and ask you if you wish to 43 | [g]enerate migration, generate and [m]igrate now or [c]ancel? 44 | Enter "g" to just generate the migration but do not run it. 45 | Enter "m" to generate the migration and run it, or press "c" 46 | to do nothing. 47 | 48 | The generator will then prompt you for the migration name, 49 | supplying a numbered default name. 50 | 51 | The generator is conservative and will prompt you to resolve 52 | any ambiguities. 53 | 54 | 55 | ## Examples 56 | 57 | 58 | 59 | 60 | $ rails generate hobo:migration 61 | 62 | ---------- Up Migration ---------- 63 | create_table :foos do |t| 64 | t.datetime :created_at 65 | t.datetime :updated_at 66 | end 67 | ---------------------------------- 68 | 69 | ---------- Down Migration -------- 70 | drop_table :foos 71 | ---------------------------------- 72 | What now: [g]enerate migration, generate and [m]igrate now or [c]ancel? m 73 | 74 | Migration filename: 75 | (you can type spaces instead of '_' -- every little helps) 76 | Filename [hobo_migration_2]: create_foo 77 | exists db/migrate 78 | create db/migrate/20091023183838_create_foo.rb 79 | (in /work/foo) 80 | == CreateFoo: migrating ====================================================== 81 | -- create_table(:yos) 82 | -> 0.0856s 83 | == CreateFoo: migrated (0.0858s) ============================================= 84 | 85 | 86 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gem 'rails', '3.2.8' 4 | #gem 'rake', '0.8.7' 5 | #gem 'will_paginate', '~> 3.0.0' 6 | 7 | #gem 'sqlite3' 8 | gem 'mysql' 9 | 10 | gem 'yard' 11 | 12 | group :development do 13 | # set to 0.43 due to problem with .45 see https://github.com/rails/rails/pull/1671 14 | gem 'quiet_assets' 15 | end 16 | 17 | gem "maruku" 18 | 19 | #temp workaround for hash_secret issue see https://groups.google.com/forum/#!topic/hobousers/dS4VT_lyVIY 20 | gem "paperclip", "~> 2.7" 21 | # gem 'paperclip', :git => "git://github.com/jeanmartin/paperclip.git", :branch => "master" 22 | #required by paperclip 23 | gem "cocaine" 24 | 25 | gem "hobo_support", :git => "git://github.com/Hobo/hobo.git" 26 | gem "hobo_fields", :git => "git://github.com/Hobo/hobo.git" 27 | gem "dryml", :git => "git://github.com/Hobo/hobo.git" 28 | gem "hobo", :git => "git://github.com/Hobo/hobo.git" 29 | gem "hobo_rapid", :git => "git://github.com/Hobo/hobo.git" 30 | gem "hobo_clean", :git => "git://github.com/Hobo/hobo.git" 31 | gem "hobo_clean_sidemenu", :git => "git://github.com/Hobo/hobo.git" 32 | gem "hobo_clean_admin", :git => "git://github.com/Hobo/hobo.git" 33 | gem "hobo_jquery", :git => "git://github.com/Hobo/hobo.git" 34 | gem "hobo_jquery_ui", :git => "git://github.com/Hobo/hobo.git" 35 | gem "doc", :git => "git://github.com/Hobo/hobo.git" 36 | 37 | gem "jquery-rails" 38 | gem "jquery-ui-themes" 39 | 40 | group :development do 41 | gem "vlad", :require => false 42 | gem "vlad-git", :git => "git://github.com/bryanlarsen/vlad-git.git", :require => false 43 | end 44 | 45 | # Gems used only for assets and not required 46 | # in production environments by default. 47 | group :assets do 48 | gem 'sass-rails', '~> 3.2.3' 49 | gem 'coffee-rails', '~> 3.2.1' 50 | gem 'uglifier', '>= 1.0.3' 51 | gem 'execjs' 52 | gem 'therubyracer', '~> 0.10.2' 53 | end 54 | 55 | # Hobo plugins included solely for documentation 56 | gem "hobo_bootstrap", :git => "git://github.com/Hobo/hobo_bootstrap.git" 57 | gem "hobo_bootstrap_ui", :git => "git://github.com/Hobo/hobo_bootstrap_ui.git" 58 | gem "hobo_tree_table", :git => "git://github.com/Hobo/hobo_tree_table.git" 59 | gem "select_one_or_new_dialog", :git => "git://github.com/Hobo/select_one_or_new_dialog.git" 60 | gem "hobo_simple_color", :git => "git://github.com/Hobo/hobo_simple_color.git" 61 | gem "hobo_tokeninput", :git => "git://github.com/Hobo/hobo_tokeninput.git" 62 | gem "hobo_data_tables", :git => "git://github.com/Hobo/hobo_data_tables.git" 63 | gem "hobo_mapstraction", :git => "git://github.com/Hobo/hobo_mapstraction.git" 64 | gem "hobo_paperclip", :git => "git://github.com/Hobo/hobo_paperclip.git" 65 | gem "hobo_omniauth", :git => "git://github.com/Hobo/hobo_omniauth.git" 66 | 67 | gem "awesome_print" 68 | 69 | gem "recaptcha", :require => "recaptcha/rails" 70 | 71 | gem "will_paginate", :git => "git://github.com/Hobo/will_paginate.git" 72 | -------------------------------------------------------------------------------- /app/models/api_tag_def.rb: -------------------------------------------------------------------------------- 1 | class ApiTagDef < ActiveRecord::Base 2 | 3 | # so we can coexist with other 4 | # versions of the cookbook 5 | set_table_name "api_tag_defs_14" 6 | 7 | hobo_model # Don't put anything above this 8 | 9 | def to_param 10 | to_s 11 | end 12 | 13 | fields do 14 | tag :string, :name => true, :index => true 15 | extension :boolean 16 | polymorphic :boolean 17 | for_type :string 18 | 19 | short_description :html 20 | description :html 21 | tag_attributes :serialized, :class => Array 22 | tag_parameters :serialized, :class => Array 23 | 24 | merge_attrs :string 25 | merge_params :string 26 | 27 | source :text 28 | 29 | edit_link :string 30 | 31 | timestamps 32 | end 33 | 34 | belongs_to :taglib, :class_name => "ApiTaglib" 35 | has_many :comments, :class_name => "ApiTagComment", :dependent => :destroy 36 | 37 | #named_scope :no_for_type, :conditions => "for_type is null" 38 | scope :no_for_type, where("for_type is null") 39 | 40 | set_search_columns :tag, :short_description, :description, :source 41 | 42 | children :comments 43 | 44 | def full_name 45 | if taglib.plugin.name == taglib.name 46 | "#{tag} (#{taglib.name})" 47 | else 48 | "#{tag} (#{taglib.plugin.name}/#{taglib.name})" 49 | end 50 | end 51 | 52 | def def_line 53 | "<#{extension? ? 'extend' : 'def'} tag='#{tag}'#{' polymorphic' if polymorphic?}#{' for=\'' + for_type + '\'' if for_type}>" 54 | end 55 | 56 | def short_def_line 57 | "<#{full_name}#{' for=\'' + for_type + '\'' if for_type}>" 58 | end 59 | 60 | def short_short_def_line 61 | "<#{tag}#{' for=\'' + for_type + '\'' if for_type}>" 62 | end 63 | 64 | def typed_variants 65 | return [] if for_type 66 | ApiTagDef.find :all, :conditions => ["tag = ? AND (for_type is not null)", tag] 67 | end 68 | 69 | def all_attributes 70 | tag_attributes | merged_attributes 71 | end 72 | 73 | def merge_attrs_tagdef 74 | @merged_attrs_tagdef ||= ApiTagDef.find_by_tag(merge_attrs) 75 | end 76 | 77 | def merge_params_tagdef 78 | @merged_attrs_tagdef ||= ApiTagDef.find_by_tag(merge_attrs) 79 | end 80 | 81 | def merged_attributes 82 | merge_attrs_tagdef._?.all_attributes || [] 83 | end 84 | 85 | def documented? 86 | !(description.blank? && short_description.blank?) 87 | end 88 | 89 | # --- Hobo Permissions --- # 90 | 91 | def create_permitted? 92 | acting_user.administrator? 93 | end 94 | 95 | def update_permitted? 96 | acting_user.administrator? 97 | end 98 | 99 | def destroy_permitted? 100 | acting_user.administrator? 101 | end 102 | 103 | def view_permitted?(attribute) 104 | true 105 | end 106 | 107 | end 108 | 109 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | class User < ActiveRecord::Base 2 | 3 | hobo_user_model # Don't put anything above this 4 | 5 | fields do 6 | username :string, :login => true, :name => true 7 | email_address :email_address 8 | administrator :boolean, :default => false 9 | timestamps 10 | end 11 | 12 | # This gives admin rights to the first sign-up. 13 | # Just remove it if you don't want that 14 | before_create { |user| user.administrator = true if user.class.count == 0 } 15 | 16 | children :recipes, :questions, :answers 17 | 18 | scope :administrator, :conditions => {:administrator => true} 19 | 20 | # --- Signup lifecycle --- # 21 | 22 | lifecycle do 23 | 24 | state :active 25 | state :pending, :default => true 26 | 27 | create :signup, :available_to => "Guest", 28 | :params => [:username, :email_address, :password, :password_confirmation], 29 | :become => :pending 30 | 31 | transition :request_password_reset, { :active => :active }, :new_key => true do 32 | UserMailer.deliver_forgot_password(self, lifecycle.key) 33 | end 34 | 35 | transition :reset_password, { :active => :active }, :available_to => :key_holder, 36 | :params => [ :password, :password_confirmation ] 37 | 38 | transition :approve, { :pending => :active }, :available_to => "User.administrator" do 39 | # FIXME: use sweepers 40 | ActionController::Base.expire_page("/recipes/atom.xml") 41 | end 42 | 43 | transition :request_password_reset, { :pending => :pending }, :new_key => true do 44 | UserMailer.deliver_forgot_password(self, lifecycle.key) 45 | end 46 | 47 | transition :reset_password, { :pending => :pending }, :available_to => :key_holder, 48 | :params => [ :password, :password_confirmation ] 49 | 50 | end 51 | 52 | 53 | has_many :recipes, :dependent => :destroy 54 | has_many :questions, :dependent => :destroy 55 | has_many :answers, :dependent => :destroy 56 | has_many :comments, :dependent => :destroy 57 | 58 | #named_scope :recently_active, :order => "(select created_at from recipes where recipes.user_id = users.id order by created_at limit 1)", 59 | # :limit => 6 60 | scope :recently_active, order("(select created_at from recipes where recipes.user_id = users.id order by created_at limit 1)").limit(6) 61 | 62 | def account_active? 63 | true 64 | end 65 | 66 | # --- Hobo Permissions --- # 67 | 68 | def create_permitted? 69 | false 70 | end 71 | 72 | def update_permitted? 73 | acting_user.administrator? || (acting_user == self && only_changed?(:crypted_password, :email_address)) 74 | # Note: crypted_password has attr_protected so although it is permitted to change, it cannot be changed 75 | # directly from a form submission. 76 | end 77 | 78 | def destroy_permitted? 79 | acting_user.administrator? 80 | end 81 | 82 | def view_permitted?(field) 83 | true 84 | end 85 | 86 | end 87 | 88 | -------------------------------------------------------------------------------- /config/boot-old.rb: -------------------------------------------------------------------------------- 1 | # Don't change this file! 2 | # Configure your app in config/environment.rb and config/environments/*.rb 3 | 4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT) 5 | 6 | module Rails 7 | class << self 8 | def boot! 9 | unless booted? 10 | preinitialize 11 | pick_boot.run 12 | end 13 | end 14 | 15 | def booted? 16 | defined? Rails::Initializer 17 | end 18 | 19 | def pick_boot 20 | (vendor_rails? ? VendorBoot : GemBoot).new 21 | end 22 | 23 | def vendor_rails? 24 | File.exist?("#{RAILS_ROOT}/vendor/rails") 25 | end 26 | 27 | def preinitialize 28 | load(preinitializer_path) if File.exist?(preinitializer_path) 29 | end 30 | 31 | def preinitializer_path 32 | "#{RAILS_ROOT}/config/preinitializer.rb" 33 | end 34 | end 35 | 36 | class Boot 37 | def run 38 | load_initializer 39 | Rails::Initializer.run(:set_load_path) 40 | end 41 | end 42 | 43 | class VendorBoot < Boot 44 | def load_initializer 45 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" 46 | Rails::Initializer.run(:install_gem_spec_stubs) 47 | end 48 | end 49 | 50 | class GemBoot < Boot 51 | def load_initializer 52 | self.class.load_rubygems 53 | load_rails_gem 54 | require 'initializer' 55 | end 56 | 57 | def load_rails_gem 58 | if version = self.class.gem_version 59 | gem 'rails', version 60 | else 61 | gem 'rails' 62 | end 63 | rescue Gem::LoadError => load_error 64 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.) 65 | exit 1 66 | end 67 | 68 | class << self 69 | def rubygems_version 70 | Gem::RubyGemsVersion rescue nil 71 | end 72 | 73 | def gem_version 74 | if defined? RAILS_GEM_VERSION 75 | RAILS_GEM_VERSION 76 | elsif ENV.include?('RAILS_GEM_VERSION') 77 | ENV['RAILS_GEM_VERSION'] 78 | else 79 | parse_gem_version(read_environment_rb) 80 | end 81 | end 82 | 83 | def load_rubygems 84 | require 'rubygems' 85 | min_version = '1.3.1' 86 | unless rubygems_version >= min_version 87 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.) 88 | exit 1 89 | end 90 | 91 | rescue LoadError 92 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org) 93 | exit 1 94 | end 95 | 96 | def parse_gem_version(text) 97 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/ 98 | end 99 | 100 | private 101 | def read_environment_rb 102 | File.read("#{RAILS_ROOT}/config/environment.rb") 103 | end 104 | end 105 | end 106 | end 107 | 108 | # All that for this: 109 | Rails.boot! 110 | -------------------------------------------------------------------------------- /config/environment-old.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file 2 | 3 | # Uncomment below to force Rails into production mode when 4 | # you don't control web/app server and can't set it the proper way 5 | # ENV['RAILS_ENV'] ||= 'production' 6 | 7 | # Specifies gem version of Rails to use when vendor/rails is not present 8 | #RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION 9 | 10 | # Bootstrap the Rails environment, frameworks, and default configuration 11 | require File.join(File.dirname(__FILE__), 'boot') 12 | require 'thread' 13 | 14 | Rails::Initializer.run do |config| 15 | # Settings in config/environments/* take precedence over those specified here. 16 | # Application configuration should go into files in config/initializers 17 | # -- all .rb files in that directory are automatically loaded. 18 | # See Rails::Configuration for more options. 19 | 20 | # Skip frameworks you're not going to use. To use Rails without a database 21 | # you must remove the Active Record framework. 22 | # config.frameworks -= [ :active_record, :active_resource, :action_mailer ] 23 | 24 | # Specify gems that this application depends on. 25 | # They can then be installed with "rake gems:install" on new installations. 26 | # config.gem "bj" 27 | # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" 28 | # config.gem "aws-s3", :lib => "aws/s3" 29 | 30 | # Only load the plugins named here, in the order given. By default, all plugins 31 | # in vendor/plugins are loaded in alphabetical order. 32 | # :all can be used as a placeholder for all plugins not explicitly named 33 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ] 34 | 35 | # Add additional load paths for your own custom dirs 36 | # config.load_paths += %W( #{RAILS_ROOT}/extras ) 37 | 38 | # Force all environments to use the same logger level 39 | # (by default production uses :info, the others :debug) 40 | # config.log_level = :debug 41 | 42 | # Make Time.zone default to the specified zone, and make Active Record store time values 43 | # in the database in UTC, and return them converted to the specified local zone. 44 | # Run "rake -D time" for a list of tasks for finding time zone names. Comment line to use default local time. 45 | config.time_zone = 'UTC' 46 | 47 | # Your secret key for verifying cookie session data integrity. 48 | # If you change this key, all old sessions will become invalid! 49 | # Make sure the secret is at least 30 characters and all random, 50 | # no regular words or you'll be exposed to dictionary attacks. 51 | config.action_controller.session = { 52 | :session_key => '_hobocookbook_session', 53 | :secret => 'ec7275594d3796b3814f24ac7986ef85' 54 | } 55 | 56 | # Use the database for sessions instead of the cookie-based default, 57 | # which shouldn't be used to store highly confidential information 58 | # (create the session table with "rake db:sessions:create") 59 | # config.action_controller.session_store = :active_record_store 60 | 61 | # Use SQL instead of Active Record's schema dumper when creating the test database. 62 | # This is necessary if your schema can't be completely dumped by the schema dumper, 63 | # like if you have constraints or database-specific column types 64 | # config.active_record.schema_format = :sql 65 | 66 | # Activate observers that should always be running 67 | # config.active_record.observers = :cacher, :garbage_collector 68 | 69 | config.action_controller.page_cache_directory = "#{RAILS_ROOT}/public/cache/" 70 | end 71 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Hobocookbook::Application.routes.draw do 2 | root :to => 'front#index', :as => 'homepage' 3 | 4 | match 'search' => 'front#search', :as => 'site_search' 5 | match 'manual' => 'manual#index' 6 | match 'manual/:section' => 'manual#manual_section', :as => 'manual_section' 7 | match 'manual/:section/:subsection' => 'manual#manual_subsection' 8 | 9 | match 'tagdef/:plugin/:taglib/:tag' => 'api_tag_defs#tagdef', :as => 'tagdef' 10 | match 'tagdef/:plugin/:taglib/:tag/:for' => 'api_tag_defs#tagdef', :as => 'tagdef_for' 11 | 12 | match 'tutorials' => 'tutorials#index', :as => 'tutorials' 13 | match 'tutorials/:tutorial' => 'tutorials#show', :as => 'tutorial' 14 | 15 | match 'plugins' => "plugins#index", :as => 'plugins' 16 | match 'plugins/:plugin' => "plugins#show", :as => 'plugin' 17 | 18 | #map.site_search 'search', :controller => 'front', :action => 'search' 19 | 20 | # map.homepage '', :controller => 'front', :action => 'index' 21 | 22 | # map.manual 'manual', :controller => 'manual', :action => 'index' 23 | # map.manual_section 'manual/:section', :controller => 'manual', :action => 'manual_section' 24 | # map.manual_section 'manual/:section/:subsection', :controller => 'manual', :action => 'manual_subsection' 25 | 26 | # map.tutorials 'tutorials', :controller => 'tutorials', :action => 'index' 27 | # map.tutorial 'tutorials/:tutorial', :controller => 'tutorials', :action => 'show' 28 | # 29 | # map.plugins 'plugins', :controller => 'plugins', :action => 'index' 30 | # map.plugin 'plugins/:plugin', :controller => 'plugins', :action => 'show' 31 | 32 | # Hobo.add_routes(map) 33 | # The priority is based upon order of creation: 34 | # first created -> highest priority. 35 | 36 | # Sample of regular route: 37 | # match 'products/:id' => 'catalog#view' 38 | # Keep in mind you can assign values other than :controller and :action 39 | 40 | # Sample of named route: 41 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase 42 | # This route can be invoked with purchase_url(:id => product.id) 43 | 44 | # Sample resource route (maps HTTP verbs to controller actions automatically): 45 | # resources :products 46 | 47 | # Sample resource route with options: 48 | # resources :products do 49 | # member do 50 | # get 'short' 51 | # post 'toggle' 52 | # end 53 | # 54 | # collection do 55 | # get 'sold' 56 | # end 57 | # end 58 | 59 | # Sample resource route with sub-resources: 60 | # resources :products do 61 | # resources :comments, :sales 62 | # resource :seller 63 | # end 64 | 65 | # Sample resource route with more complex sub-resources 66 | # resources :products do 67 | # resources :comments 68 | # resources :sales do 69 | # get 'recent', :on => :collection 70 | # end 71 | # end 72 | 73 | # Sample resource route within a namespace: 74 | # namespace :admin do 75 | # # Directs /admin/products/* to Admin::ProductsController 76 | # # (app/controllers/admin/products_controller.rb) 77 | # resources :products 78 | # end 79 | 80 | # You can have the root of your site routed with "root" 81 | # just remember to delete public/index.html. 82 | # root :to => "welcome#index" 83 | 84 | # See how all your routes lay out with "rake routes" 85 | 86 | # This is a legacy wild controller route that's not recommended for RESTful applications. 87 | # Note: This route will make all actions in every controller accessible via GET requests. 88 | # match ':controller(/:action(/:id(.:format)))' 89 | end 90 | -------------------------------------------------------------------------------- /manual/generators/setup_wizard.markdown: -------------------------------------------------------------------------------- 1 | Generators -- manual/generators/setup\_wizard.markdown 2 | {: .document-title} 3 | 4 | 5 | ## Usage 6 | 7 | 8 | 9 | rails generate hobo:setup_wizard [options] 10 | 11 | 12 | ## Options 13 | 14 | 15 | 16 | [--add-admin-subsite] # Add an Admin Subsite 17 | -t, [--test-framework=TEST_FRAMEWORK] # Use a specific test framework 18 | # Default: test_unit 19 | [--migration-generate] # Generate migration only 20 | [--main-title] # Shows the main title 21 | # Default: true 22 | [--admin-subsite-name=ADMIN_SUBSITE_NAME] # Admin Subsite Name 23 | # Default: admin 24 | [--user-resource-name=USER_RESOURCE_NAME] # User Resource Name 25 | # Default: user 26 | [--migration-migrate] # Generate migration and migrate 27 | # Default: true 28 | [--wizard] # Ask instead using options 29 | # Default: true 30 | [--fixtures] # Add the fixture option to the test framework 31 | # Default: true 32 | [--default-locale=DEFAULT_LOCALE] # Sets the default locale 33 | [--admin-theme=ADMIN_THEME] # Admin Theme 34 | # Default: clean 35 | [--fixture-replacement=FIXTURE_REPLACEMENT] # Use a specific fixture replacement 36 | [--activation-email] # Send an email to activate the account 37 | [--git-repo] # Create the git repository with the initial commit 38 | [--front-controller-name=FRONT_CONTROLLER_NAME] # Front Controller Name 39 | # Default: front 40 | [--admin-ui-theme=ADMIN_UI_THEME] # Admin jQuery-UI Theme 41 | # Default: redmond 42 | [--gitignore-auto-generated-files] # Add the auto-generated files to .gitignore 43 | # Default: true 44 | [--locales=one two three] # Choose the locales 45 | # Default: en 46 | [--front-theme=FRONT_THEME] # Front Theme 47 | # Default: clean 48 | [--dryml-only-templates] # The application uses only dryml templates 49 | [--invite-only] # Require invitation to join site 50 | [--front-ui-theme=FRONT_UI_THEME] # Front jQuery-UI Theme 51 | # Default: redmond 52 | [--update] # Run bundle update to install the missing gems 53 | [--private-site] # Make the site unaccessible to non-members 54 | 55 | 56 | ## Runtime options 57 | 58 | 59 | 60 | -q, [--quiet] # Suppress status output 61 | -s, [--skip] # Skip files that already exist 62 | -f, [--force] # Overwrite files that already exist 63 | -p, [--pretend] # Run but do not make any changes 64 | 65 | 66 | ## Description 67 | 68 | 69 | 70 | This wizard is used by bin/hobo to configure a new 71 | created application. You can use it directly in order 72 | to overwrite any file of the original installation. 73 | -------------------------------------------------------------------------------- /gitorials/gitorial.markdown: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Gitorial Sidebar 8 | {: .document-title} 9 | 10 | Contents 11 | {: .contents-heading} 12 | 13 | - contents 14 | {:toc} 15 | 16 | # Gitorial Sidebar 17 | 18 | The agility tutorial is a 'gitorial', a tutorial made with 19 | [git](http://www.git-scm.org/). 20 | 21 | ## Using patch 22 | 23 | The patches we have displayed are simplified for on-screen viewing. 24 | However, there is a link beside each entry you can click on to 25 | download the raw patch. To apply the raw patch from your project's 26 | root directory: 27 | 28 | patch -p1 < patch-file 29 | 30 | ## Using git fully 31 | 32 | Following along using git allows you to quickly and easily skip 33 | through the tutorial. Doing so requires a little bit of git 34 | knowledge -- you may not wish to learn git and Hobo simultaneously. 35 | 36 | Check out the [application from 37 | github](http://github.com/Hobo/agility-gitorial/tree/master): 38 | 39 | $ git clone git://github.com/Hobo/agility-gitorial.git 40 | $ cd agility-gitorial 41 | 42 | Now rewind the tutorial to the beginning, and create your own branch 43 | to record your changes. 44 | 45 | $ git checkout gitorial-004 46 | $ git checkout -b my_branch 47 | 48 | You'll notice that the first command gives you a warning, recommending 49 | that you also run the second command. You should also notice that 50 | we're starting at step four -- this includes the ".gitignore" file and 51 | the initial run of the hobo command. 52 | 53 | Start the tutorial, and follow along. 54 | 55 | Every once in a while, check in your progress: 56 | 57 | $ git add . 58 | $ git commit 59 | 60 | After checking in your progress, you can merge in the changes from the 61 | gitorial to see if you typed everything in correctly or not. For 62 | example, if the first time you checked in your progress is at step 63 | gitorial-020: 64 | 65 | $ git merge gitorial-020 66 | 67 | It's quite likely there are conflicts -- you didn't follow the 68 | tutorial exactly. For instance, if your `tasks_controller.rb` is 69 | different, you'll see a message like: 70 | 71 | CONFLICT (content): Merge conflict in app/controllers/tasks_controller.rb 72 | Automatic merge failed; fix conflicts and then commit the result. 73 | 74 | Edit `tasks_controller.rb` to fix the conflict, and then resolve the 75 | conflict: 76 | 77 | $ git add app/controllers/tasks_controller.rb 78 | $ git commit 79 | 80 | Once you have your current position merged in cleanly, you can skip 81 | ahead to any point in the tutorial: 82 | 83 | $ git merge gitorial-060 84 | 85 | You can only jump forwards. To jump backwards, utilize a different 86 | mechanism, such as `git checkout` or `Stacked Git`. 87 | 88 | ## Using git checkout 89 | 90 | This mechanism is the quickest way to jump around in the tutorial. 91 | However, any changes you make will be lost. 92 | 93 | $ git clone git://github.com/Hobo/agility-gitorial.git 94 | $ cd agility-gitorial 95 | $ git submodule update --init 96 | 97 | Then you can switch to any point in the tutorial: 98 | 99 | $ git checkout gitorial-001 100 | 101 | ## Using stacked git 102 | 103 | We used [Stacked Git](http://www.procode.org/stgit/) to develop this 104 | gitorial. It's a great tool to follow this gitorial. 105 | 106 | Instructions for using stacked git with this gitorial are in the 107 | README in our [source 108 | repository](http://github.com/Hobo/agility-gitorial-patches/tree/master). 109 | 110 | # Updating to later versions of the tutorial 111 | 112 | To keep the gitorial clean, updates to the gitorial **rewrite 113 | history**. That means that you cannot `git pull`. If you wish to 114 | update to a later version of the tutorial, you must `git clone` the 115 | repository again and manually move any changes you have made from your 116 | old clone to the new one. 117 | 118 | 119 | gitorial-002: [view on github](http://github.com/Hobo/agility-gitorial/commit/ec14ee2939346e0be5d36ad866c8b2f89ff7796b), [download 02-gitorial-sidebar.patch](/patches/agility/02-gitorial-sidebar.patch) 120 | {: .commit} 121 | -------------------------------------------------------------------------------- /app/models/gitorial.rb: -------------------------------------------------------------------------------- 1 | class Gitorial 2 | # directory: point at the git repository 3 | # commit_link_base: the base for URL's to view the commit 4 | # patch_link_base: the base for URL's to download the patch 5 | def initialize(directory, commit_link_base="http://github.com/Hobo/agility-gitorial/commit/", patch_link_base="/patches/agility/") 6 | @gitlogp = `cd #{directory}; git pack-refs --all ; git log --unified=5 --reverse gitorial-001^..HEAD` 7 | @tag_refs = File.readlines("#{Rails.root}/.git/modules/gitorials/agility/packed-refs") 8 | @commit_link_base=commit_link_base 9 | @patch_link_base=patch_link_base 10 | end 11 | 12 | def tags 13 | @tags ||= begin 14 | tags = Hash.new { |hash, key| hash[key]=key.slice(0,6) } 15 | @tag_refs.slice(1..-1).each do |ref| 16 | refs = ref.split 17 | if File.dirname(refs[1])=="refs/tags" 18 | tags[refs[0]] = File.basename(refs[1]) 19 | end 20 | end 21 | tags 22 | end 23 | end 24 | 25 | # returns a hash: filenames and contents 26 | def process 27 | filename = "index.markdown" 28 | markdowns = {filename => []} 29 | state = :message 30 | message = ["\n"] 31 | patch = [] 32 | commit = nil 33 | (@gitlogp.split("\n")+["DONE"]).each { |line| 34 | words=line.split 35 | if line.slice(0,1)==" " || words.length==0 36 | # commit messages start with 4 spaces, diff contents with 1 space 37 | if state==:message 38 | if words[0]=="OUTPUT_FILE:" 39 | filename = words[1] 40 | markdowns[filename] ||= [] 41 | else 42 | message << "#{line.slice(4..-1)}" 43 | end 44 | else 45 | patch << " #{line}" if state==:patch 46 | end 47 | elsif words[0]=="commit" or words[0]=="DONE" 48 | if !commit.nil? 49 | # replace the short description line with a named link 50 | shortlog = message[2] 51 | message[2] = " " 52 | markdowns[filename] += message.map {|l| 53 | if l=="SHOW_PATCH" 54 | (patch+["{: .diff}\n"]).join("\n") 55 | else 56 | l 57 | end 58 | } 59 | series = tags[commit].slice(-2..-1) 60 | markdowns[filename] << "\n#{tags[commit]}: [view on github](#{@commit_link_base}#{commit}), [download #{series}-#{shortlog}.patch](#{@patch_link_base}/#{series}-#{shortlog}.patch)\n{: .commit}\n" 61 | end 62 | 63 | message=["\n"] 64 | patch=[] 65 | 66 | commit = words[1] 67 | state = :message 68 | elsif ["Author:", "Date:", "new", "index", "---", "+++", '\\'].include?(words[0]) 69 | # chomp 70 | elsif words[0]=="diff" 71 | state = :patch 72 | left = words[2].slice(2..-1) 73 | right = words[3].slice(2..-1) 74 | if left==right 75 | patch << " ::: #{right}" 76 | else 77 | patch << " ::: #{left} -> #{right}" 78 | end 79 | elsif words[0]=="@@" 80 | # git tries to put the function or class name after @@. This 81 | # works great for C diffs, but it only finds the class name in 82 | # Ruby, which is usually similar to the file name, Therefore 83 | # it's distracting cruft. Toss it. 84 | patch << " #{words.slice(0,4).join(" ")}" 85 | else 86 | message << "#{line.slice(4..-1)}" if state==:message 87 | patch << " #{line}" if state==:patch 88 | end 89 | } 90 | output = {} 91 | markdowns.each do |fn, markdown| 92 | output[fn] = markdown.join("\n") 93 | Rails.logger.info(output[fn]) if respond_to? :Rails 94 | end 95 | return output 96 | end 97 | end 98 | 99 | if $0 == __FILE__ 100 | if ARGV.size < 2 101 | puts "Usage: ruby #{$0} commit_link_base patch_link_base " 102 | puts "Example: ruby #{$0} http://github.com/bryanlarsen/agility-gitorial/commit/ /patches/agility/" 103 | exit 1 104 | end 105 | repository_directory=ARGV[2] 106 | repository_directory ||= '.' 107 | output_directory=ARGV[3] 108 | output_directory ||= '.' 109 | puts repository_directory 110 | puts output_directory 111 | 112 | Gitorial.new(repository_directory, ARGV[0], ARGV[1]).process.each {|fn, contents| 113 | f=open("#{output_directory}/#{fn}", "w") 114 | f.write(contents) 115 | f.close # need explicit close so Rakefiles work 116 | } 117 | end 118 | -------------------------------------------------------------------------------- /lib/api_doc_loader.rb: -------------------------------------------------------------------------------- 1 | require 'English' 2 | 3 | module ApiDocLoader 4 | 5 | # TAGLIB_HOME = "#{RAILS_ROOT}/vendor/plugins/hobo/hobo/taglibs" 6 | # TAGLIB_HOME = "#{Rails.root}/vendor/hobo13/hobo/lib/hobo/rapid/taglibs" 7 | TAGLIB_HOME = "#{Hobo.root}/lib/hobo/rapid/taglibs" 8 | INTERNAL_PLUGINS = [ HoboRapid, HoboJquery, HoboClean, HoboCleanAdmin] 9 | PLUGINS_HOME = "#{Rails.root}/taglibs" 10 | 11 | class Taglib < Dryml::DrymlDoc::Taglib 12 | 13 | 14 | def api_taglib(api_plugin) 15 | ApiTaglib.new(:name => name, :short_description => comment_intro_html, :description => comment_rest_html, :plugin => api_plugin) 16 | end 17 | 18 | def api_tagdefs(api_taglib, edit_link) 19 | tag_defs.map do |tag_def| 20 | tag_def.api_tagdef(api_taglib, edit_link) 21 | end.select{|t| t} 22 | end 23 | 24 | end 25 | 26 | class Helper 27 | include Rails.application.routes.url_helpers 28 | include ActionView::Helpers 29 | def link(tag) 30 | link_to("<#{tag.tag}>", {:controller => :api_tag_defs, :action => :tagdef, :plugin => tag.taglib.plugin.name, :taglib => tag.taglib.name, :tag => tag.tag}, {:class => "tag-link"}) 31 | end 32 | end 33 | 34 | 35 | 36 | class TagDef < Dryml::DrymlDoc::TagDef 37 | 38 | def api_tagdef(owner, edit_link) 39 | return if no_doc? 40 | t = ApiTagDef.find_or_initialize_by_tag_and_for_type_and_taglib_id(name, for_type, owner.id) 41 | t.taglib = owner 42 | t.edit_link = edit_link 43 | t.attributes = { :tag => name, :extension => extension?, :polymorphic => polymorphic?, 44 | :short_description => comment_intro_html, 45 | :description => comment_rest_html, 46 | :for_type => for_type, 47 | :tag_attributes => attributes, :tag_parameters => parameters, 48 | :merge_params => merge_params, :merge_attrs => merge_attrs, 49 | :source => source } 50 | ApiDocLoader.all_tags << name 51 | t 52 | end 53 | end 54 | 55 | def self.all_tags 56 | @all_tags ||= [] 57 | end 58 | 59 | def self.create_taglib(plugin, dir, name) 60 | filename = "#{dir}/#{name}.dryml" 61 | taglib = ApiDocLoader::Taglib.new(dir, filename, name) 62 | api_taglib = taglib.api_taglib(plugin) 63 | api_taglib.edit_link = File.join(plugin.edit_link_base, filename[-(filename.length - plugin.dir.to_s.length - 1)..-1]) 64 | api_taglib.tags = taglib.api_tagdefs(api_taglib, api_taglib.edit_link) 65 | taglib.tag_defs.clear 66 | 67 | (Dir["#{dir}/*.dryml"] - ["#{dir}/#{name}.dryml"]).sort.map {|filename| 68 | taglib.parse_file filename 69 | edit_link = File.join(plugin.edit_link_base, filename[-(filename.length - plugin.dir.to_s.length - 1)..-1]) 70 | api_taglib.tags += taglib.api_tagdefs(api_taglib, edit_link) 71 | taglib.tag_defs.clear 72 | } 73 | 74 | unless api_taglib.tags.blank? 75 | api_taglib.save! 76 | plugin.taglibs << api_taglib 77 | end 78 | api_taglib 79 | end 80 | 81 | def self.load 82 | clear 83 | 84 | [Dryml,HoboRapid,HoboJquery,HoboJqueryUi,HoboClean,HoboCleanSidemenu,HoboBootstrap,HoboBootstrapUi,HoboPaperclip,HoboOmniauth,HoboDataTables,HoboTokeninput,HoboSimpleColor,HoboTreeTable,HoboMapstraction,SelectOneOrNewDialog].each_with_index do |mod, position| 85 | plugin = ApiPlugin.new 86 | plugin.dir = mod.root 87 | plugin.name = mod.name.underscore 88 | puts "**** #{plugin.name}" 89 | plugin.position = position+1 90 | plugin.edit_link_base = mod::EDIT_LINK_BASE 91 | readme_file = Dir["#{plugin.dir}/README*"].first 92 | plugin.edit_link = File.join(plugin.edit_link_base, File.basename(readme_file)) 93 | readme = File.read(readme_file) 94 | if readme =~ /(.*?\n)^#/m 95 | plugin.short_description = Maruku.new($1).to_html 96 | plugin.description = Maruku.new($POSTMATCH).to_html 97 | else 98 | plugin.short_description = Maruku.new(readme).to_html 99 | plugin.description = "" 100 | end 101 | 102 | ApiDocLoader.create_taglib(plugin, "#{plugin.dir}/taglibs", plugin.name) 103 | 104 | Dir["#{plugin.dir}/taglibs/*/"].sort.each do |dir| 105 | ApiDocLoader.create_taglib(plugin, dir[0..-2], File.basename(dir)) 106 | end 107 | 108 | plugin.save! 109 | 110 | end 111 | 112 | ApiTagDef.all.each do |tag| 113 | b = Proc.new do |t| 114 | tt=ApiTagDef.find_by_tag($1) 115 | if tt.nil? 116 | unless %w(def div ul select li td th span br ol img textarea).include?($1) 117 | puts "Could not link to #{$1} in #{tag.tag}" 118 | end 119 | t 120 | else 121 | Helper.new.link(tt) 122 | end 123 | end 124 | re = /<([-a-zA-Z0-9]*)[!:]*?\/?><\/code>/ 125 | tag.short_description = tag.short_description.gsub(re, &b) 126 | tag.description = tag.description.gsub(re, &b) 127 | tag.save! 128 | end 129 | end 130 | 131 | def self.clear 132 | ApiPlugin.delete_all 133 | ApiTaglib.delete_all 134 | ApiTagDef.delete_all 135 | end 136 | 137 | end 138 | 139 | -------------------------------------------------------------------------------- /gitorials/subsite.markdown: -------------------------------------------------------------------------------- 1 | # Adding an Administration subsite to an existing Rails 3 application 2 | 3 | This tutorial will show how you can create an administrative subsite 4 | for an existing Rails application. This will allow the administrator 5 | to create, update and destroy any database row without writing any 6 | view code -- only three lines of controller code for each model! 7 | 8 | It should also be useful for those who wish to add a subsite to a Hobo 9 | application. If you already have a Hobo application, some of the 10 | steps mentioned here will be unnecessary. 11 | 12 | In this tutorial, we've placed the Hobofied controllers and views in a 13 | subsite. However, it is certainly possible to mix Hobo code 14 | into your existing controllers. If you have any questions, [the 15 | mailing list](http://groups.google.com/group/hobousers) is probably 16 | your best resource. 17 | 18 | ## Install Hobo 19 | 20 | The application that I'm going to convert is called **scheduler**. 21 | Let's add a Hobo dependency to it. 22 | 23 | $ gem install hobo 24 | 25 | Inside the Gemfile add: 26 | 27 | gem 'hobo' 28 | 29 | It might be a good idea to run your application and confirm that 30 | everything still works. 31 | 32 | Now might also be a good time to make sure you have your source code 33 | backed up, preferably in an SCM tool like git or subversion. We're 34 | going to be running some generators: they will ask you before eventually 35 | overwriting some existing file, but just in case you make any mistake. 36 | 37 | Notice: When you run in a conflict with an existing file you can see the diffs 38 | by typing 'd'. Check also the other options. 39 | 40 | ## Run the Hobo generators 41 | 42 | Now we'll ask Hobo to copy it's shared files into your application. 43 | These are mostly javascript, css and dryml files 44 | 45 | $ hobo g assets 46 | $ hobo g rapid 47 | 48 | Now let's create our admin subsite: 49 | 50 | $ hobo g subsite admin --make-front-site 51 | $ hobo g front_controller admin::front --add-routes 52 | 53 | Note that if you use `admin_subsite` rather than `subsite`, the 54 | subsite will be limited to the administrator. For this to work, you 55 | will need to complete the section labelled "Updating your User Model", 56 | below. 57 | 58 | ## Hobofying a model 59 | 60 | Adding the Hobo magic to a model requires two things: 61 | 62 | Add this to the top of your model: 63 | 64 | Class Event < ActiveRecord::Base 65 | hobo_model # Don't put anything above this 66 | ... 67 | 68 | Secondly, all Hobo models require four permission functions. Here is 69 | what I use in my user model: 70 | 71 | # --- Permissions --- # 72 | 73 | def create_permitted? 74 | false 75 | end 76 | 77 | def update_permitted? 78 | acting_user.administrator? || (acting_user == self && only_changed?(:crypted_password, :email_address)) 79 | # Note: crypted_password has attr_protected so although it is permitted to change, it cannot be changed 80 | # directly from a form submission. 81 | end 82 | 83 | def destroy_permitted? 84 | acting_user.administrator? 85 | end 86 | 87 | def view_permitted?(field) 88 | true 89 | end 90 | 91 | For now, I recommend returning _true_ from all of these permission 92 | functions. After hobofying your User model, these functions will 93 | become easier to write. 94 | 95 | If your model does not have a column called "name", I recommend 96 | defining a function on your model that returns a human readable 97 | summary of the row. 98 | 99 | ## Creating a controller for the hobofied model: 100 | 101 | I'm going to create an Admin::Event controller for my event model. 102 | This file goes in `app/controllers/admin/events_controller.rb`: 103 | 104 | class Admin::EventsController < Admin::AdminSiteController 105 | hobo_model_controller Event 106 | auto_actions :all 107 | end 108 | 109 | At this stage you should be able to run your application. If you 110 | browse to "/admin/events", you can create, remove, update and destroy 111 | any events you have permission to access. 112 | 113 | ## Modifying the views 114 | 115 | If you need to modify the views for your subsite, you may create 116 | subdirectories in `app/views/admin`. For example, 117 | `app/views/admin/foos/show.dryml` is the show view for the foos 118 | controller. 119 | 120 | `app/views/taglibs/admin_site.dryml` is the equivalent of 121 | application.dryml for your subsite. 122 | 123 | ## Updating your User model 124 | 125 | At this stage you have created an administrator interface, and could 126 | stop here. However, as far as Hobo is concerned, any users are 127 | logged in as a guest. To distinguish administrators from normal users 128 | from random surfers, hackers and bots, we will need to set up an 129 | authentication system. 130 | 131 | ### If you don't have one 132 | 133 | If you don't currently have a User model, type: 134 | 135 | $ hobo g user_resource User 136 | $ hobo g migration 137 | 138 | The last generator will ask if you wish to run the migration immediately. Enter "m" to tell it to do so. 139 | 140 | The following pages will now be available: 141 | 142 | * `/users/signup` 143 | * `/forgot_password` 144 | * `/login` 145 | * `/logout` 146 | 147 | ### If you have a User model 148 | 149 | Most likely, you already have a User model and authentication system. 150 | In most cases, it is quite easy to make this Hobo compatible. 151 | 152 | First of all, you should add the following line to the top of your 153 | model: 154 | 155 | hobo_model # Don't put anything above this 156 | 157 | Do not use `hobo_user_model` -- this will pull in authentication 158 | functions and database columns. 159 | 160 | Many User models have the columns *name:string* and 161 | *administrator:boolean*. If your model does not, create appropriate functions to 162 | mimic this behaviour. For example: 163 | 164 | def name 165 | "#{first_name} #{last_name}" 166 | end 167 | 168 | def administrator 169 | role == "administrator" 170 | end 171 | 172 | Also, Hobo requires the following functions to be defined on your 173 | User model. Define appropriately. Here is what I used: 174 | 175 | def to_s 176 | name 177 | end 178 | 179 | def guest? 180 | false 181 | end 182 | 183 | def signed_up? 184 | true 185 | end 186 | 187 | def login 188 | email_address 189 | end 190 | 191 | Finally, you need to let Hobo know who the current user is. This is 192 | done by setting a session variable when the user logs in: 193 | 194 | session[:user] = user.typed_id 195 | 196 | In my case, a very similar line was placed in `SessionsController::create` 197 | 198 | From now on, an instantiated User or Guest object will be available in 199 | `current_user` in your controllers and views. It will also be 200 | available in `acting_user` in your permission functions in your 201 | hobofied models. 202 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # Note that this schema.rb definition is the authoritative source for your 6 | # database schema. If you need to create the application database on another 7 | # system, you should be using db:schema:load, not running all the migrations 8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 9 | # you'll amass, the slower it'll run and the greater likelihood for issues). 10 | # 11 | # It's strongly recommended to check this file into your version control system. 12 | 13 | ActiveRecord::Schema.define(:version => 20120311165826) do 14 | 15 | create_table "answers", :force => true do |t| 16 | t.datetime "created_at" 17 | t.datetime "updated_at" 18 | t.integer "user_id" 19 | t.integer "recipe_id" 20 | t.integer "question_id" 21 | t.text "body" 22 | t.boolean "markdown" 23 | end 24 | 25 | add_index "answers", ["question_id"], :name => "index_answers_on_question_id" 26 | add_index "answers", ["recipe_id"], :name => "index_answers_on_recipe_id" 27 | add_index "answers", ["user_id"], :name => "index_answers_on_user_id" 28 | 29 | create_table "api_plugins_14", :force => true do |t| 30 | t.string "name" 31 | t.text "short_description" 32 | t.text "description" 33 | t.string "edit_link_base" 34 | t.string "edit_link" 35 | t.datetime "created_at" 36 | t.datetime "updated_at" 37 | t.integer "position" 38 | end 39 | 40 | create_table "api_tag_comments", :force => true do |t| 41 | t.text "body" 42 | t.boolean "markdown" 43 | t.datetime "created_at" 44 | t.datetime "updated_at" 45 | t.integer "api_tag_def_id" 46 | t.integer "user_id" 47 | end 48 | 49 | create_table "api_tag_comments_14", :force => true do |t| 50 | t.text "body" 51 | t.boolean "markdown" 52 | t.datetime "created_at" 53 | t.datetime "updated_at" 54 | t.integer "api_tag_def_id" 55 | t.integer "user_id" 56 | end 57 | 58 | add_index "api_tag_comments_14", ["api_tag_def_id"], :name => "index_api_tag_comments_14_on_api_tag_def_id" 59 | add_index "api_tag_comments_14", ["user_id"], :name => "index_api_tag_comments_14_on_user_id" 60 | 61 | create_table "api_tag_defs", :force => true do |t| 62 | t.string "tag" 63 | t.boolean "extension" 64 | t.boolean "polymorphic" 65 | t.string "for_type" 66 | t.text "description" 67 | t.text "tag_attributes" 68 | t.text "tag_parameters" 69 | t.string "merge_attrs" 70 | t.string "merge_params" 71 | t.datetime "created_at" 72 | t.datetime "updated_at" 73 | t.integer "taglib_id" 74 | t.text "short_description" 75 | t.text "source" 76 | end 77 | 78 | create_table "api_tag_defs_14", :force => true do |t| 79 | t.string "tag" 80 | t.boolean "extension" 81 | t.boolean "polymorphic" 82 | t.string "for_type" 83 | t.text "short_description" 84 | t.text "description" 85 | t.text "tag_attributes" 86 | t.text "tag_parameters" 87 | t.string "merge_attrs" 88 | t.string "merge_params" 89 | t.text "source" 90 | t.string "edit_link" 91 | t.datetime "created_at" 92 | t.datetime "updated_at" 93 | t.integer "taglib_id" 94 | end 95 | 96 | add_index "api_tag_defs_14", ["taglib_id"], :name => "index_api_tag_defs_14_on_taglib_id" 97 | 98 | create_table "api_taglibs", :force => true do |t| 99 | t.string "name" 100 | t.datetime "created_at" 101 | t.datetime "updated_at" 102 | t.text "description" 103 | t.text "short_description" 104 | t.string "library" 105 | end 106 | 107 | create_table "api_taglibs_14", :force => true do |t| 108 | t.string "name" 109 | t.text "short_description" 110 | t.text "description" 111 | t.string "edit_link" 112 | t.datetime "created_at" 113 | t.datetime "updated_at" 114 | t.integer "plugin_id" 115 | end 116 | 117 | add_index "api_taglibs_14", ["plugin_id"], :name => "index_api_taglibs_14_on_plugin_id" 118 | 119 | create_table "comments", :force => true do |t| 120 | t.text "body" 121 | t.boolean "markdown" 122 | t.datetime "created_at" 123 | t.datetime "updated_at" 124 | t.integer "user_id" 125 | t.integer "recipe_id" 126 | end 127 | 128 | add_index "comments", ["recipe_id"], :name => "index_comments_on_recipe_id" 129 | add_index "comments", ["user_id"], :name => "index_comments_on_user_id" 130 | 131 | create_table "images", :force => true do |t| 132 | t.datetime "created_at" 133 | t.datetime "updated_at" 134 | t.integer "recipe_id" 135 | t.string "image_file_name" 136 | t.string "image_content_type" 137 | t.integer "image_file_size", :limit => 4 138 | t.datetime "image_updated_at" 139 | end 140 | 141 | add_index "images", ["recipe_id"], :name => "index_images_on_recipe_id" 142 | 143 | create_table "questions", :force => true do |t| 144 | t.text "description" 145 | t.boolean "markdown" 146 | t.datetime "created_at" 147 | t.datetime "updated_at" 148 | t.integer "user_id" 149 | t.string "subject" 150 | end 151 | 152 | add_index "questions", ["user_id"], :name => "index_questions_on_user_id" 153 | 154 | create_table "recipes", :force => true do |t| 155 | t.string "name" 156 | t.text "body" 157 | t.datetime "created_at" 158 | t.datetime "updated_at" 159 | t.integer "user_id" 160 | end 161 | 162 | add_index "recipes", ["user_id"], :name => "index_recipes_on_user_id" 163 | 164 | create_table "taggings", :force => true do |t| 165 | t.datetime "created_at" 166 | t.datetime "updated_at" 167 | t.integer "tag_id" 168 | t.integer "recipe_id" 169 | end 170 | 171 | add_index "taggings", ["recipe_id"], :name => "index_taggings_on_recipe_id" 172 | add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" 173 | 174 | create_table "tags", :force => true do |t| 175 | t.string "name" 176 | t.datetime "created_at" 177 | t.datetime "updated_at" 178 | end 179 | 180 | create_table "users", :force => true do |t| 181 | t.string "crypted_password", :limit => 40 182 | t.string "salt", :limit => 40 183 | t.string "remember_token" 184 | t.datetime "remember_token_expires_at" 185 | t.string "username" 186 | t.string "email_address" 187 | t.boolean "administrator", :default => false 188 | t.datetime "created_at" 189 | t.datetime "updated_at" 190 | t.string "state", :default => "active" 191 | t.datetime "key_timestamp" 192 | end 193 | 194 | add_index "users", ["state"], :name => "index_users_on_state" 195 | 196 | end 197 | -------------------------------------------------------------------------------- /app/assets/javascripts/application/code_highlighter.js: -------------------------------------------------------------------------------- 1 | /* Unobtrustive Code Highlighter By Dan Webb 11/2005 2 | Version: 0.4 3 | 4 | Usage: 5 | Add a script tag for this script and any stylesets you need to use 6 | to the page in question, add correct class names to CODE elements, 7 | define CSS styles for elements. That's it! 8 | 9 | Known to work on: 10 | IE 5.5+ PC 11 | Firefox/Mozilla PC/Mac 12 | Opera 7.23 + PC 13 | Safari 2 14 | 15 | Known to degrade gracefully on: 16 | IE5.0 PC 17 | 18 | Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors 19 | in older browsers use expressions that use lookahead in string format when defining stylesets. 20 | 21 | This script is inspired by star-light by entirely cunning Dean Edwards 22 | http://dean.edwards.name/star-light/. 23 | */ 24 | 25 | // replace callback support for safari. 26 | if ("a".replace(/a/, function() {return "b"}) != "b") (function(){ 27 | var default_replace = String.prototype.replace; 28 | String.prototype.replace = function(search,replace){ 29 | // replace is not function 30 | if(typeof replace != "function"){ 31 | return default_replace.apply(this,arguments) 32 | } 33 | var str = "" + this; 34 | var callback = replace; 35 | // search string is not RegExp 36 | if(!(search instanceof RegExp)){ 37 | var idx = str.indexOf(search); 38 | return ( 39 | idx == -1 ? str : 40 | default_replace.apply(str,[search,callback(search, idx, str)]) 41 | ) 42 | } 43 | var reg = search; 44 | var result = []; 45 | var lastidx = reg.lastIndex; 46 | var re; 47 | while((re = reg.exec(str)) != null){ 48 | var idx = re.index; 49 | var args = re.concat(idx, str); 50 | result.push( 51 | str.slice(lastidx,idx), 52 | callback.apply(null,args).toString() 53 | ); 54 | if(!reg.global){ 55 | lastidx += RegExp.lastMatch.length; 56 | break 57 | }else{ 58 | lastidx = reg.lastIndex; 59 | } 60 | } 61 | result.push(str.slice(lastidx)); 62 | return result.join("") 63 | } 64 | })(); 65 | 66 | var CodeHighlighter = { styleSets : new Array }; 67 | 68 | CodeHighlighter.addStyle = function(name, rules) { 69 | // using push test to disallow older browsers from adding styleSets 70 | if ([].push) this.styleSets.push({ 71 | name : name, 72 | rules : rules, 73 | ignoreCase : arguments[2] || false 74 | }) 75 | 76 | function setEvent() { 77 | // set highlighter to run on load (use LowPro if present) 78 | if (typeof Event != 'undefined' && typeof Event.onReady == 'function') 79 | return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter)); 80 | 81 | var old = window.onload; 82 | 83 | if (typeof window.onload != 'function') { 84 | window.onload = function() { CodeHighlighter.init() }; 85 | } else { 86 | window.onload = function() { 87 | old(); 88 | CodeHighlighter.init(); 89 | } 90 | } 91 | } 92 | 93 | // only set the event when the first style is added 94 | if (this.styleSets.length==1) setEvent(); 95 | } 96 | 97 | CodeHighlighter.init = function() { 98 | if (!document.getElementsByTagName) return; 99 | if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function 100 | // throw out older browsers 101 | 102 | var codeEls = document.getElementsByTagName("CODE"); 103 | // collect array of all pre elements 104 | codeEls.filter = function(f) { 105 | var a = new Array; 106 | for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i]; 107 | return a; 108 | } 109 | 110 | var rules = new Array; 111 | rules.toString = function() { 112 | // joins regexes into one big parallel regex 113 | var exps = new Array; 114 | for (var i = 0; i < this.length; i++) exps.push(this[i].exp); 115 | return exps.join("|"); 116 | } 117 | 118 | function addRule(className, rule) { 119 | // add a replace rule 120 | var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp; 121 | // converts regex rules to strings and chops of the slashes 122 | rules.push({ 123 | className : className, 124 | exp : "(" + exp + ")", 125 | length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule 126 | replacement : rule.replacement || null 127 | }); 128 | } 129 | 130 | function parse(text, ignoreCase) { 131 | // main text parsing and replacement 132 | return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() { 133 | var i = 0, j = 1, rule; 134 | while (rule = rules[i++]) { 135 | if (arguments[j]) { 136 | // if no custom replacement defined do the simple replacement 137 | if (!rule.replacement) return "" + arguments[0] + ""; 138 | else { 139 | // replace $0 with the className then do normal replaces 140 | var str = rule.replacement.replace("$0", rule.className); 141 | for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]); 142 | return str; 143 | } 144 | } else j+= rule.length; 145 | } 146 | }); 147 | } 148 | 149 | function highlightCode(styleSet) { 150 | // clear rules array 151 | var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)"); 152 | rules.length = 0; 153 | 154 | // get stylable elements by filtering out all code elements without the correct className 155 | var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.parentNode.className) }); 156 | 157 | // add style rules to parser 158 | for (var className in styleSet.rules) addRule(className, styleSet.rules[className]); 159 | 160 | 161 | // replace for all elements 162 | for (var i = 0; i < stylableEls.length; i++) { 163 | // EVIL hack to fix IE whitespace badness if it's inside a
164 | 			if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
165 | 				stylableEls[i] = stylableEls[i].parentNode;
166 | 				
167 | 				parsed = stylableEls[i].innerHTML.replace(/(]*>)([^<]*)<\/code>/i, function() {
168 | 					return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + ""
169 | 				});
170 | 				parsed = parsed.replace(/\n( *)/g, function() { 
171 | 					var spaces = "";
172 | 					for (var i = 0; i < arguments[1].length; i++) spaces+= " ";
173 | 					return "\n" + spaces;  
174 | 				});
175 | 				parsed = parsed.replace(/\t/g, "    ");
176 | 				parsed = parsed.replace(/\n(<\/\w+>)?/g, "
$1").replace(/
[\n\r\s]*
/g, "


"); 177 | 178 | } else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase); 179 | 180 | stylableEls[i].innerHTML = parsed; 181 | } 182 | } 183 | 184 | // run highlighter on all stylesets 185 | for (var i=0; i < this.styleSets.length; i++) { 186 | highlightCode(this.styleSets[i]); 187 | } 188 | } -------------------------------------------------------------------------------- /app/controllers/manual_controller.rb: -------------------------------------------------------------------------------- 1 | class ManualController < ApplicationController 2 | 3 | caches_page :manual_section, :manual_subsection 4 | def self.create_ordered_hash(llist) 5 | ActiveSupport::OrderedHash[llist] 6 | end 7 | 8 | DOC_GITHUB = "https://github.com/Hobo/hobodoc/edit/master/doc" 9 | HOBO_GITHUB = "https://github.com/Hobo/hobodoc/edit/master/hobo" 10 | HOBOFIELDS_GITHUB = "https://github.com/Hobo/hobodoc/edit/master/hobo_fields" 11 | HOBOSUPPORT_GITHUB ="https://github.com/Hobo/hobodoc/edit/master/hobo_support" 12 | DOC_ROOT = `bundle show doc`.strip 13 | 14 | TITLES = self.create_ordered_hash( 15 | [# ['to-do', "To Do List"], 16 | ["toc", ["Table of Contents", "manual/toc.markdown", DOC_ROOT, DOC_GITHUB]], 17 | ["download", ["Download and Install", "manual/download.markdown", DOC_ROOT, DOC_GITHUB]], 18 | ["changes13", ["Changes in 1.3", "CHANGES-1.3.txt", Hobo.root, HOBO_GITHUB]], 19 | ["changes20", ["Changes in 2.0", "CHANGES-2.0.markdown", Hobo.root, HOBO_GITHUB]], 20 | ["faq", ["FAQ and Misunderstandings", "manual/FAQ.markdown", DOC_ROOT, DOC_GITHUB]], 21 | ["hobo_support", ["Hobo Support", "test/hobosupport.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 22 | ["hobo_fields", ["Hobo Fields", "test/doc-only.rdoctest", HoboFields.root, HOBOFIELDS_GITHUB]], 23 | ["scopes", ["Automatic Named Scopes", "test/doctest/hobo/scopes.rdoctest", Hobo.root, HOBO_GITHUB]], 24 | ["permissions", ["The Permission System", "manual/permissions.markdown", DOC_ROOT, DOC_GITHUB]], 25 | ["multi_model_forms", ["Accessible Associations", "test/doctest/hobo/multi_model_forms.rdoctest", Hobo.root, HOBO_GITHUB]], 26 | ["users_and_authentication", ["Users and Authentication", "manual/users_and_authentication.markdown", DOC_ROOT, DOC_GITHUB]], 27 | ["model", ["Miscellaneous Model Extensions", "test/doctest/hobo/model.rdoctest", Hobo.root, HOBO_GITHUB]], 28 | ["controllers", ["Controllers and Routing", "manual/controllers.markdown", DOC_ROOT, DOC_GITHUB]], 29 | ["controller", ["Miscellaneous Controller Extensions", "test/doctest/hobo/controller.rdoctest", Hobo.root, HOBO_GITHUB]], 30 | ["dryml-guide", ["The DRYML Guide", "manual/dryml-guide.markdown", DOC_ROOT, DOC_GITHUB]], 31 | ["ajax", ["Ajax in Hobo", "manual/ajax.markdown", DOC_ROOT, DOC_GITHUB]], 32 | ["lifecycles", ["Lifecycles", "manual/lifecycles.markdown", DOC_ROOT, DOC_GITHUB]], 33 | ["viewhints", ["View Hints", "manual/viewhints.markdown", DOC_ROOT, DOC_GITHUB]], 34 | ["generators", ["Generators", "manual/generators.markdown", DOC_ROOT, DOC_GITHUB]], 35 | ["i18n", ["Internationalization", "manual/i18n.markdown", DOC_ROOT, DOC_GITHUB]], 36 | ["plugins", ["Creating Plugins", "manual/plugins.markdown", DOC_ROOT, DOC_GITHUB]], 37 | ["gems", ["The Hobo Gem Stack and UI Plugins", "manual/gems.markdown", DOC_ROOT, DOC_GITHUB]], 38 | ]) 39 | 40 | SUBTITLES = { 41 | "hobo_fields" => self.create_ordered_hash( 42 | [["rich_types", ["Rich Types", "test/rich_types.rdoctest", HoboFields.root, HOBOFIELDS_GITHUB]], 43 | ["api", ["API", "test/api.rdoctest", HoboFields.root, HOBOFIELDS_GITHUB]], 44 | ["migration_generator",["Migration Generator", "test/migration_generator.rdoctest", HoboFields.root, HOBOFIELDS_GITHUB]], 45 | #["generators", "Generators"], 46 | #["interactive_primary_key", "Interactive Primary Key"], 47 | #["migration_generator_comments", ["Migration Generator Comments", "test/migration_generator_comments.rdoctest", HoboFields.root, HOBOFIELDS_GITHUB]] 48 | ]), 49 | "hobo_support" => self.create_ordered_hash( 50 | [["chronic", ["Chronic", "test/hobosupport/chronic.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 51 | ["enumerable", ["Enumerable", "test/hobosupport/enumerable.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 52 | ["hash", ["Hash", "test/hobosupport/hash.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 53 | ["implies", ["Implies", "test/hobosupport/implies.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 54 | ["metaid", ["Metaid", "test/hobosupport/metaid.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 55 | ["methodphitamine", ["Methodphitamine", "test/hobosupport/methodphitamine.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 56 | ["module", ["Module", "test/hobosupport/module.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 57 | ["xss", ["XSS", "test/hobosupport/xss.rdoctest", HoboSupport.root, HOBOSUPPORT_GITHUB]], 58 | ]), 59 | "generators" => self.create_ordered_hash( 60 | [["admin_subsite", ["admin_subsite", "manual/generators/admin_subsite.markdown", Rails.root, nil]], 61 | ["assets", ["assets", "manual/generators/assets.markdown", Rails.root, nil]], 62 | ["controller", ["controller", "manual/generators/controller.markdown", Rails.root, nil]], 63 | ["front_controller", ["front_controller", "manual/generators/front_controller.markdown", Rails.root, nil]], 64 | ["i18n", ["i18n", "manual/generators/i18n.markdown", Rails.root, nil]], 65 | ["install_plugin", ["install_plugin", "manual/generators/install_plugin.markdown", Rails.root, nil]], 66 | ["migration", ["migration", "manual/generators/migration.markdown", Rails.root, nil]], 67 | ["model", ["model", "manual/generators/model.markdown", Rails.root, nil]], 68 | ["resource", ["resource", "manual/generators/resource.markdown", Rails.root, nil]], 69 | ["routes", ["routes", "manual/generators/routes.markdown", Rails.root, nil]], 70 | ["setup_wizard", ["setup_wizard", "manual/generators/setup_wizard.markdown", Rails.root, nil]], 71 | ["subsite", ["subsite", "manual/generators/subsite.markdown", Rails.root, nil]], 72 | ["subsite_taglib", ["subsite_taglib", "manual/generators/subsite_taglib.markdown", Rails.root, nil]], 73 | ["test_framework", ["test_framework", "manual/generators/test_framework.markdown", Rails.root, nil]], 74 | ["user_controller", ["user_controller", "manual/generators/user_controller.markdown", Rails.root, nil]], 75 | ["user_mailer", ["user_mailer", "manual/generators/user_mailer.markdown", Rails.root, nil]], 76 | ["user_model", ["user_model", "manual/generators/user_model.markdown", Rails.root, nil]], 77 | ["user_resource", ["user_resource", "manual/generators/user_resource.markdown", Rails.root, nil]]]) 78 | 79 | } 80 | 81 | def manual_section 82 | section = params[:section].gsub(/[^a-z0-9_\-]/, '') 83 | if TITLES[section].nil? 84 | redirect_to :action => :index 85 | return 86 | end 87 | filename = "#{TITLES[section][2]}/#{TITLES[section][1]}" 88 | @title = TITLES[section][0] 89 | @subtitles = SUBTITLES[section].nil? ? nil : ActiveSupport::OrderedHash[*SUBTITLES[section].map {|k,v| [k, v[0]]}.flatten] 90 | @content = HoboFields::Types::MarkdownString.new(File.read(filename)) 91 | @last_update = last_update filename 92 | @edit_link = "#{TITLES[section][3]}/#{TITLES[section][1]}" 93 | end 94 | 95 | def manual_subsection 96 | section = params[:section].gsub(/[^a-z0-9_\-]/, '') 97 | subsection = params[:subsection].gsub(/[^a-z0-9_\-]/, '') 98 | if SUBTITLES[section].nil? || SUBTITLES[section][subsection].nil? 99 | redirect_to :action => :index 100 | return 101 | end 102 | filename = "#{SUBTITLES[section][subsection][2]}/#{SUBTITLES[section][subsection][1]}" 103 | @title = TITLES[section][0] 104 | @subtitles = ActiveSupport::OrderedHash[*SUBTITLES[section].map {|k,v| [k, v[0]]}.flatten] 105 | @current_subtitle = SUBTITLES[section][subsection][0] 106 | @content = HoboFields::Types::MarkdownString.new(File.read(filename)) 107 | @last_update = last_update filename 108 | @edit_link = "#{SUBTITLES[section][subsection][3]}/#{SUBTITLES[section][subsection][1]}" if SUBTITLES[section][subsection][3] 109 | render :manual_subsection 110 | end 111 | 112 | def index 113 | redirect_to :action => "manual_section", :section => "toc" 114 | end 115 | 116 | def self.titles 117 | ActiveSupport::OrderedHash[*TITLES.map {|k,v| [k, v[0]]}.flatten] 118 | end 119 | 120 | end 121 | 122 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GIT 2 | remote: git://github.com/Hobo/hobo.git 3 | revision: 1f253d667850a7063c146fb8e704e4706a10eac5 4 | specs: 5 | doc (0.0.1) 6 | dryml (2.0.0.pre7) 7 | actionpack (~> 3.2.0) 8 | hobo_support (= 2.0.0.pre7) 9 | hobo (2.0.0.pre7) 10 | dryml (= 2.0.0.pre7) 11 | hobo_fields (= 2.0.0.pre7) 12 | hobo_support (= 2.0.0.pre7) 13 | will_paginate (~> 3.0.0) 14 | hobo_clean (2.0.0.pre7) 15 | hobo (= 2.0.0.pre7) 16 | hobo_jquery (= 2.0.0.pre7) 17 | hobo_clean_admin (2.0.0.pre7) 18 | hobo_clean (= 2.0.0.pre7) 19 | hobo_clean_sidemenu (2.0.0.pre7) 20 | hobo_clean (= 2.0.0.pre7) 21 | hobo_fields (2.0.0.pre7) 22 | hobo_support (= 2.0.0.pre7) 23 | hobo_jquery (2.0.0.pre7) 24 | hobo_rapid (= 2.0.0.pre7) 25 | jquery-rails (~> 2.0) 26 | hobo_jquery_ui (2.0.0.pre7) 27 | hobo (= 2.0.0.pre7) 28 | hobo_jquery (= 2.0.0.pre7) 29 | jquery-ui-themes (~> 0.0.4) 30 | hobo_rapid (2.0.0.pre7) 31 | hobo (= 2.0.0.pre7) 32 | hobo_support (2.0.0.pre7) 33 | rails (~> 3.2.0) 34 | 35 | GIT 36 | remote: git://github.com/Hobo/hobo_bootstrap.git 37 | revision: 854c5ae38bd31a437ed9d9d39c3691b46aa77e48 38 | specs: 39 | hobo_bootstrap (2.0.0.pre7) 40 | bootstrap-sass (~> 2.1) 41 | hobo (~> 2.0.0.pre6) 42 | hobo_jquery (~> 2.0.0.pre6) 43 | will_paginate-bootstrap (~> 0.2.1) 44 | 45 | GIT 46 | remote: git://github.com/Hobo/hobo_bootstrap_ui.git 47 | revision: e73a58727b186f0bd674e1ff84470716862ad70c 48 | specs: 49 | hobo_bootstrap_ui (2.0.0.pre7) 50 | bootstrap-datepicker-rails 51 | hobo_bootstrap (~> 2.0.0.pre1) 52 | 53 | GIT 54 | remote: git://github.com/Hobo/hobo_data_tables.git 55 | revision: 89a5a882b938c8cb775eb50e79ea6c3ab3d1dbaa 56 | specs: 57 | hobo_data_tables (0.0.1) 58 | hobo (> 1.4.0.pre5) 59 | jquery-datatables-rails 60 | 61 | GIT 62 | remote: git://github.com/Hobo/hobo_mapstraction.git 63 | revision: 3df6c1c70ab593db0d04f1233bb3b1199bd60b68 64 | specs: 65 | hobo_mapstraction (0.0.1) 66 | hobo (> 1.4.0.pre6) 67 | 68 | GIT 69 | remote: git://github.com/Hobo/hobo_omniauth.git 70 | revision: cb9d74aaa98e20dfaf08dee6dfd8963a9468e244 71 | specs: 72 | hobo_omniauth (0.0.1) 73 | hobo (~> 2.0.0.pre7) 74 | omniauth (~> 1.1) 75 | 76 | GIT 77 | remote: git://github.com/Hobo/hobo_paperclip.git 78 | revision: 47e37cdb9e55547da3a3fd8c75ba949d846fb215 79 | specs: 80 | hobo_paperclip (0.0.4) 81 | hobo 82 | paperclip 83 | 84 | GIT 85 | remote: git://github.com/Hobo/hobo_simple_color.git 86 | revision: 35dea062d760c39dbcff521f1377afbbed2f10b1 87 | specs: 88 | hobo_simple_color (0.0.2) 89 | hobo (> 1.4.0.pre4) 90 | 91 | GIT 92 | remote: git://github.com/Hobo/hobo_tokeninput.git 93 | revision: 271317004e0a3c6fd6083405b30193e3fbbae0ba 94 | specs: 95 | hobo_tokeninput (0.0.1) 96 | hobo (> 1.4.0.pre5) 97 | 98 | GIT 99 | remote: git://github.com/Hobo/hobo_tree_table.git 100 | revision: f3533062ae8f8051daeb82292d31735cdee7b697 101 | specs: 102 | hobo_tree_table (0.0.1) 103 | hobo (> 1.4.0.pre1) 104 | 105 | GIT 106 | remote: git://github.com/Hobo/select_one_or_new_dialog.git 107 | revision: 238312c2d032e40c899215835c220fc338c0f472 108 | specs: 109 | select_one_or_new_dialog (0.0.1) 110 | hobo (> 1.4.0.pre1) 111 | hobo_jquery_ui (> 1.4.0.pre1) 112 | 113 | GIT 114 | remote: git://github.com/Hobo/will_paginate.git 115 | revision: cc7ef01551b94fe4f607e38929037234dc70bb62 116 | specs: 117 | will_paginate (3.0.4.hobo) 118 | 119 | GIT 120 | remote: git://github.com/bryanlarsen/vlad-git.git 121 | revision: 0fa91ca93089003779aa564b4cdef238f08385cf 122 | specs: 123 | vlad-git (2.2.0) 124 | vlad (>= 2.1.0) 125 | 126 | GEM 127 | remote: http://rubygems.org/ 128 | specs: 129 | actionmailer (3.2.8) 130 | actionpack (= 3.2.8) 131 | mail (~> 2.4.4) 132 | actionpack (3.2.8) 133 | activemodel (= 3.2.8) 134 | activesupport (= 3.2.8) 135 | builder (~> 3.0.0) 136 | erubis (~> 2.7.0) 137 | journey (~> 1.0.4) 138 | rack (~> 1.4.0) 139 | rack-cache (~> 1.2) 140 | rack-test (~> 0.6.1) 141 | sprockets (~> 2.1.3) 142 | activemodel (3.2.8) 143 | activesupport (= 3.2.8) 144 | builder (~> 3.0.0) 145 | activerecord (3.2.8) 146 | activemodel (= 3.2.8) 147 | activesupport (= 3.2.8) 148 | arel (~> 3.0.2) 149 | tzinfo (~> 0.3.29) 150 | activeresource (3.2.8) 151 | activemodel (= 3.2.8) 152 | activesupport (= 3.2.8) 153 | activesupport (3.2.8) 154 | i18n (~> 0.6) 155 | multi_json (~> 1.0) 156 | arel (3.0.2) 157 | awesome_print (1.1.0) 158 | bootstrap-datepicker-rails (0.6.32) 159 | railties (>= 3.0) 160 | bootstrap-sass (2.2.1.1) 161 | sass (~> 3.2) 162 | builder (3.0.4) 163 | cocaine (0.4.2) 164 | coffee-rails (3.2.2) 165 | coffee-script (>= 2.2.0) 166 | railties (~> 3.2.0) 167 | coffee-script (2.2.0) 168 | coffee-script-source 169 | execjs 170 | coffee-script-source (1.4.0) 171 | erubis (2.7.0) 172 | execjs (1.4.0) 173 | multi_json (~> 1.0) 174 | hashie (1.2.0) 175 | hike (1.2.1) 176 | httparty (0.9.0) 177 | multi_json (~> 1.0) 178 | multi_xml 179 | i18n (0.6.1) 180 | journey (1.0.4) 181 | jquery-datatables-rails (1.11.2) 182 | jquery-rails 183 | jquery-rails (2.1.4) 184 | railties (>= 3.0, < 5.0) 185 | thor (>= 0.14, < 2.0) 186 | jquery-ui-themes (0.0.8) 187 | httparty 188 | json (1.7.5) 189 | libv8 (3.3.10.4) 190 | mail (2.4.4) 191 | i18n (>= 0.4.0) 192 | mime-types (~> 1.16) 193 | treetop (~> 1.4.8) 194 | maruku (0.6.1) 195 | syntax (>= 1.0.0) 196 | mime-types (1.19) 197 | multi_json (1.5.0) 198 | multi_xml (0.5.1) 199 | mysql (2.8.1) 200 | omniauth (1.1.1) 201 | hashie (~> 1.2) 202 | rack 203 | open4 (1.3.0) 204 | paperclip (2.8.0) 205 | activerecord (>= 2.3.0) 206 | activesupport (>= 2.3.2) 207 | cocaine (>= 0.0.2) 208 | mime-types 209 | polyglot (0.3.3) 210 | quiet_assets (1.0.1) 211 | railties (~> 3.1) 212 | rack (1.4.1) 213 | rack-cache (1.2) 214 | rack (>= 0.4) 215 | rack-ssl (1.3.2) 216 | rack 217 | rack-test (0.6.2) 218 | rack (>= 1.0) 219 | rails (3.2.8) 220 | actionmailer (= 3.2.8) 221 | actionpack (= 3.2.8) 222 | activerecord (= 3.2.8) 223 | activeresource (= 3.2.8) 224 | activesupport (= 3.2.8) 225 | bundler (~> 1.0) 226 | railties (= 3.2.8) 227 | railties (3.2.8) 228 | actionpack (= 3.2.8) 229 | activesupport (= 3.2.8) 230 | rack-ssl (~> 1.3.2) 231 | rake (>= 0.8.7) 232 | rdoc (~> 3.4) 233 | thor (>= 0.14.6, < 2.0) 234 | rake (10.0.3) 235 | rake-remote_task (2.1.0) 236 | open4 (~> 1.0) 237 | rake (>= 0.8, < 11.0) 238 | rdoc (3.12) 239 | json (~> 1.4) 240 | recaptcha (0.3.4) 241 | sass (3.2.3) 242 | sass-rails (3.2.5) 243 | railties (~> 3.2.0) 244 | sass (>= 3.1.10) 245 | tilt (~> 1.3) 246 | sprockets (2.1.3) 247 | hike (~> 1.2) 248 | rack (~> 1.0) 249 | tilt (~> 1.1, != 1.3.0) 250 | syntax (1.0.0) 251 | therubyracer (0.10.2) 252 | libv8 (~> 3.3.10) 253 | thor (0.16.0) 254 | tilt (1.3.3) 255 | treetop (1.4.12) 256 | polyglot 257 | polyglot (>= 0.3.1) 258 | tzinfo (0.3.35) 259 | uglifier (1.3.0) 260 | execjs (>= 0.3.0) 261 | multi_json (~> 1.0, >= 1.0.2) 262 | vlad (2.3.1) 263 | rake (>= 0.8, < 11.0) 264 | rake-remote_task (~> 2.1) 265 | will_paginate-bootstrap (0.2.1) 266 | will_paginate (>= 3.0.3) 267 | yard (0.8.3) 268 | 269 | PLATFORMS 270 | ruby 271 | 272 | DEPENDENCIES 273 | awesome_print 274 | cocaine 275 | coffee-rails (~> 3.2.1) 276 | doc! 277 | dryml! 278 | execjs 279 | hobo! 280 | hobo_bootstrap! 281 | hobo_bootstrap_ui! 282 | hobo_clean! 283 | hobo_clean_admin! 284 | hobo_clean_sidemenu! 285 | hobo_data_tables! 286 | hobo_fields! 287 | hobo_jquery! 288 | hobo_jquery_ui! 289 | hobo_mapstraction! 290 | hobo_omniauth! 291 | hobo_paperclip! 292 | hobo_rapid! 293 | hobo_simple_color! 294 | hobo_support! 295 | hobo_tokeninput! 296 | hobo_tree_table! 297 | jquery-rails 298 | jquery-ui-themes 299 | maruku 300 | mysql 301 | paperclip (~> 2.7) 302 | quiet_assets 303 | rails (= 3.2.8) 304 | recaptcha 305 | sass-rails (~> 3.2.3) 306 | select_one_or_new_dialog! 307 | therubyracer (~> 0.10.2) 308 | uglifier (>= 1.0.3) 309 | vlad 310 | vlad-git! 311 | will_paginate! 312 | yard 313 | --------------------------------------------------------------------------------