Class: Webgen::Node
- Inherits:
-
Object
- Object
- Webgen::Node
- Includes:
- Loggable, WebsiteAccess
- Defined in:
- lib/webgen/node.rb
Overview
Represents a file, a directory or a fragment. A node always belongs to a Tree.
Instance Attribute Summary collapse
-
#absolute_cn ⇒ Object
readonly
The absolute canonical name of this node.
-
#absolute_lcn ⇒ Object
readonly
The absolute localized canonical name of this node.
-
#children ⇒ Object
readonly
The children of this node.
-
#cn ⇒ Object
readonly
The canonical name of this node.
-
#created ⇒ Object
Has the node been created or has it been read from the cache?.
-
#dirty ⇒ Object
Set by other objects to
trueif they think the object has changed since the last run. -
#dirty_meta_info ⇒ Object
Set by other objects to
trueif the meta information of the node has changed since the last run. -
#lang ⇒ Object
readonly
The language of this node.
-
#lcn ⇒ Object
readonly
The localized canonical name of this node.
-
#level ⇒ Object
readonly
The level of the node.
-
#meta_info ⇒ Object
readonly
Meta information associated with the node.
-
#parent ⇒ Object
readonly
The parent node.
-
#path ⇒ Object
readonly
The full output path of this node.
-
#tree ⇒ Object
readonly
The tree to which this node belongs.
Class Method Summary collapse
-
.absolute_name(parent, name, type) ⇒ Object
Construct the absolute (localized) canonical name by using the
parentnode andname(which can be a cn or an lcn). -
.url(name) ⇒ Object
Construct an internal URL for the given
namewhich can be a acn/alcn/path.
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Sort nodes by using the meta info
sort_info(ortitleifsort_infois not set) of both involved nodes. -
#=~(pattern) ⇒ Object
Return
trueif the alcn matches the pattern. -
#[](key) ⇒ Object
Return the meta information item for
key. -
#[]=(key, value) ⇒ Object
Assign
valueto the meta information item forkey. -
#changed? ⇒ Boolean
Return
trueif the node has changed since the last webgen run. -
#in_lang(lang) ⇒ Object
Return the node with the same canonical name but in language
langor, if no such node exists, an unlocalized version of the node. -
#in_subtree_of?(node) ⇒ Boolean
Check if the this node is in the subtree which is spanned by
node. -
#initialize(parent, path, cn, meta_info = {}) ⇒ Node
constructor
Create a new Node instance.
-
#inspect ⇒ Object
Return an informative representation of the node.
-
#is_directory? ⇒ Boolean
Check if the node is a directory.
-
#is_file? ⇒ Boolean
Check if the node is a file.
-
#is_fragment? ⇒ Boolean
Check if the node is a fragment.
-
#is_root? ⇒ Boolean
Check if the node is the root node.
-
#link_to(node, attr = {}) ⇒ Object
Return a HTML link from this node to the
nodeor, if this node andnodeare the same and the parameterwebsite.link_to_current_pageisfalse, aspanelement with the link text. -
#meta_info_changed? ⇒ Boolean
Return
trueif the meta information of the node has changed. -
#node_info ⇒ Object
Return the node information hash which contains information for processing the node.
-
#resolve(path, lang = nil) ⇒ Object
Return the node representing the given
pathwhich can be an acn/alcn. -
#route_to(other) ⇒ Object
Return the relative path to the given path
other. -
#routing_node(lang) ⇒ Object
Return the routing node in language
langwhich is the node that is used when routing to this node.
Methods included from Loggable
Methods included from WebsiteAccess
Constructor Details
#initialize(parent, path, cn, meta_info = {}) ⇒ Node
Create a new Node instance.
parent(immutable)-
The parent node under which this nodes should be created.
path(immutable)-
The full output path for this node. If this node is a directory, the path must have a trailing slash (
dir/). If it is a fragment, the hash sign must be the first character of the path (#fragment). This can also be an absolute path likehttp://myhost.com/. cn(immutable)-
The canonical name for this node. Needs to be of the form
basename.extorbasenamewherebasenamedoes not contain any dots. Also, thebasenamemust not include a language part! meta_info-
A hash with meta information for the new node.
The language of a node is taken from the meta information lang and the entry is deleted from the meta information hash. The language cannot be changed afterwards! If no lang key is found, the node is language neutral.
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/webgen/node.rb', line 79 def initialize(parent, path, cn, = {}) @parent = parent @path = path.freeze @cn = cn.chomp('/').freeze @lang = .delete('lang').freeze @lang = nil unless is_file? = @children = [] @dirty = true @created = true init_rest end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object (private)
Delegate missing methods to a processor. The current node is placed into the argument array as the first argument before the method name is invoked on the processor.
337 338 339 340 341 342 343 |
# File 'lib/webgen/node.rb', line 337 def method_missing(name, *args, &block) if node_info[:processor] website.cache.instance(node_info[:processor]).send(name, *([self] + args), &block) else super end end |
Instance Attribute Details
#absolute_cn ⇒ Object (readonly)
The absolute canonical name of this node.
32 33 34 |
# File 'lib/webgen/node.rb', line 32 def absolute_cn @absolute_cn end |
#absolute_lcn ⇒ Object (readonly)
The absolute localized canonical name of this node.
38 39 40 |
# File 'lib/webgen/node.rb', line 38 def absolute_lcn @absolute_lcn end |
#children ⇒ Object (readonly)
The children of this node.
20 21 22 |
# File 'lib/webgen/node.rb', line 20 def children @children end |
#cn ⇒ Object (readonly)
The canonical name of this node.
29 30 31 |
# File 'lib/webgen/node.rb', line 29 def cn @cn end |
#created ⇒ Object
Has the node been created or has it been read from the cache?
58 59 60 |
# File 'lib/webgen/node.rb', line 58 def created @created end |
#dirty ⇒ Object
Set by other objects to true if they think the object has changed since the last run. Must not be set to false once it is true!
51 52 53 |
# File 'lib/webgen/node.rb', line 51 def dirty @dirty end |
#dirty_meta_info ⇒ Object
Set by other objects to true if the meta information of the node has changed since the last run. Must not be set to false once it is true!
55 56 57 |
# File 'lib/webgen/node.rb', line 55 def end |
#lang ⇒ Object (readonly)
The language of this node.
44 45 46 |
# File 'lib/webgen/node.rb', line 44 def lang @lang end |
#lcn ⇒ Object (readonly)
The localized canonical name of this node.
35 36 37 |
# File 'lib/webgen/node.rb', line 35 def lcn @lcn end |
#level ⇒ Object (readonly)
The level of the node. The level specifies how deep the node is in the hierarchy.
41 42 43 |
# File 'lib/webgen/node.rb', line 41 def level @level end |
#meta_info ⇒ Object (readonly)
Meta information associated with the node.
47 48 49 |
# File 'lib/webgen/node.rb', line 47 def end |
#parent ⇒ Object (readonly)
The parent node.
17 18 19 |
# File 'lib/webgen/node.rb', line 17 def parent @parent end |
#path ⇒ Object (readonly)
The full output path of this node.
23 24 25 |
# File 'lib/webgen/node.rb', line 23 def path @path end |
#tree ⇒ Object (readonly)
The tree to which this node belongs.
26 27 28 |
# File 'lib/webgen/node.rb', line 26 def tree @tree end |
Class Method Details
.absolute_name(parent, name, type) ⇒ Object
Construct the absolute (localized) canonical name by using the parent node and name (which can be a cn or an lcn). The type can be either :alcn or :acn.
165 166 167 168 169 170 171 172 173 |
# File 'lib/webgen/node.rb', line 165 def self.absolute_name(parent, name, type) if parent.kind_of?(Tree) '' else parent = parent.parent while parent.is_fragment? # Handle fragment nodes specially in case they are nested parent_name = (type == :alcn ? parent.absolute_lcn : parent.absolute_cn) parent_name + (parent_name !~ /\/$/ && (parent.is_directory? || parent == parent.tree.dummy_root) ? '/' : '') + name end end |
.url(name) ⇒ Object
Construct an internal URL for the given name which can be a acn/alcn/path.
176 177 178 179 180 |
# File 'lib/webgen/node.rb', line 176 def self.url(name) url = URI::parse(name) url = URI::parse('webgen://webgen.localhost/') + url unless url.absolute? url end |
Instance Method Details
#<=>(other) ⇒ Object
Sort nodes by using the meta info sort_info (or title if sort_info is not set) of both involved nodes.
153 154 155 156 157 158 159 160 161 |
# File 'lib/webgen/node.rb', line 153 def <=>(other) self_so = (['sort_info'] && ['sort_info'].to_s) || ['title'] || '' other_so = (other['sort_info'] && other['sort_info'].to_s) || other['title'] || '' if self_so !~ /\D/ && other_so !~ /\D/ self_so = self_so.to_i other_so = other_so.to_i end self_so <=> other_so end |
#=~(pattern) ⇒ Object
Return true if the alcn matches the pattern. See File.fnmatch for useable patterns.
147 148 149 |
# File 'lib/webgen/node.rb', line 147 def =~(pattern) File.fnmatch(pattern, @absolute_lcn, File::FNM_DOTMATCH|File::FNM_CASEFOLD|File::FNM_PATHNAME) end |
#[](key) ⇒ Object
Return the meta information item for key.
93 94 95 |
# File 'lib/webgen/node.rb', line 93 def [](key) [key] end |
#[]=(key, value) ⇒ Object
Assign value to the meta information item for key.
98 99 100 |
# File 'lib/webgen/node.rb', line 98 def []=(key, value) [key] = value end |
#changed? ⇒ Boolean
Return true if the node has changed since the last webgen run. If it has changed, dirty is set to true.
121 122 123 124 125 126 127 128 |
# File 'lib/webgen/node.rb', line 121 def changed? if_not_checked(:node) do @dirty = @dirty || @dirty = node_info[:used_nodes].any? {|n| n != @absolute_lcn && (!tree[n] || tree[n].changed?)} unless @dirty website.blackboard.dispatch_msg(:node_changed?, self) unless @dirty end @dirty end |
#in_lang(lang) ⇒ Object
Return the node with the same canonical name but in language lang or, if no such node exists, an unlocalized version of the node. If no such node is found either, nil is returned.
194 195 196 197 198 199 200 201 202 203 |
# File 'lib/webgen/node.rb', line 194 def in_lang(lang) avail = @tree.node_access[:acn][@absolute_cn] avail.find do |n| n = n.parent while n.is_fragment? n.lang == lang end || avail.find do |n| n = n.parent while n.is_fragment? n.lang.nil? end end |
#in_subtree_of?(node) ⇒ Boolean
Check if the this node is in the subtree which is spanned by node. The check is performed using only the parent information of the involved nodes, NOT the actual path/alcn values!
185 186 187 188 189 |
# File 'lib/webgen/node.rb', line 185 def in_subtree_of?(node) temp = self temp = temp.parent while temp != tree.dummy_root && temp != node temp != tree.dummy_root end |
#inspect ⇒ Object
Return an informative representation of the node.
142 143 144 |
# File 'lib/webgen/node.rb', line 142 def inspect "<##{self.class.name}: alcn=#{@absolute_lcn}>" end |
#is_directory? ⇒ Boolean
Check if the node is a directory.
108 |
# File 'lib/webgen/node.rb', line 108 def is_directory?; @path[-1] == ?/; end |
#is_file? ⇒ Boolean
Check if the node is a file.
111 |
# File 'lib/webgen/node.rb', line 111 def is_file?; !is_directory? && !is_fragment?; end |
#is_fragment? ⇒ Boolean
Check if the node is a fragment.
114 |
# File 'lib/webgen/node.rb', line 114 def is_fragment?; @cn[0] == ?# end |
#is_root? ⇒ Boolean
Check if the node is the root node.
117 |
# File 'lib/webgen/node.rb', line 117 def is_root?; self == tree.root; end |
#link_to(node, attr = {}) ⇒ Object
Return a HTML link from this node to the node or, if this node and node are the same and the parameter website.link_to_current_page is false, a span element with the link text.
You can optionally specify additional attributes for the HTML element in the attr Hash. Also, the meta information link_attrs of the given node is used, if available, to set attributes. However, the attr parameter takes precedence over the link_attrs meta information. Be aware that all key-value pairs with Symbol keys are removed before the attributes are written. Therefore you always need to specify general attributes with Strings!
If the special value :link_text is present in the attributes, it will be used as the link text; otherwise the title of the node will be used.
If the special value :lang is present in the attributes, it will be used as parameter to the node.routing_node call for getting the linked-to node instead of this node’s lang attribute. Note: this is only useful when linking to a directory.
291 292 293 294 295 296 297 298 299 300 301 |
# File 'lib/webgen/node.rb', line 291 def link_to(node, attr = {}) attr = node['link_attrs'].merge(attr) if node['link_attrs'].kind_of?(Hash) rnode = node.routing_node(attr[:lang] || @lang) link_text = attr[:link_text] || (rnode != node && rnode['routed_title']) || node['title'] attr.delete_if {|k,v| k.kind_of?(Symbol)} use_link = (rnode != self || website.config['website.link_to_current_page']) attr['href'] = self.route_to(rnode) if use_link attrs = attr.collect {|name,value| "#{name.to_s}=\"#{value}\"" }.sort.unshift('').join(' ') (use_link ? "<a#{attrs}>#{link_text}</a>" : "<span#{attrs}>#{link_text}</span>") end |
#meta_info_changed? ⇒ Boolean
Return true if the meta information of the node has changed.
131 132 133 134 135 136 137 138 139 |
# File 'lib/webgen/node.rb', line 131 def if_not_checked(:meta_info) do = node_info[:used_meta_info_nodes].any? do |n| n != @absolute_lcn && (!tree[n] || tree[n].) end unless website.blackboard.dispatch_msg(:node_meta_info_changed?, self) unless end end |
#node_info ⇒ Object
Return the node information hash which contains information for processing the node.
103 104 105 |
# File 'lib/webgen/node.rb', line 103 def node_info tree.node_info[@absolute_lcn] ||= {} end |
#resolve(path, lang = nil) ⇒ Object
Return the node representing the given path which can be an acn/alcn. The path can be absolute (i.e. starting with a slash) or relative to the current node. If no node exists for the given path or if the path is invalid, nil is returned.
If the path is an alcn and a node is found, it is returned. If the path is an acn, the correct localized node according to lang is returned or if no such node exists but an unlocalized version does, the unlocalized node is returned.
212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/webgen/node.rb', line 212 def resolve(path, lang = nil) url = self.class.url(self.is_directory? ? File.join(@absolute_lcn, '/') : @absolute_lcn) + path path = url.path + (url.fragment.nil? ? '' : '#' + url.fragment) path.chomp!('/') unless path == '/' return nil if path =~ /^\/\.\./ node = @tree[path, :alcn] if node && node.absolute_cn != path node else (node = @tree[path, :acn]) && node.in_lang(lang) end end |
#route_to(other) ⇒ Object
Return the relative path to the given path other. The parameter other can be a Node or a String.
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/webgen/node.rb', line 229 def route_to(other) my_url = self.class.url(@path) other_url = if other.kind_of?(Node) self.class.url(other.routing_node(@lang).path) elsif other.kind_of?(String) my_url + other else raise ArgumentError, "improper class for argument" end # resolve any '.' and '..' paths in the target url if other_url.path =~ /\/\.\.?\// && other_url.scheme == 'webgen' other_url.path = Pathname.new(other_url.path).cleanpath.to_s end route = my_url.route_to(other_url).to_s (route == '' ? File.basename(self.path) : route) end |
#routing_node(lang) ⇒ Object
Return the routing node in language lang which is the node that is used when routing to this node. The returned node can differ from the node itself in case of a directory where the routing node is the directory index node.
250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
# File 'lib/webgen/node.rb', line 250 def routing_node(lang) if !is_directory? self else key = [absolute_lcn, :index_node, lang] vcache = website.cache.volatile return vcache[key] if vcache.has_key?(key) index_path = self.['index_path'] if index_path.nil? vcache[key] = self else index_node = resolve(index_path, lang) if index_node vcache[key] = index_node log(:info) { "Directory index path for <#{absolute_lcn}> => <#{index_node.absolute_lcn}>" } else vcache[key] = self log(:warn) { "No directory index path found for directory <#{absolute_lcn}>" } end end vcache[key] end end |