Skip to content

Commit

Permalink
Fixed 'root' scoping and custom urls with mode ('_' in url).
Browse files Browse the repository at this point in the history
  • Loading branch information
gaspard committed May 31, 2011
1 parent 9873beb commit 82eb7ea
Show file tree
Hide file tree
Showing 26 changed files with 192 additions and 122 deletions.
6 changes: 3 additions & 3 deletions app/controllers/columns_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def index

if role_a == role_b
a.name <=> b.name
elsif role_a.kpath == role_a.kpath
elsif role_a.kpath == role_b.kpath
role_a.name <=> role_b.name
else
role_a.kpath <=> role_a.kpath
role_a.kpath <=> role_b.kpath
end
end

Expand Down Expand Up @@ -88,8 +88,8 @@ def update
respond_to do |format|
if @column.update_attributes(params[:column])
flash.now[:notice] = _('Column was successfully updated.')
format.js
format.html { redirect_to(@column) }
format.js
format.xml { head :ok }
else
format.html { render :action => "edit" }
Expand Down
4 changes: 2 additions & 2 deletions app/models/site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Site < ActiveRecord::Base
ACTIONS = %w{clear_cache rebuild_index}
include RubyLess
safe_method :host => String, :lang_list => [String], :default_lang => String
safe_context :root => {:class => 'Project', :enroll => true, :method => 'root_node'}
safe_method :root => Proc.new {|h, r, s| {:method => 'root_node', :class => VirtualClass['Project'], :nil => true}}

validate :valid_site
validates_uniqueness_of :host
Expand All @@ -46,7 +46,7 @@ def create_for_host(host, su_password, opts={})
params = {
:name => host.split('.').first,
:authentication => false,
:auto_publish => false,
:auto_publish => true,
:redit_time => '2h',
:languages => '',
:default_lang => "en",
Expand Down
2 changes: 1 addition & 1 deletion app/models/virtual_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ def valid_virtual_class
end

def get_real_class(klass)
klass.kind_of?(VirtualClass) ? get_real_class(klass.superclass) : klass.to_s
(klass.kind_of?(VirtualClass) ? klass.real_class : klass).to_s
end

def old
Expand Down
2 changes: 1 addition & 1 deletion config/gems.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ yamltest: '= 0.7.0'
rubyless: '= 0.8.3'
property: '= 2.1.2'
versions: '= 0.3.1'
zafu: '= 0.7.9'
zafu: '= 0.8.0'

jeweler:

Expand Down
66 changes: 5 additions & 61 deletions lib/zena/acts/enrollable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,8 @@ class << base
end
end

# FIXME: remove all this and simply use VirtualClass['NNP'] in RubyLess:
# write 'safe_method_type' for VirtualClass and forward from there to the real_class
# def self.make_class(klass)
# if klass.kind_of?(VirtualClass)
# res_class = Class.new(klass.real_class) do
# include Named
# end
# elsif klass <= Node
# res_class = Class.new(klass) do
# include Named
# end
# else
# return klass
# end
#
#
# res_class.to_s = klass.name
# res_class.kpath = klass.kpath
# res_class.klass = klass
#
# res_class.load_roles!
# res_class
# end

module LoadRoles
# FIXME: can we remove or move the 'enroll' stuff to VirtualClass ?
def safe_method_type(signature, receiver = nil)
if type = super
if type[:enroll]
klass = type[:class]
if klass.kind_of?(Array)
if klass = Enrollable::Common.get_class(klass.first.to_s)
klass = [klass]
else
return nil
end
elsif klass
unless klass = Enrollable::Common.get_class(klass.to_s)
return nil
end
else
return nil
end
type.merge(:class => klass)
else
type
end
end
end
end # LoadRoles

module ModelMethods
def self.included(base)
base.extend LoadRoles

class << base
attr_accessor :loaded_role_properties
attr_accessor :declared_node_contexts, :declared_node_contexts_proc
Expand All @@ -74,20 +21,17 @@ def loaded_role_properties
end

# Declare a safe context resulting in a (virtual) sub-class of Node. This method
# ensures that the returned class will load the Roles available. If you need to
# use a virtual-class, you must declare it by using a Symbol or RubyLess will try
# to resolve it as a real class resulting in a NameError.
# ensures that the returned class will load the proper virtual Class during
# runtime.
def safe_node_context(methods_hash)
methods_hash[:defaults] ||= {}
methods_hash[:defaults][:nil] = true
methods_hash[:defaults][:enroll] = true
safe_method(methods_hash)
methods_hash.each do |key, opts|
safe_method key => Proc.new {|h, r, s| {:method => key, :class => VirtualClass[opts], :nil => true}}
end
end
end

base.class_eval do
attr_accessor :loaded_role_properties
include LoadRoles

def loaded_role_properties
@loaded_role_properties ||= {}
Expand Down
43 changes: 38 additions & 5 deletions lib/zena/console.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,21 @@ def field_to_prop(list, native_key, prop_key)
end
end

def set_prop(list, key, value)
list.each do |rec|
if rec.kind_of?(Node)
elems = rec.visible_versions
else
elems = [rec]
end
elems.each do |rec|
prop = rec.prop
prop[key] = value
Zena::Db.execute "UPDATE #{rec.class.table_name} SET properties=#{Zena::Db.quote(rec.class.encode_properties(prop))} WHERE id=#{rec[:id]}"
end
end
end

def login(name, host = nil)
finder = {}
finder[:conditions] = cond = [[]]
Expand Down Expand Up @@ -74,11 +89,29 @@ def nodes(zip_or_name)
end
end

def find(query)
default_scope = 'site'
query = {:qb => query} unless query.kind_of?(Hash)
query[:_find] = Node.plural_relation?(query[:qb].split(' ').first) ? :all : :first
nodes = secure(Node) { Node.search_records(query, :node => current_site.root_node, :default => {:scope => default_scope}) }
# Usage:
# find('contacts in site')
# find(:all, 'contacts in site') # same as above
# find(:qb => 'contacts in site', :_find => :all) # same as above
def find(count_or_query, pseudo_sql = nil, opts = {})
if count_or_query.kind_of?(Hash)
query = count_or_query
elsif count_or_query.kind_of?(Fixnum)
query = {:qb => "node in site where id = #{count_or_query}", :_find => :first}
elsif pseudo_sql.nil?
query = {:qb => count_or_query}
else
query = {:qb => pseudo_sql, :_find => count_or_query}
end
query[:_find] ||=
count = Node.plural_relation?(query[:qb].split(' ').first) ? :all : :first

nodes = secure(Node) do
Node.search_records(query,
:node => current_site.root_node,
:default => {:scope => 'site'}
)
end
end

def count(pseudo_sql, opts = {})
Expand Down
7 changes: 4 additions & 3 deletions lib/zena/core_ext/string.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
end

class String
ALLOWED_CHARS_IN_URL = " a-zA-Z0-9_\\."
# in filename, allow '-' because it does not represent a space
ALLOWED_CHARS_IN_FILENAME = "#{ALLOWED_CHARS_IN_URL}\\-"
ALLOWED_CHARS_IN_URL = " a-zA-Z0-9\\."
# in filename, allow '-' and '_' because it does not represent a space and we do
# not have the mode confusion thing.
ALLOWED_CHARS_IN_FILENAME = "#{ALLOWED_CHARS_IN_URL}_\\-"
# Everything apart from a-zA-Z0-9_.-/$ are not allowed in template paths
ALLOWED_CHARS_IN_FILEPATH = "#{ALLOWED_CHARS_IN_FILENAME}+/$"
TO_FILENAME_REGEXP = %r{([^ #{ALLOWED_CHARS_IN_FILENAME}]+)}n
Expand Down
4 changes: 2 additions & 2 deletions lib/zena/parser/zazen_rules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def scan_exclam
else
store @helper._('[documents]')
end
elsif @text =~ /\A\!([^0-9:]{0,2})(#{PSEUDO_ID_REGEXP})(_([^\/\!]+)|)(\/([^\!]*)|)\!(:([^:\(][^\s]+|#{PSEUDO_ID_REGEXP}(_[a-zA-Z]+|))|)/m
elsif @text =~ /\A\!([^0-9:]{0,2})(#{PSEUDO_ID_REGEXP})(_([^\/\!]+)|)(\/([^\!]*)|)\!(:([^:\(][^\s]*|#{PSEUDO_ID_REGEXP}(_[a-zA-Z]+|))|)/m
# image !<.:art++_pv/blah blah!:12
#puts "SHORCUT IMAGE:#{$~.to_a.inspect}"
eat $&
Expand Down Expand Up @@ -144,7 +144,7 @@ def scan_exclam
else
store "[#{id} not found]"
end
elsif @text =~ /\A\!([^0-9]{0,2})([0-9]+)(_([^\/\!]+)|)(\/([^\!]*)|)\!(:([^:\(][^\s]+|#{PSEUDO_ID_REGEXP}(_[a-zA-Z]+|))|)/m
elsif @text =~ /\A\!([^0-9]{0,2})([0-9]+)(_([^\/\!]+)|)(\/([^\!]*)|)\!(:([^:\(][^\s]*|#{PSEUDO_ID_REGEXP}(_[a-zA-Z]+|))|)/m
# image !<.12_pv/blah blah!:12
#puts "IMAGE:[#{$&}]"
eat $&
Expand Down
17 changes: 16 additions & 1 deletion lib/zena/use/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def self.visitor_node_proc
safe_method :visitor => User
safe_method :visitor_node => visitor_node_proc
safe_method :main => Proc.new {|h, r, s| {:method => '@node', :class => VirtualClass['Node']}}
safe_method :root => {:method => 'visitor.site.root_node', :class => 'Project', :enroll => true, :nil => true}
safe_method :root => Proc.new {|h, r, s| {:method => 'visitor.site.root_node', :class => VirtualClass['Project'], :nil => true}}
safe_method :site => {:class => Site, :method => 'visitor.site'}

# Group an array of records by key.
Expand Down Expand Up @@ -161,6 +161,21 @@ def r_context

alias r_find r_context

def r_set
@params.each do |var, code|
var = var.to_s
begin
typed_string = ::RubyLess.translate(self, code)
name = get_var_name('set_var', var)
out "<% #{name} = #{typed_string} %>"
set_context_var('set_var', var, RubyLess::TypedString.new(name, typed_string.opts))
rescue RubyLess::NoMethodError => err
parser_error(err.message, code)
end
end
expand_with
end

# Group elements in a list. Use :order to specify order.
def r_group
return parser_error("cannot be used outside of a list") unless node.list_context?
Expand Down
6 changes: 5 additions & 1 deletion lib/zena/use/query_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ def safe_first(query)
# Find related nodes.
# See Node#build_find for details on the options available.
# TODO: do we need rubyless translate here ? It should be removed.
def find(count, pseudo_sql, opts = {})
def find(count, pseudo_sql = nil, opts = {})
if pseudo_sql.nil?
pseudo_sql = count
count = Node.plural_relation?(pseudo_sql.split(' ').first) ? :all : :first
end
if !opts[:skip_rubyless] && type = RubyLess::SafeClass.safe_method_type_for(self.class, [pseudo_sql])
self.send(type[:method])
else
Expand Down
31 changes: 22 additions & 9 deletions lib/zena/use/urls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module Urls
}


ALLOWED_REGEXP = /\A(([a-zA-Z]+)([0-9]+)|([#{String::ALLOWED_CHARS_IN_FILENAME}%]+))(_[a-zA-Z]+|)(\..+|)\Z/
ALLOWED_REGEXP = /\A(([a-zA-Z]+)([0-9]+)|([#{String::ALLOWED_CHARS_IN_URL}\-%]+))(_[a-zA-Z]+|)(\..+|)\Z/

module Common
CACHESTAMP_FORMATS = ['jpg', 'png', 'gif', 'css', 'js']
Expand Down Expand Up @@ -247,15 +247,16 @@ def path_params
end

def http_protocol
@http_protocol ||= begin
if request.protocol =~ /^(.*):\/\/$/
$1
else
'http'
end
end
'http'
end

# We do not have access to the request. Port and host should be passed from view.
def host_with_port
current_site.host
end
end # Common

module ViewAndControllerMethods
def host_with_port
@host_with_port ||= begin
port = request.port
Expand All @@ -266,14 +267,26 @@ def host_with_port
end
end
end
end # Common

def http_protocol
@http_protocol ||= begin
if request.protocol =~ /^(.*):\/\/$/
$1
else
'http'
end
end
end
end

module ControllerMethods
include Common
include ViewAndControllerMethods
end # ControllerMethods

module ViewMethods
include Common
include ViewAndControllerMethods
include RubyLess
safe_method [:url, Node] => {:class => String, :method => 'zen_url'}
safe_method [:url, Node, Hash] => {:class => String, :method => 'zen_url'}
Expand Down
14 changes: 12 additions & 2 deletions test/functional/nodes_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class NodesControllerTest < Zena::Controller::TestCase

context 'creating a node' do
subject do
{:action => 'create', :controller => 'nodes', :node => {:parent_id => nodes_zip(:zena), :title => 'hello', :klass => 'Page'}}
{:action => 'create', :controller => 'nodes', :node => {:parent_id => nodes_zip(:zena), :title => 'hello', :klass => 'Blog'}}
end

should 'recognize create page' do
Expand All @@ -238,7 +238,17 @@ class NodesControllerTest < Zena::Controller::TestCase
should 'succeed' do
post_subject
node = assigns(:node)
assert_redirected_to "/oo/page#{node.zip}.html"
assert_redirected_to "/oo/blog#{node.zip}.html"
end

should 'set type and vclass' do
post_subject
node = assigns(:node)
assert_equal 'NPPB', node.kpath
assert_equal 'Project', node.type
node = Node.find(node.id)
assert_equal 'NPPB', node.kpath
assert_equal 'Project', node.type
end
end # creating a node

Expand Down
4 changes: 2 additions & 2 deletions test/functional/sites_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def setup
assert File.exist?(filepath)
assert CachedPage.find(:first, :conditions => ["path = ?", "/test.host/public/en/clear_cache_test.html"])
login(:lion)
post 'clear_cache', :id => visitor.site.id
post 'action', :do => 'clear_cache', :id => visitor.site.id
assert !File.exist?(filepath)
assert !CachedPage.find(:first, :conditions => ["path = ?", "/test.host/public/en/clear_cache_test.html"])
end
Expand All @@ -31,7 +31,7 @@ def setup
File.open(filepath, 'wb') {|f| f.puts "puts 'hello'"}
assert File.exist?(filepath)
login(:lion)
post 'clear_cache', :id => visitor.site.id
post 'action', :do => 'clear_cache', :id => visitor.site.id
assert !File.exist?(filepath)
end
end
Expand Down

0 comments on commit 82eb7ea

Please sign in to comment.