git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@4452 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/1.1.0
@@ -22,7 +22,7 @@ class ApplicationController < ActionController::Base | |||
include Redmine::I18n | |||
layout 'base' | |||
exempt_from_layout 'builder' | |||
exempt_from_layout 'builder', 'apit' | |||
# Remove broken cookie after upgrade from 0.8.x (#4292) | |||
# See https://rails.lighthouseapp.com/projects/8994/tickets/3360 |
@@ -229,3 +229,5 @@ end | |||
Redmine::WikiFormatting.map do |format| | |||
format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper | |||
end | |||
ActionView::Template.register_template_handler :apit, Redmine::Views::ApiTemplateHandler |
@@ -0,0 +1,28 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
module Redmine | |||
module Views | |||
class ApiTemplateHandler < ActionView::TemplateHandler | |||
include ActionView::TemplateHandlers::Compilable | |||
def compile(template) | |||
"Redmine::Views::Builders.for(params[:format]) do |api|; #{template.source}; self.output_buffer = api.output; end" | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,35 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
module Redmine | |||
module Views | |||
module Builders | |||
def self.for(format, &block) | |||
builder = case format | |||
when 'xml', :xml; Builders::Xml.new | |||
when 'json', :json; Builders::Json.new | |||
else; raise "No builder for format #{format}" | |||
end | |||
if block | |||
block.call(builder) | |||
else | |||
builder | |||
end | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,30 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
require 'blankslate' | |||
module Redmine | |||
module Views | |||
module Builders | |||
class Json < Structure | |||
def output | |||
@struct.first.to_json | |||
end | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,68 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
require 'blankslate' | |||
module Redmine | |||
module Views | |||
module Builders | |||
class Structure < BlankSlate | |||
def initialize | |||
@struct = [{}] | |||
end | |||
def array(tag, &block) | |||
@struct << [] | |||
block.call(self) | |||
ret = @struct.pop | |||
@struct.last[tag] = ret | |||
end | |||
def method_missing(sym, *args, &block) | |||
if args.any? | |||
if args.first.is_a?(Hash) | |||
if @struct.last.is_a?(Array) | |||
@struct.last << args.first | |||
end | |||
else | |||
if @struct.last.is_a?(Array) | |||
@struct.last << (args.last || {}).merge(:value => args.first) | |||
else | |||
@struct.last[sym] = args.first | |||
end | |||
end | |||
end | |||
if block | |||
@struct << {} | |||
block.call(self) | |||
ret = @struct.pop | |||
if @struct.last.is_a?(Array) | |||
@struct.last << ret | |||
else | |||
@struct.last[sym] = ret | |||
end | |||
end | |||
end | |||
def output | |||
raise "Need to implement #{self.class.name}#output" | |||
end | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,45 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
module Redmine | |||
module Views | |||
module Builders | |||
class Xml < ::Builder::XmlMarkup | |||
def initialize | |||
super | |||
instruct! | |||
end | |||
def output | |||
target! | |||
end | |||
def method_missing(sym, *args, &block) | |||
if args.size == 1 && args.first.is_a?(Time) | |||
__send__ sym, args.first.xmlschema, &block | |||
else | |||
super | |||
end | |||
end | |||
def array(name, options={}, &block) | |||
__send__ name, options.merge(:type => 'array'), &block | |||
end | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,54 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
require File.dirname(__FILE__) + '/../../../../../test_helper' | |||
class Redmine::Views::Builders::JsonTest < HelperTestCase | |||
def test_hash | |||
assert_json_output({'person' => {'name' => 'Ryan', 'age' => 32}}) do |b| | |||
b.person do | |||
b.name 'Ryan' | |||
b.age 32 | |||
end | |||
end | |||
end | |||
def test_array | |||
assert_json_output({'books' => [{'title' => 'Book 1', 'author' => 'B. Smith'}, {'title' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b| | |||
b.array :books do |b| | |||
b.book :title => 'Book 1', :author => 'B. Smith' | |||
b.book :title => 'Book 2', :author => 'G. Cooper' | |||
end | |||
end | |||
end | |||
def test_array_with_content_tags | |||
assert_json_output({'books' => [{'value' => 'Book 1', 'author' => 'B. Smith'}, {'value' => 'Book 2', 'author' => 'G. Cooper'}]}) do |b| | |||
b.array :books do |b| | |||
b.book 'Book 1', :author => 'B. Smith' | |||
b.book 'Book 2', :author => 'G. Cooper' | |||
end | |||
end | |||
end | |||
def assert_json_output(expected, &block) | |||
builder = Redmine::Views::Builders::Json.new | |||
block.call(builder) | |||
assert_equal(expected, ActiveSupport::JSON.decode(builder.output)) | |||
end | |||
end |
@@ -0,0 +1,54 @@ | |||
# Redmine - project management software | |||
# Copyright (C) 2006-2010 Jean-Philippe Lang | |||
# | |||
# This program is free software; you can redistribute it and/or | |||
# modify it under the terms of the GNU General Public License | |||
# as published by the Free Software Foundation; either version 2 | |||
# of the License, or (at your option) any later version. | |||
# | |||
# This program is distributed in the hope that it will be useful, | |||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
# GNU General Public License for more details. | |||
# | |||
# You should have received a copy of the GNU General Public License | |||
# along with this program; if not, write to the Free Software | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
require File.dirname(__FILE__) + '/../../../../../test_helper' | |||
class Redmine::Views::Builders::XmlTest < HelperTestCase | |||
def test_hash | |||
assert_xml_output('<person><name>Ryan</name><age>32</age></person>') do |b| | |||
b.person do | |||
b.name 'Ryan' | |||
b.age 32 | |||
end | |||
end | |||
end | |||
def test_array | |||
assert_xml_output('<books type="array"><book author="B. Smith" title="Book 1"/><book author="G. Cooper" title="Book 2"/></books>') do |b| | |||
b.array :books do |b| | |||
b.book :title => 'Book 1', :author => 'B. Smith' | |||
b.book :title => 'Book 2', :author => 'G. Cooper' | |||
end | |||
end | |||
end | |||
def test_array_with_content_tags | |||
assert_xml_output('<books type="array"><book author="B. Smith">Book 1</book><book author="G. Cooper">Book 2</book></books>') do |b| | |||
b.array :books do |b| | |||
b.book 'Book 1', :author => 'B. Smith' | |||
b.book 'Book 2', :author => 'G. Cooper' | |||
end | |||
end | |||
end | |||
def assert_xml_output(expected, &block) | |||
builder = Redmine::Views::Builders::Xml.new | |||
block.call(builder) | |||
assert_equal('<?xml version="1.0" encoding="UTF-8"?>' + expected, builder.output) | |||
end | |||
end |