Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Json xml #96

Closed
wants to merge 39 commits into from

2 participants

@GerryG
Collaborator

The plan for this is to reduce it to the parts that must be in the core and more the rest to the appropriate external container (TBD, maybe a gem)

It is ATP now, and we can have the necessary debate about the right way to change routing.

Gerry Gleason added some commits
Gerry Gleason Revert the xml/json removal commit on json_xml branch 16c729a
Gerry Gleason Merge branch 'obj_render' into json_xml 22d53a5
Gerry Gleason Merge remote-tracking branch 'origin/obj_render' into json_xml 24f0289
Gerry Gleason merge forward (manually) the cleanup of the renderer calling code aa3e36e
Gerry Gleason Merge some cleanups forward (adding back parts) de767b8
Gerry Gleason Merge branch 'obj_render' into json_xml 9a15bac
Gerry Gleason revert removal (probably should just edit the commit to add it) cc08cfb
Gerry Gleason Merge branch 'obj_render' into json_xml 9a00cb8
Gerry Gleason Merge 1.10.3 forward 0c86ad2
Gerry Gleason Merge :session codename disable 8900c74
Gerry Gleason merge ab74e10
Gerry Gleason Merge obj_content dcc7045
Gerry Gleason to_actions through obj_render to json_xml 3e4fe46
Gerry Gleason Merge branch 'obj_render' into json_xml 1e85b22
Gerry Gleason Merge branch 'obj_render' into json_xml 13234a1
Gerry Gleason Merge to_actions forward via obj_render to json_xml c79d7fa
Gerry Gleason Double included removed d1b8792
Gerry Gleason Merge branch 'obj_render' into json_xml 1ae9625
Gerry Gleason Merge branch 'obj_render' into json_xml 7dbf109
Gerry Gleason Merge branch 'obj_render' into json_xml 6933dcc
Gerry Gleason Remove cardtype.rb, was only needed for old migrations 85e85d8
Gerry Gleason Merge branch 'obj_render' into json_xml d401f69
Gerry Gleason Merge branch 'obj_render' into json_xml 30ecf0b
Gerry Gleason Merge remote branch 'origin/json_xml' into json_xml 22d0d15
Gerry Gleason Removing Renderer suffix from clasnames 49af216
Gerry Gleason merging and fixing Renderer suffix remove eb28c88
Gerry Gleason Merge remote branch 'e/develop' into json_xml 4eccf1a
Gerry Gleason fix test 25e6d92
Gerry Gleason Merge branch 'develop' into json_xml 16fd0cf
Gerry Gleason merge a45d10f
Gerry Gleason Merge branch 'develop' into json_xml ba8674a
Gerry Gleason Merge branch 'develop' into json_xml 0b9d64d
Gerry Gleason merge 197c529
Gerry Gleason Index action was failing, needed the preload like read to work right da16124
Gerry Gleason Merge branch 'develop' into json_xml d3a27df
@GerryG GerryG commented on the diff
app/controllers/application_controller.rb
((5 lines not shown))
renderer = Wagn::Renderer.new card, :format=>ext, :controller=>self
view_opts = ( params[:slot] || {} ).merge :view => ( view || params[:view] )
- rendered_text = renderer.render_show view_opts
- render :text=>rendered_text, :status=> renderer.error_status || status
+ rendered_obj = renderer.render_show view_opts
+ render obj_sym => rendered_obj, :status => renderer.error_status || status
@GerryG Collaborator
GerryG added a note

I think this change is common to action_events. I think it makes sense, but I know you had some questions before.

@ethn Collaborator
ethn added a note

This means that when the JSON Renderer does its rendering, you get a ruby object? That won't fly. How would you ever attach JSON to an email? Any time we're dependent upon the controller to do work that we might want in controller-less contexts, it's a no-go imo.

@ethn Collaborator
ethn added a note

I also realized another case that this complicates. Suppose I have a card on wagn with json or xml in it. So it's already text. How would that work if the renderer isn't allowed to discriminate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@GerryG GerryG commented on the diff
config/routes.rb
((5 lines not shown))
match 'recent(.:format)' => 'card#read', :id => '*recent', :view => 'content'
+
+ resources :card, :path => '/', :except => :show
@GerryG Collaborator
GerryG added a note

I think your comment before was that we really only use a few of the routes created with this. With my last fixup, the card_controller handles the #index action too, so the match '/' isn't needed. YMMV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@GerryG GerryG commented on the diff
lib/wagn/renderer.rb
@@ -460,7 +459,7 @@ def add_name_context name=nil
end
- class Renderer::JsonRenderer < Renderer
+ class Renderer::Json < Renderer
@GerryG Collaborator
GerryG added a note

This can be promoted either way, we are eliminating the Renderer on Json and Html as a general pattern.

@ethn Collaborator
ethn added a note

I don't think we can do this until we stop autoloading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@GerryG GerryG commented on the diff
lib/wagn/set/all/kml.rb
@@ -9,7 +9,6 @@ module Set::All::Kml
render( args[:view] || :search)
end
- # FIXME: integrate this with common XML features when it is added
@GerryG Collaborator
GerryG added a note

Ok, I guess we should complet this on this branch now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ethn
Collaborator

ticket?

@GerryG
Collaborator
@ethn
Collaborator

this could be trimmed down a lot. I don't think there's any way we want to maintain multiple copies of #wrap, #build_link, #get_layout_content, etc

@ethn
Collaborator

I'm going to close this PR, because I don't think there's much we're going to retain here. All the stuff in controllers is a major architectural violation. Almost all the stuff in renderers / specs is indiscriminate cut-and-paste. We should certainly keep it around, but this feels like a step backwards to me.

@ethn ethn closed this
@ethn
Collaborator

hmm, not all the stuff in controllers is violating (at least not the xml processing stuff). will continue to study...

@GerryG
Collaborator

Yeah, it is in the wrong place, but from an agile standpoint that should be ok until we have more functionality to merge and we can refactor so that this has a better home. As we have discussed, we need to spec all of it better and then implement to that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 13, 2013
  1. Revert the xml/json removal commit on json_xml branch

    Gerry Gleason authored
  2. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
  3. Merge some cleanups forward (adding back parts)

    Gerry Gleason authored
  4. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
  5. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
Commits on Jan 15, 2013
  1. Merge 1.10.3 forward

    Gerry Gleason authored
  2. Merge :session codename disable

    Gerry Gleason authored
  3. merge

    Gerry Gleason authored
Commits on Jan 17, 2013
  1. Merge obj_content

    Gerry Gleason authored
  2. to_actions through obj_render to json_xml

    Gerry Gleason authored
  3. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
Commits on Jan 18, 2013
  1. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
  2. Merge to_actions forward via obj_render to json_xml

    Gerry Gleason authored
  3. Double included removed

    Gerry Gleason authored
Commits on Jan 19, 2013
  1. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
  2. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
Commits on Jan 20, 2013
  1. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
  2. Remove cardtype.rb, was only needed for old migrations

    Gerry Gleason authored
  3. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
Commits on Jan 22, 2013
  1. Merge branch 'obj_render' into json_xml

    Gerry Gleason authored
Commits on Jan 23, 2013
  1. Merge remote branch 'origin/json_xml' into json_xml

    Gerry Gleason authored
Commits on Feb 17, 2013
  1. Removing Renderer suffix from clasnames

    Gerry Gleason authored
  2. merging and fixing Renderer suffix remove

    Gerry Gleason authored
Commits on Feb 19, 2013
  1. Merge remote branch 'e/develop' into json_xml

    Gerry Gleason authored
  2. fix test

    Gerry Gleason authored
Commits on Mar 2, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 5, 2013
  1. merge

    Gerry Gleason authored
  2. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 6, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 9, 2013
  1. merge

    Gerry Gleason authored
Commits on Mar 11, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 15, 2013
  1. Merge tagged release

    Gerry Gleason authored
Commits on Mar 24, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 25, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
Commits on Mar 27, 2013
  1. Merge branch 'develop' into json_xml

    Gerry Gleason authored
This page is out of date. Refresh to see the latest.
View
5 app/controllers/application_controller.rb
@@ -97,11 +97,12 @@ def show view = nil, status = 200
case
when known # renderers can handle it
+ obj_sym = [:json, :xml].member?( ext = ext.to_sym ) ? ext : :text
renderer = Wagn::Renderer.new card, :format=>ext, :controller=>self
view_opts = ( params[:slot] || {} ).merge :view => ( view || params[:view] )
- rendered_text = renderer.render_show view_opts
- render :text=>rendered_text, :status=> renderer.error_status || status
+ rendered_obj = renderer.render_show view_opts
+ render obj_sym => rendered_obj, :status => renderer.error_status || status
@GerryG Collaborator
GerryG added a note

I think this change is common to action_events. I think it makes sense, but I know you had some questions before.

@ethn Collaborator
ethn added a note

This means that when the JSON Renderer does its rendering, you get a ruby object? That won't fly. How would you ever attach JSON to an email? Any time we're dependent upon the controller to do work that we might want in controller-less contexts, it's a no-go imo.

@ethn Collaborator
ethn added a note

I also realized another case that this complicates. Suppose I have a card on wagn with json or xml in it. So it's already text. How would that work if the renderer isn't allowed to discriminate?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
when show_file # send_file can handle it
else # dunno how to handle it
View
107 app/controllers/card_controller.rb
@@ -1,4 +1,5 @@
# -*- encoding : utf-8 -*-
+require 'xmlscan/processor'
require_dependency 'cardlib'
@@ -8,10 +9,90 @@ class CardController < ApplicationController
before_filter :read_file_preload, :only=> [ :read_file ]
- before_filter :load_id, :only => [ :read ]
+ before_filter :load_id, :only => [ :read, :index ]
before_filter :load_card
before_filter :refresh_card, :only=> [ :create, :update, :delete, :comment, :rollback ]
+ # rest XML put/post
+ def read_xml(io)
+ pairs = XMLScan::XMLProcessor.process(io, {:key=>:name, :element=>:card,
+ :substitute=>":include|{{:name}}", :extras=>[:type]})
+ return if pairs.empty?
+
+ main = pairs.shift
+ #warn "main#{main.inspect}, #{pairs.empty?}"
+ main, content, type = main[0], main[1][0]*'', main[1][2]
+
+ data = { :name=>main }
+ data[:cards] = pairs.inject({}) { |hash,p| k,v = p
+ h = {:content => v[0]*''}
+ h[:type] = v[2] if v[2]
+ hash[k.to_cardname.to_absolute(v[1])] = h
+ hash } unless pairs.empty?
+ data[:content] = content unless content.blank?
+ data[:type] = type if type
+ data
+ end
+
+ def dump_pairs(pairs)
+ warn "Result
+#{ pairs.map do |p| n,o,c,t = p
+ "#{c&&c.size>0&&"#{c}::"||''}#{n}#{t&&"[#{t}]"}=>#{o*''}"
+ end * "\n"}
+Done"
+ end
+ # Need to split off envelope code somehome
+
+=begin FIXME move to events
+ def create
+ Rails.logger.warn "create card #{params.inspect}"
+ if request.parameters['format'] == 'xml'
+ Rails.logger.warn (Rails.logger.debug "POST(rest)[#{params.inspect}] #{request.format}")
+ #return render(:action=>"missing", :format=>:xml) unless params[:card]
+ if card_create = read_xml(request.body)
+ begin
+ @card = Card.new card_create
+ #warn "POST creates are #{card_create.inspect}"
+ rescue Exception => e
+ Rails.logger.warn "except #{e.inspect}, #{e.backtrace*"\n"}"
+ end
+ end
+
+ Rails.logger.warn "create card #{request.body.inspect}"
+ end
+
+=end
+
+ attr_reader :card
+ cattr_reader :subset_actions
+ @@subset_actions = {}
+
+ METHODS = {
+ 'POST' => :create, # C
+ 'GET' => :read, # R
+ 'PUT' => :update, # U
+ 'DELETE' => :delete, # D
+ 'INDEX' => :index
+ }
+
+ # this form of dispatching is not used yet, write specs first, then integrate into routing
+ def action
+ @action = METHODS[request.method]
+ Rails.logger.warn "action #{request.method}, #{@action} #{params.inspect}"
+ warn "action #{request.method}, #{@action} #{params.inspect}"
+ send "perform_#{@action}"
+ render_errors || success
+ end
+
+ def action_method event
+ return "_final_#{event}" unless card && subset_actions[event]
+ card.method_keys.each do |method_key|
+ meth = "_final_"+(method_key.blank? ? "#{event}" : "#{method_key}_#{event}")
+ #warn "looking up #{method_key}, M:#{meth} for #{card.name}"
+ return meth if respond_to?(meth.to_sym)
+ end
+ end
+
def create
if card.save
success
@@ -24,6 +105,30 @@ def read
save_location # should be an event!
show
end
+ alias index read
+
+=begin FIXME move to action events
+ Rails.logger.warn "update card #{params.inspect}"
+ if request.parameters['format'] == 'xml'
+ Rails.logger.warn (Rails.logger.debug "POST(rest)[#{params.inspect}] #{request.format}")
+ #return render(:action=>"missing", :format=>:xml) unless params[:card]
+ if main_card = read_xml(request.body)
+ begin
+ @card = Card.new card_create
+ #warn "POST creates are #{card_create.inspect}"
+ rescue Exception => e
+ Rails.logger.warn "except #{e.inspect}, #{e.backtrace*"\n"}"
+ end
+ end
+
+ Rails.logger.warn "create card #{request.body.inspect}"
+ end
+ @card = @card.refresh if @card.frozen? # put in model
+ case
+ when @card.new_card? ; create
+ when @card.update_attributes( params[:card] ) ; success
+ else render_errors
+=end
def update
if card.new_card?
View
5 config/routes.rb
@@ -12,8 +12,11 @@
match ':asset/:foo' => 'application#fast_404', :constraints =>
{ :asset=>/assets|images?|stylesheets?|javascripts?/, :foo => /.*/ }
- match '/' => 'card#read'
match 'recent(.:format)' => 'card#read', :id => '*recent', :view => 'content'
+
+ resources :card, :path => '/', :except => :show
@GerryG Collaborator
GerryG added a note

I think your comment before was that we really only use a few of the routes created with this. With my last fixup, the card_controller handles the #index action too, so the match '/' isn't needed. YMMV

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ get '/:id(.:format)' => 'card#read'
+
match '(/wagn)/:id(.:format)' => 'card#read'
match '/files/(*id)' => 'card#read_file'
View
4 lib/cardtype.rb
@@ -1,4 +0,0 @@
-class Cardtype # this is not needed, but sometimes migrations and regeneration
- # of fixtures would fail on Cardtype not being defined. This fixes that.
- # After 1.8.2 migrations this can be deleted for sure ...
-end
View
3  lib/wagn/renderer.rb
@@ -11,7 +11,6 @@ class Renderer
#DEFAULT_ITEM_VIEW = :link # should be set in card?
RENDERERS = { #should be defined in renderer
- :json => :JsonRenderer,
:email => :EmailHtml,
:txt => :Text
}
@@ -466,7 +465,7 @@ def add_name_context name=nil
end
- class Renderer::JsonRenderer < Renderer
+ class Renderer::Json < Renderer
@GerryG Collaborator
GerryG added a note

This can be promoted either way, we are eliminating the Renderer on Json and Html as a general pattern.

@ethn Collaborator
ethn added a note

I don't think we can do this until we stop autoloading.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
end
class Renderer::Text < Renderer
View
106 lib/wagn/renderer/json.rb
@@ -0,0 +1,106 @@
+module Wagn
+
+ LAYOUTS = { 'default' => {:status => "{{:status}}",:result => "{{_main}}"},
+ 'none' => "{{_main}}"
+ }
+
+ class Renderer::Json < Renderer
+
+ cattr_accessor :set_actions
+ attr_accessor :options_need_save, :js_queue_initialized,
+ :position, :start_time, :skip_autosave
+
+ # This creates a separate class hash in the subclass
+ class << self
+ def actions() @@set_actions||={} end
+ end
+
+ def set_action(key)
+ Renderer::Json.actions[key] or super
+ end
+
+ def initialize(card, opts=nil)
+ super
+ @context = "main_1" unless @context =~ /\_/
+ @position = @context.split('_').last
+ @state = :view
+ @renders = {}
+ @js_queue_initialized = {}
+
+ if card and card.collection? and item_param=params[:item]
+ @item_view = item_param if !item_param.blank?
+ end
+ end
+
+ def build_link href, text, known_card=nil
+ #Rails.logger.warn "bl #{href.inspect}, #{text.inspect}, #{known_card.inspect}"
+ klass = case href.to_s
+ when /^https?:/; 'external-link'
+ when /^mailto:/; 'email-link'
+ when /^\//
+ href = full_uri href.to_s
+ 'internal-link'
+ else
+ known_card = !!Card.fetch(href, :skip_modules=>true) if known_card.nil?
+ smartname = href.to_name
+ text = smartname.to_show(card.name) unless text
+ #href+= "?type=#{type.to_url_key}" if type && card && card.new_card? WANT THIS; NEED TEST
+ href = full_uri Wagn::Conf[:root_path] + '/' +
+ (known_card ? smartname.to_url_key : CGI.escape(smartname.escape))
+
+ return %{{"cardlink":{"class":"#{
+ known_card ? 'known-card' : 'wanted-card'
+ }", "url":"#{href}","text":"#{text}"}}}
+ end
+ { :link => { :class => "#{klass}", :url => "#{href}",:text => "#{text}"}} # return a Hash, not a string for json
+ end
+
+ def wrap(view=nil, args = {})
+
+ attributes = card.nil? ? {} : {
+ :name => card.cardname.tag_name.to_s,
+ :key => card.key,
+ :cardId => card.id,
+ :type => card.type_name,
+ }
+ [:style, :home_view, :item, :base].each { |key| a = args[key] and attributes[key] = a }
+
+ cont = yield # (Enumerable===(c=yield) ? c.to_a : c)
+ #Rails.logger.info "wrap json #{cont.class}, I#{cont.inspect}"
+ {card: { attr: attributes, content: cont }}
+ end
+
+ def get_layout_content(args)
+ Account.as_bot do
+ case
+ when (params[:layout] || args[:layout]) ; layout_from_name
+ when card ; layout_from_card
+ else ; LAYOUTS['default']
+ end
+ end
+ end
+
+ def layout_from_name
+ lname = (params[:layout] || args[:layout]).to_s
+ lcard = Card.fetch(lname, :skip_virtual=>true)
+ case
+ when lcard && lcard.ok?(:read) ; lcard.content
+ when hardcoded_layout = LAYOUTS[lname] ; hardcoded_layout
+ else ; %{{"error":"Unknown layout: #{lname}. Built-in Layouts: #{LAYOUTS.keys.join(', ')}}}
+
+ end
+ end
+
+ def layout_from_card
+ return unless rule_card = (card.rule_card(:layout) or Card.default_rule_card(:layout))
+ rule_card.include_set_modules
+ return unless rule_card.type_id == Card::PointerID and
+ layout_name=rule_card.item_names.first and
+ !layout_name.nil? and
+ lo_card = Card.fetch(layout_name, :skip_virtual => true) and
+ lo_card.ok?(:read)
+ lo_card.content
+ end
+
+ end
+end
View
112 lib/wagn/renderer/xml.rb
@@ -0,0 +1,112 @@
+module Wagn
+ class Renderer::Xml < Renderer
+
+ LAYOUTS = { 'default' => %{
+<carddoc>
+{{_main}}
+</carddoc>
+} }
+
+ cattr_accessor :set_actions
+ attr_accessor :options_need_save, :js_queue_initialized,
+ :position, :start_time, :skip_autosave
+
+ # This creates a separate class hash in the subclass
+ class << self
+ def actions() @@set_actions||={} end
+ end
+
+ def set_action(key)
+ Renderer::Xml.actions[key] or super
+ end
+
+ def initialize(card, opts=nil)
+ super
+ @context = "main_1" unless @context =~ /\_/
+ @position = @context.split('_').last
+ @state = :view
+ @renders = {}
+ @js_queue_initialized = {}
+
+ if card and card.collection? and item_param=params[:item]
+ @item_view = item_param if !item_param.blank?
+ end
+ end
+
+ def build_link href, text, known_card=nil
+ #Rails.logger.warn "bl #{href.inspect}, #{text.inspect}, #{known_card.inspect}"
+ klass = case href.to_s
+ when /^https?:/; 'external-link'
+ when /^mailto:/; 'email-link'
+ when /^\//
+ href = full_uri href.to_s
+ 'internal-link'
+ else
+ known_card = !!Card.fetch(href, :skip_modules=>true) if known_card.nil?
+ cardname = href.to_name
+ text ||= showname
+ #href+= "?type=#{type.url_key}" if type && card && card.new_card? WANT THIS; NEED TEST
+ href = full_uri Wagn::Conf[:root_path] + '/' +
+ (known_card ? cardname.url_key : CGI.escape(cardname.s))
+
+ return %{<cardlink class="#{
+ known_card ? 'known-card' : 'wanted-card'
+ }" card="#{href}">#{text}</cardlink>}
+ end
+ %{<link class="#{klass}" href="#{href}">#{text}</link>}
+ end
+
+ def wrap(view=nil, args = {})
+ css_class = case args[:action].to_s
+ when 'content' ; 'included'
+ when 'exception'; 'exception'
+ when 'closed' ; 'card-slot line'
+ else ; 'card-slot paragraph'
+ end
+ css_class << " " + card.safe_keys if card
+ css_class << " view-#{view}" if view
+
+ attributes = {
+ :name => card.cardname.tag,
+ :cardId => (card && card.id),
+ :type_id => card.type_id,
+ :class => css_class,
+ }
+ [:style, :home_view, :item, :base].each { |key| attributes[key] = args[key] }
+
+ content_tag(:card, attributes ) { yield }
+ end
+
+ def get_layout_content(args)
+ Account.as_bot do
+ case
+ when (params[:layout] || args[:layout]) ; layout_from_name
+ when card ; layout_from_card
+ else ; LAYOUTS['default']
+ end
+ end
+ end
+
+ def layout_from_name
+ lname = (params[:layout] || args[:layout]).to_s
+ lcard = Card.fetch(lname, :skip_virtual=>true)
+ case
+ when lcard && lcard.ok?(:read) ; lcard.content
+ when hardcoded_layout = LAYOUTS[lname] ; hardcoded_layout
+ else ; "<h1>Unknown layout: #{lname}</h1>Built-in Layouts: #{LAYOUTS.keys.join(', ')}"
+ end
+ end
+
+ def layout_from_card
+ return unless rule_card = (card.rule_card(:layout) or Card.default_rule_card(:layout))
+ rule_card.include_set_modules
+ return unless rule_card.type_id == Card::PointerID and
+ layout_name=rule_card.item_names.first and
+ !layout_name.nil? and
+ lo_card = Card.fetch(layout_name, :skip_virtual => true) and
+ lo_card.ok?(:read)
+ lo_card.content
+ end
+
+ end
+end
View
1  lib/wagn/set/all/kml.rb
@@ -9,7 +9,6 @@ module Set::All::Kml
render( args[:view] || :search)
end
- # FIXME: integrate this with common XML features when it is added
@GerryG Collaborator
GerryG added a note

Ok, I guess we should complet this on this branch now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
define_view :search do |args|
xml = Builder::XmlMarkup.new
xml.instruct! :xml, :version => "1.0"
View
1  lib/wagn/set/all/rss.rb
@@ -9,7 +9,6 @@ module Set::All::Rss
render_feed
end
- # FIXME: integrate this with common XML features when it is added
define_view :feed do |args|
xml = Builder::XmlMarkup.new
xml.instruct! :xml, :version => "1.0"
View
51 lib/wagn/set/all/xml.rb
@@ -0,0 +1,51 @@
+
+module Wagn
+ module Set::All::Xml
+ include Sets
+
+ format :xml
+
+ define_view(:layout) do |args|
+ if @main_content = args.delete( :main_content )
+ @card = Card.fetch '*placeholder',:new=>{}, :skip_defaults=>true
+ else
+ @main_card = card
+ end
+
+ layout_content = get_layout_content(args)
+
+ args[:action]="view"
+ args[:relative_content] = args[:params] = params
+
+ process_content(layout_content, args)
+ end
+
+ define_view(:content) do |args|
+ c = _render_core(args)
+ c = "<span class=\"faint\">--</span>" if c.size < 10 && strip_tags(c).blank?
+ wrap(:content, args) { wrap_content(:content) { c } }
+ end
+
+ define_view(:content) do |args|
+ @state = :view
+ self.wrap(:content, args) { _render_core(args) }
+ end
+
+ define_view(:open) do |args|
+ @state = :view
+ self.wrap(:open, args) { _render_core(args) }
+ end
+
+ define_view(:closed) do |args|
+ @state = :line
+ self.wrap(:closed, args) { _render_closed(args) }
+ end
+
+ [ :deny_view, :edit_auto, :too_slow, :too_deep, :open_missing, :closed_missing, :setting_missing, :missing ].each do |view|
+ define_view(view) do |args|
+ %{<no_card status="#{view.to_s.gsub('_',' ')}">#{card.name}</no_card>}
+ end
+ end
+
+ end
+end
View
444 spec/lib/wagn/renderer/xml_spec.rb
@@ -0,0 +1,444 @@
+require File.dirname(__FILE__) + '/../../../spec_helper'
+require File.dirname(__FILE__) + '/../../../packs/pack_spec_helper'
+
+describe Wagn::Renderer::Xml, "" do
+ before do
+ Wagn::Conf[:base_url] = nil
+ Account.current_id= Card['joe_user'].id
+ Wagn::Renderer::Xml.current_slot = nil
+ end
+
+#~~~~~~~~~~~~ special syntax ~~~~~~~~~~~#
+
+ context "special syntax handling should render" do
+ #before do
+ # Account.as_bot do
+ # end
+ #end
+
+ it "simple card links" do
+ xml_render_content("[[A]]").should=="<cardlink class=\"known-card\" card=\"/A\">A</cardlink>"
+ end
+
+ it "invisible comment inclusions as blank" do
+ xml_render_content("{{## now you see nothing}}").should==''
+ end
+
+ it "visible comment inclusions as html comments" do
+ xml_render_content("{{# now you see me}}").should == '<!-- # now you see me -->'
+ xml_render_content("{{# -->}}").should == '<!-- # --&gt; -->'
+ end
+
+ it "css in inclusion syntax in wrapper" do
+ c = Card.new :name => 'Afloatright', :content => "{{A|float:right}}"
+ data=Wagn::Renderer.new(c)._render( :core )
+ assert_view_select data, 'div[style="float:right;"]'
+ end
+
+ # I want this test to show the explicit escaped HTML, but be_html_with seems to escape it already :-/
+ it "HTML in inclusion systnax as escaped" do
+ c =Card.new :name => 'Afloat', :type => 'Html', :content => '{{A|float:<object class="subject">}}'
+ data=Wagn::Renderer::Xml.new(c)._render( :core )
+ #warn "data is #{data}"
+ assert_view_select data, %{card[style="float:&amp;lt;object class=&amp;quot;subject&amp;quot;&amp;gt;;"]}
+ end
+
+ context "CGI variables" do
+ it "substituted when present" do
+ c = Card.new :name => 'cardNaked', :content => "{{_card+B|naked}}"
+ result = Wagn::Renderer::Xml.new(c, :params=>{'_card' => "A"})._render_core
+ result.should == "AlphaBeta"
+ end
+ end
+
+ end
+
+#~~~~~~~~~~~~ Error handling ~~~~~~~~~~~~~~~~~~#
+
+ context "Error handling" do
+
+ it "prevents infinite loops" do
+ Card.create! :name => "n+a", :content=>"{{n+a|array}}"
+ c = Card.new :name => 'naArray', :content => "{{n+a|array}}"
+ Wagn::Renderer::Xml.new(c)._render( :core ).should =~ /too deep/
+ end
+
+ it "missing relative inclusion is relative" do
+ c = Card.new :name => 'bad_include', :content => "{{+bad name missing}}"
+ Wagn::Renderer::Xml.new(c)._render(:core).should match /^<no_card .*\"missing\".*bad_include\+bad name missing/
+ end
+
+ it "renders deny for unpermitted cards" do
+ pending "with html"
+ Account.as_bot do
+ Card.create(:name=>'Joe no see me', :type=>'Html', :content=>'secret')
+ Card.create(:name=>'Joe no see me+*self+*read', :type=>'Pointer', :content=>'[[Administrator]]')
+ end
+ Account.as :joe_user do
+ Wagn::Renderer::Xml.new(Card.fetch('Joe no see me')).render(:core).should be_html_with { no_card(:status=>"deny view") }
+ end
+ end
+ end
+
+#~~~~~~~~~~~~~ Standard views ~~~~~~~~~~~~~~~~#
+# (*all sets)
+
+
+ context "handles view" do
+
+ it("name" ) { render_card(:name).should == 'Tempo Rary' }
+ it("key" ) { render_card(:key).should == 'tempo_rary' }
+ it("linkname") { render_card(:linkname).should == 'Tempo_Rary' }
+ it("url" ) { render_card(:url).should == '/Tempo_Rary' }
+
+ it "should handle size argument in inclusion syntax" do
+ image_card = Card.create! :name => "TestImage", :type=>"Image", :content => %{TestImage.jpg\nimage/jpeg\n12345}
+ including_card = Card.new :name => 'Image1', :content => "{{TestImage | core; size:small }}"
+ rendered = Wagn::Renderer::Xml.new(including_card)._render :core
+ rendered.should == "/files/TestImage-small-#{image_card.current_revision_id}.jpg"
+ end
+
+ describe "css classes" do
+ it "are correct for open view" do
+ c = Card.new :name => 'Aopen', :content => "{{A|open}}"
+ Wagn::Renderer::Xml.new(c)._render(:core).should match /<card cardId="\d+" class="card-slot paragraph ALL TYPE-basic SELF-a view-open" home_view="open" name="A" style="" type_id="3">Alpha <cardlink class="known-card" card="\/Z">Z<\/cardlink><\/card>/
+ end
+ end
+
+ it "naked" do
+ render_card(:core, :name=>'A+B').should == "AlphaBeta"
+ end
+
+ it "content" do
+ pending "with html"
+ render_card(:content, :name=>'A+B').should be_html_with {
+ div( :class=>'included ALL ALL_PLUS TYPE-basic RIGHT-b TYPE_PLUS_RIGHT-basic-b SELF-a-b', :home_view=>'content') {
+ span( :class=>'content-content content')
+ }
+ }
+ end
+
+ it "titled" do
+ pending "with html"
+ render_card(:titled, :name=>'A+B').should be_html_with do
+ div( :home_view=>'titled') {
+ [ h1 { [ span{'A'}, span{'+'}, span{'B'} ] },
+ span(:class=>'titled-content'){'AlphaBeta'}
+ ]
+ }
+ end
+ end
+ end
+
+ describe "cgi params" do
+ it "renders params in card inclusions" do
+ c = Card.new :name => 'cardNaked', :content => "{{_card+B|naked}}"
+ result = Wagn::Renderer::Xml.new(c, :params=>{'_card' => "A"})._render_core
+ result.should == "AlphaBeta"
+ end
+
+ it "should not change name if variable isn't present" do
+ c = Card.new :name => 'cardBname', :content => "{{_card+B|name}}"
+ Wagn::Renderer::Xml.new(c)._render( :core ).should == "_card+B"
+ end
+
+ it "array (search card)" do
+ Card.create! :name => "n+a", :type=>"Number", :content=>"10"
+ Card.create! :name => "n+b", :type=>"Phrase", :content=>"say:\"what\""
+ Card.create! :name => "n+c", :type=>"Number", :content=>"30"
+ c = Card.new :name => 'nplusarray', :content => "{{n+*plus cards+by create|array}}"
+ Wagn::Renderer::Xml.new(c)._render( :core ).should == %{["10", "say:\\"what\\"", "30"]}
+ end
+
+ it "array (pointer card)" do
+ Card.create! :name => "n+a", :type=>"Number", :content=>"10"
+ Card.create! :name => "n+b", :type=>"Number", :content=>"20"
+ Card.create! :name => "n+c", :type=>"Number", :content=>"30"
+ Card.create! :name => "npoint", :type=>"Pointer", :content => "[[n+a]]\n[[n+b]]\n[[n+c]]"
+ c = Card.new :name => 'npointArray', :content => "{{npoint|array}}"
+ Wagn::Renderer::Xml.new(c)._render( :core ).should == %q{["10", "20", "30"]}
+ end
+
+=begin
+ it "should use inclusion view overrides" do
+ # FIXME love to have these in a scenario so they don't load every time.
+ t = Card.create! :name=>'t1', :content=>"{{t2|card}}"
+ Card.create! :name => "t2", :content => "{{t3|view}}"
+ Card.create! :name => "t3", :content => "boo"
+
+ # a little weird that we need :open_content to get the version without
+ # slot divs wrapped around it.
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :name } )
+ s.render( :core ).should == "t2"
+
+ # similar to above, but use link
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :link } )
+ s.render( :core ).should == "<a class=\"known-card\" href=\"/wagn/t2\">t2</a>"
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :core } )
+ s.render( :core ).should == "boo"
+ end
+=end
+ end
+
+ context "builtin card" do
+=begin
+ it "should use inclusion view overrides" do
+ # FIXME love to have these in a scenario so they don't load every time.
+ t = Card.create! :name=>'t1', :content=>"{{t2|card}}"
+ Card.create! :name => "t2", :content => "{{t3|view}}"
+ Card.create! :name => "t3", :content => "boo"
+
+ # a little weird that we need :open_content to get the version without
+ # slot divs wrapped around it.
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :name } )
+ s.render( :core ).should == "t2"
+
+ # similar to above, but use link
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :link } )
+ s.render( :core ).should == "<a class=\"known-card\" href=\"/wagn/t2\">t2</a>"
+ s = Wagn::Renderer.new(t, :inclusion_view_overrides=>{ :open => :core } )
+ s.render( :core ).should == "boo"
+ end
+=end
+
+ it "should render internal builtins" do
+ pending "with html"
+ render_card( :core, :content=>%{
+<div>
+ <span name="head">
+ Head:{{*head|naked}}
+ </span>
+ <span name="now">
+ Now:{{*now}}
+ </span>
+ <span name="version">
+ Version:{{*version|naked}}
+ </span>
+ <span name="foot">
+ Foot:{{*foot|core}}
+ </span>
+</div>} ).should be_html_with do
+ div {
+ span(:name=>'head') { }
+ span(:name=>'now') {
+ div(:home_view=>'content') {
+ span() { text(Time.now.strftime('%A, %B %d, %Y %I:%M %p %Z')) }
+ }
+ }
+ span(:name=>'version') { "Version:#{Wagn::Version.full}" }
+ span(:name=>"foot") { script(:type=>"text/javascript") {} }
+ }
+ end
+ end
+ end
+
+#~~~~~~~~~~~~~ content views
+# includes some *right stuff
+
+
+ context "Content settings" do
+ it "are rendered as raw" do
+ template = Card.new(:name=>'A+*right+*content', :content=>'[[link]] {{inclusion}}')
+ Wagn::Renderer::Xml.new(template)._render(:core).should == '[[link]] {{inclusion}}'
+ end
+
+ it "skips *content if narrower *default is present" do #this seems more like a settings test
+ pending
+ content_card = default_card = nil
+ Account.as_bot do
+ content_card = Card.create!(:name=>"Phrase+*type+*content", :content=>"Content Foo" )
+ default_card = Card.create!(:name=>"templated+*right+*default", :content=>"Default Bar" )
+ end
+ @card = Card.new( :name=>"test+templated", :type=>'Phrase' )
+ mock(@card).rule_card(:content, :default).returns(default_card)
+ Wagn::Renderer::Xml.new(@card).render(:raw).should == "Default Bar"
+ end
+
+ end
+
+#~~~~~~~~~~~~~~~ Cardtype Views ~~~~~~~~~~~~~~~~~#
+# (type sets)
+
+ context "cards of type" do
+ context "Date" do
+ it "should have special editor" do
+ data=xml_render_card(:link,:type=>'Date')
+ #warn "data = #{data}"
+ assert_view_select data, 'cardlink[class="wanted-card"]'
+ end
+ end
+
+ context "File and Image" do
+ pending "with html"
+ #image calls the file partial, so in a way this tests both
+ it "should have special editor" do
+ pending #This test works fine alone but fails when run with others
+
+ render_editor('Image').should be_html_with do
+ body do ## this is weird -- why does it have a body?
+ [div(:class=>'attachment-preview'),
+ div { iframe :class=>'upload-iframe'}
+ ]
+ end
+ end
+ end
+ end
+
+ context "Image" do
+ it "should handle size argument in inclusion syntax" do
+ Card.create! :name => "TestImage", :type=>"Image",
+ :content => %{TestImage.jpg\nimage/jpeg\n12345}
+ c=Card.new :name => 'Image1',
+ :content => "{{TestImage | naked; size:small }}"
+ r=Wagn::Renderer::Xml.new(c)._render( :core )
+ r.should == "/files/TestImage-small-#{Card['testImage'].current_revision_id}.jpg"
+ end
+ end
+
+ context "HTML" do
+ before do
+ Account.current_id= Card::WagnBotID
+ end
+
+ it "should have special editor" do
+ pending "with html"
+ render_editor('Html').should be_html_with { textarea :rows=>'30' }
+ end
+
+ it "should not render any content in closed view" do
+ render_card(:closed_content, :type=>'Html', :content=>"<strong>Lions and Tigers</strong>").should == ''
+ end
+ end
+
+ context "Number" do
+ it "should have special editor" do
+ pending "with html"
+ render_editor('Number').should be_html_with { input :type=>'text' }
+ end
+ end
+
+ context "Phrase" do
+ it "should have special editor" do
+ pending "with html"
+ render_editor('Phrase').should be_html_with { input :type=>'text', :class=>'phrasebox'}
+ end
+ end
+
+ context "Plain Text" do
+ it "should have special editor" do
+ pending "with html"
+ render_editor('Plain Text').should be_html_with { textarea :rows=>'3' }
+ end
+
+ it "should have special content that escapes HTML" do
+ render_card(:core, :type=>'Plain Text', :content=>"<b></b>").should == '&lt;b&gt;&lt;/b&gt;'
+ end
+ end
+
+ context "Search" do
+ it "should wrap search items with correct view class" do
+ pending "this is not yet default behavior"
+ Card.create :type=>'Search', :name=>'Asearch', :content=>%{{"type":"User"}}
+
+ c=xml_render_content("{{Asearch|naked;item:name}}")
+ c.should match('search-result-item item-name')
+ xml_render_content("{{Asearch|naked;item:open}}").should match('search-result-item item-open')
+ xml_render_content("{{Asearch|naked}}").should match('search-result-item item-closed')
+ end
+
+ it "should handle returning 'count'" do
+ render_card(:core, :type=>'Search', :content=>%{{ "type":"User", "return":"count"}}).should == '10'
+ end
+ end
+
+ context "Toggle" do
+ it "should have special editor" do
+ pending "with html"
+ render_editor('Toggle').should be_html_with { input :type=>'checkbox' }
+ end
+
+ it "should have yes/no as processed content" do
+ render_card(:core, :type=>'Toggle', :content=>"0").should == 'no'
+ render_card(:closed_content, :type=>'Toggle', :content=>"1").should == 'yes'
+ end
+ end
+ end
+
+
+ # ~~~~~~~~~~~~~~~~~ Builtins Views ~~~~~~~~~~~~~~~~~~~
+ # ( *self sets )
+
+
+ context "builtin card" do
+ context "*now" do
+ it "should have a date" do
+ render_card(:raw, :name=>'*now').match(/\w+day, \w+ \d+, \d{4}/ ).should_not be_nil
+ end
+ end
+
+ context "*version" do
+ it "should have an X.X.X version" do
+ render_card(:raw, :name=>'*version').
+ match(/\d\.\d+\.\w+/ ).should_not be_nil
+ end
+ end
+
+ context "*head" do
+ it "should have a javascript tag" do
+ pending "with html"
+ render_card(:raw, :name=>'*head').should be_html_with { script :type=>'text/javascript' }
+ end
+ end
+
+ context "*foot" do
+ it "should have a javascript tag" do
+ pending "with html"
+ render_card(:raw, :name=>'*foot').should be_html_with { script :type=>'text/javascript' }
+ end
+ end
+
+ context "*navbox" do
+ it "should have a form" do
+ pending "with html"
+ render_card(:raw, :name=>'*navbox').should be_html_with { form :id=>'navbox_form' }
+ #render_card(:raw, :name=>'*navbox').should == 'foobar'
+ end
+ end
+
+ context "*account link" do
+ it "should have a 'my card' link" do
+ pending
+ Account.as :joe_user do
+ render_card(:raw, :name=>'*account links').should be_html_with { span( :id=>'logging' ) {
+ a( :id=>'my-card-link') { 'My Card: Joe User' }
+ }
+ }
+ end
+ end
+ end
+
+ # also need one for *alerts
+ end
+
+
+#~~~~~~~~~ special views
+
+ context "open missing" do
+ it "should use the showname" do
+ xml_render_content('{{+cardipoo|open}}').match(/\<no_card status=\"missing\"\>Tempo Rary 2\+cardipoo\<\/no_card\>/ ).should_not be_nil
+ end
+ end
+
+
+ context "replace refs" do
+ before do
+ Account.current_id= Card::WagnBotID
+ end
+
+ it "replace references should work on inclusions inside links" do
+ card = Card.create!(:name=>"test", :content=>"[[foo|test{{test}}]]" )
+ assert_equal "[[foo|test{{best}}]]", card.replace_references("test", "best" )
+ end
+ end
+
+end
View
4 spec/lib/wagn/set/all/json_spec.rb
@@ -15,9 +15,9 @@
unknown = Card.new :name=>'sump'
unreadable = Card.new :name=>'kumq', :type=>'Fruit'
- unknown_json = Wagn::Renderer::JsonRenderer.new(unknown)._render_status
+ unknown_json = Wagn::Renderer::Json.new(unknown)._render_status
JSON[unknown_json].should == {"key"=>"sump","status"=>"unknown", 'url_key'=>'sump'}
- unreadable_json = Wagn::Renderer::JsonRenderer.new(unreadable)._render_status
+ unreadable_json = Wagn::Renderer::Json.new(unreadable)._render_status
JSON[unreadable_json].should == {"key"=>"kumq","status"=>"unknown", 'url_key'=>'kumq'}
end
end
View
2  spec/spec_helper.rb
@@ -16,8 +16,6 @@ def newcard(name, content="")
Spork.prefork do
require File.expand_path File.dirname(__FILE__) + "/../config/environment"
require File.expand_path File.dirname(__FILE__) + "/../lib/authenticated_test_helper.rb"
-
- #require File.expand_path File.dirname(__FILE__) + "/../lib/util/card_builder.rb"
require 'rspec/rails'
require_dependency 'chunks/chunk'
Something went wrong with that request. Please try again.