Permalink
Browse files

move builder, parts, and jquery out, and exceptions and auth in

  • Loading branch information...
wycats committed Oct 8, 2008
1 parent 8316619 commit 13834e33bf264ba1c46f9f03e937f0fd4660878d
View
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2008 Daniel Neighman
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
4 README
@@ -0,0 +1,4 @@
+merb-parts
+==========
+
+A plugin for the Merb framework that provides ...
View
@@ -0,0 +1,77 @@
+require 'rubygems'
+require 'rake/gempackagetask'
+require "extlib"
+require 'merb-core/tasks/merb_rake_helper'
+require "spec/rake/spectask"
+
+##############################################################################
+# Package && release
+##############################################################################
+RUBY_FORGE_PROJECT = "merb"
+PROJECT_URL = "http://merbivore.com"
+PROJECT_SUMMARY = "Merb plugin that provides Part Controllers."
+PROJECT_DESCRIPTION = PROJECT_SUMMARY
+
+GEM_AUTHOR = "Daniel Neighman"
+GEM_EMAIL = "has.sox@gmail.com"
+
+GEM_NAME = "merb_parts"
+PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
+GEM_VERSION = (Merb::MORE_VERSION rescue "0.9.9") + PKG_BUILD
+
+RELEASE_NAME = "REL #{GEM_VERSION}"
+
+require "extlib/tasks/release"
+
+spec = Gem::Specification.new do |s|
+ s.rubyforge_project = RUBY_FORGE_PROJECT
+ s.name = GEM_NAME
+ s.version = GEM_VERSION
+ s.platform = Gem::Platform::RUBY
+ s.has_rdoc = true
+ s.extra_rdoc_files = ["README", "LICENSE", 'TODO']
+ s.summary = PROJECT_SUMMARY
+ s.description = PROJECT_DESCRIPTION
+ s.author = GEM_AUTHOR
+ s.email = GEM_EMAIL
+ s.homepage = PROJECT_URL
+ s.add_dependency('merb-core', '>= 0.9.9')
+ s.require_path = 'lib'
+ s.files = %w(LICENSE README Rakefile TODO) + Dir.glob("{lib,spec,merb_generators}/**/*")
+end
+
+Rake::GemPackageTask.new(spec) do |pkg|
+ pkg.gem_spec = spec
+end
+
+desc "Install the gem"
+task :install do
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
+end
+
+desc "Uninstall the gem"
+task :uninstall do
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
+end
+
+desc "Create a gemspec file"
+task :gemspec do
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
+ file.puts spec.to_ruby
+ end
+end
+
+desc "Run all examples (or a specific spec with TASK=xxxx)"
+Spec::Rake::SpecTask.new('spec') do |t|
+ t.spec_opts = ["-cfs"]
+ t.spec_files = begin
+ if ENV["TASK"]
+ ENV["TASK"].split(',').map { |task| "spec/**/#{task}_spec.rb" }
+ else
+ FileList['spec/**/*_spec.rb']
+ end
+ end
+end
+
+desc 'Default: run spec examples'
+task :default => 'spec'
View
5 TODO
@@ -0,0 +1,5 @@
+TODO:
+Fix LICENSE with your name
+Fix Rakefile with your name and contact info
+Add your code to lib/merb-parts.rb
+Add your Merb rake tasks to lib/merb-parts/merbtasks.rb
View
@@ -0,0 +1,4 @@
+require File.join(File.dirname(__FILE__), "merb-parts", "part_controller")
+require File.join(File.dirname(__FILE__), "merb-parts", "mixins", "parts_mixin")
+
+Merb::Controller.send(:include, Merb::PartsMixin)
@@ -0,0 +1,6 @@
+namespace :merb-parts do
+ desc "Do something for merb-parts"
+ task :default do
+ puts "merb-parts doesn't do anything"
+ end
+end
@@ -0,0 +1,42 @@
+module Merb
+ module PartsMixin
+
+ # Dispatches a PartController.
+ # ==== Parameters
+ # opts<Hash>:: A Hash of Options. (see below)
+ #
+ # ==== Options
+ # An option hash has two parts.
+ # 1. keys that are Merb::PartControllers with values that are action names (as symbols)
+ # 2. key value pairs that will become available in the PartController as params merged
+ # with the web controllers params
+ #
+ # ==== Example
+ # Calling a part controller
+ # {{{
+ # part TodoPart => :list
+ # }}}
+ #
+ # Calling a part with additional options
+ # {{{
+ # part TodoPart => :list, :limit => 20, :user => current_user
+ # }}}
+ #
+ # ==== Returns
+ # Returns the result of the PartControllers action, which is a string.
+ def part(opts = {})
+ # Extract any params out that may have been specified
+ klasses, opts = opts.partition do |k,v|
+ k.respond_to?(:ancestors) && k.ancestors.include?(Merb::PartController)
+ end
+
+ opts = opts.empty? ? {} : Hash[*(opts.first)]
+
+ res = klasses.inject([]) do |memo,(klass,action)|
+ memo << klass.new(self, opts)._dispatch(action)
+ end
+ res.size == 1 ? res[0] : res
+ end
+
+ end
+end
@@ -0,0 +1,53 @@
+# Includes files into the class to allow it to minimally delegates to a web controller
+module Merb
+ module Mixins
+ module WebController
+
+ def self.included(base)
+ [:content_type, :web_controller].each do |attr|
+ base.send(:attr_accessor, attr)
+ end
+ base.send(:include, InstanceMethods)
+ base.send(:extend, ClassMethods)
+ end
+
+ module InstanceMethods
+ def request
+ @web_controller.request
+ end
+
+ def cookies
+ @web_controller.cookies
+ end
+
+ def headers
+ @web_controller.headers
+ end
+
+ def session
+ @web_controller.session
+ end
+
+ def response
+ @web_controller.response
+ end
+
+ def route
+ request.route
+ end
+
+ def url(name, *args)
+ @web_controller.url(name, *args)
+ end
+
+ end
+
+ module ClassMethods
+
+ end
+
+
+
+ end # WebController
+ end # Mixins
+end # Merb
@@ -0,0 +1,114 @@
+require File.join(File.dirname(__FILE__), "mixins", "web_controller")
+module Merb
+
+ # A Merb::PartController is a light weight way to share logic and templates
+ # amongst controllers.
+ # Merb::PartControllers work just like Merb::controller.
+ # There is a filter stack, layouts (if needed) all the render functions,
+ # and url generation.
+ #
+ # Cookies, params, and even the request object are shared with the web controller
+ class PartController < AbstractController
+ include Merb::Mixins::WebController
+
+ attr_reader :params
+
+ cattr_accessor :_subclasses
+ self._subclasses = Set.new
+
+ # ==== Returns
+ # Array[Class]:: Classes that inherit from Merb::PartController.
+ def self.subclasses_list() _subclasses end
+
+ # ==== Parameters
+ # action<~to_s>:: The name of the action that will be rendered.
+ # type<~to_s>::
+ # The mime-type of the template that will be rendered. Defaults to html.
+ # controller<~to_s>::
+ # The name of the controller that will be rendered. Defaults to
+ # controller_name.
+ #
+ # ==== Returns
+ # String:: The template location, i.e. ":controller/:action.:type".
+ def _template_location(action, type = :html, controller = controller_name)
+ "#{controller}/#{action}.#{type}"
+ end
+
+ # The location to look for a template and mime-type. This is overridden
+ # from AbstractController, which defines a version of this that does not
+ # involve mime-types.
+ #
+ # ==== Parameters
+ # template<String>::
+ # The absolute path to a template - without mime and template extension.
+ # The mime-type extension is optional - it will be appended from the
+ # current content type if it hasn't been added already.
+ # type<~to_s>::
+ # The mime-type of the template that will be rendered. Defaults to nil.
+ #
+ # @public
+ def _absolute_template_location(template, type)
+ template.match(/\.#{type.to_s.escape_regexp}$/) ? template : "#{template}.#{type}"
+ end
+
+ # Sets the template root to the default parts view directory.
+ #
+ # ==== Parameters
+ # klass<Class>::
+ # The Merb::PartController inheriting from the base class.
+ def self.inherited(klass)
+ _subclasses << klass.to_s
+ super
+ klass._template_root = Merb.dir_for(:part) / "views" unless self._template_root
+ end
+
+ # ==== Parameters
+ # web_controller<Merb::Controller>:: The controller calling this part.
+ # opts<Hash>:: Additional options for this part.
+ def initialize(web_controller, opts = {})
+ @web_controller = web_controller
+ @params = @web_controller.params.dup
+ @params.merge!(opts) unless opts.empty?
+ super
+ @content_type = @web_controller.content_type
+ end
+
+ # ==== Parameters
+ # name<~to_sym, Hash>:: The name of the URL to generate.
+ # rparams<Hash>:: Parameters for the route generation.
+ #
+ # ==== Returns
+ # String:: The generated URL.
+ #
+ # ==== Alternatives
+ # If a hash is used as the first argument, a default route will be
+ # generated based on it and rparams.
+ # ====
+ # TODO: Update this documentation
+ def url(name, *args)
+ args << params
+ Merb::Router.url(name, *args)
+ end
+
+ alias_method :relative_url, :url
+
+ # ==== Parameters
+ # action<~to_s>:: An action to dispatch to. Defaults to :to_s.
+ #
+ # ==== Returns
+ # String:: The part body.
+ def _dispatch(action=:to_s)
+ action = action.to_s
+ self.action_name = action
+ super(action)
+ @body
+ end
+
+ # Send any methods that are missing back up to the web controller
+ # Patched to set partial locals on the web controller
+ def method_missing(sym, *args, &blk)
+ @web_controller.instance_variable_set(:@_merb_partial_locals, @_merb_partial_locals) if @_merb_partial_locals
+ @web_controller.send(sym, *args, &blk)
+ end
+ end
+end
@@ -0,0 +1,37 @@
+class Main < Merb::Controller
+ self._template_root = File.dirname(__FILE__) / ".." / "views"
+
+ def index
+ part TodoPart => :list
+ end
+
+ def index2
+ part TodoPart => :one
+ end
+
+ def index3
+ part(TodoPart => :one) + part(TodoPart => :list)
+ end
+
+ def index4
+ provides :xml, :js
+ part(TodoPart => :formatted_output)
+ end
+
+ def part_with_params
+ part(TodoPart => :part_with_params, :my_param => "my_value")
+ end
+
+ def part_with_arrays_in_params
+ part(TodoPart => :part_with_params, :my_param => ['my_first_value', 'my_second_value'])
+ end
+
+ def part_within_view
+ render
+ end
+
+ def parth_with_absolute_template
+ part(TodoPart => :parth_with_absolute_template)
+ end
+
+end
@@ -0,0 +1,4 @@
+require File.dirname(__FILE__) / 'todo_part'
+
+class DonePart < TodoPart
+end
Oops, something went wrong.

0 comments on commit 13834e3

Please sign in to comment.