Class: Webgen::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/webgen/node.rb

Overview

Represents a file, a directory or a fragment. A node always belongs to a Tree.

All needed meta and processing information is associated with the node itself. The meta information is available through the #[] and #meta_info accessors, the internal processing information through the #node_info accessor.

This class is not directly used. Instead path handlers define sub-classes that provide handler specific methods. See the basic sub-class Webgen::PathHandler::Base::Node.

Direct Known Subclasses

PathHandler::Base::Node

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, cn, dest_path, meta_info = {}) ⇒ Node

Create a new Node instance.

parent (immutable)

The parent node under which this nodes should be created.

cn (immutable)

The canonical name for this node. Needs to be of the form ‘basename.ext’ or ‘basename’ where basename does not contain any dots. Also, the basename must not include a language part!

dest_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, it has to include a hash sign. This can also be an absolute path like example.com.

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 unlocalized.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/webgen/node.rb', line 79

def initialize(parent, cn, dest_path, meta_info = {})
  @parent = parent
  @children = []
  @cn = cn.freeze
  @dest_path = dest_path.freeze

  @lang = Webgen::LanguageManager.language_for_code(meta_info.delete('lang'))
  @lang = nil unless is_file?

  @lcn = Webgen::Path.lcn(@cn, @lang).freeze
  @acn = (@parent.kind_of?(Webgen::Node) ? @parent.acn.sub(/#.*$/, '') + @cn : '').freeze
  @alcn = (@parent.kind_of?(Webgen::Node) ? @parent.alcn.sub(/#.*$/, '') + @lcn : '').freeze

  @meta_info = meta_info
  @node_info = {}

  @level = -1
  @tree = @parent
  while @tree.kind_of?(Webgen::Node)
    @level += 1
    @tree = @tree.parent
  end

  @tree.register_node(self)
  @parent.children << self unless @parent == @tree
end

Instance Attribute Details

#acnObject (readonly)

The absolute canonical name of this node.



33
34
35
# File 'lib/webgen/node.rb', line 33

def acn
  @acn
end

#alcnObject (readonly)

The absolute localized canonical name of this node.



36
37
38
# File 'lib/webgen/node.rb', line 36

def alcn
  @alcn
end

#childrenObject (readonly)

The child nodes of this node.



24
25
26
# File 'lib/webgen/node.rb', line 24

def children
  @children
end

#cnObject (readonly)

The canonical name of this node.



27
28
29
# File 'lib/webgen/node.rb', line 27

def cn
  @cn
end

#dest_pathObject (readonly)

The full destination path of this node.



52
53
54
# File 'lib/webgen/node.rb', line 52

def dest_path
  @dest_path
end

#langObject (readonly)

The language of this node.



42
43
44
# File 'lib/webgen/node.rb', line 42

def lang
  @lang
end

#lcnObject (readonly)

The localized canonical name of this node.



30
31
32
# File 'lib/webgen/node.rb', line 30

def lcn
  @lcn
end

#levelObject (readonly)

The level of the node. The level specifies how deep the node is in the hierarchy.



39
40
41
# File 'lib/webgen/node.rb', line 39

def level
  @level
end

#meta_infoObject (readonly)

Meta information associated with the node. If you need just a value for a meta information key, use the #[] method.



46
47
48
# File 'lib/webgen/node.rb', line 46

def meta_info
  @meta_info
end

#node_infoObject (readonly)

Return the node information hash which contains information for processing the node.



49
50
51
# File 'lib/webgen/node.rb', line 49

def node_info
  @node_info
end

#parentObject (readonly)

The parent node. This is in all but one case a Node object. The one exception is that the parent of the Tree#dummy_node is a Tree object.



21
22
23
# File 'lib/webgen/node.rb', line 21

def parent
  @parent
end

#treeObject (readonly)

The tree to which this node belongs.



55
56
57
# File 'lib/webgen/node.rb', line 55

def tree
  @tree
end

Instance Method Details

#=~(pattern) ⇒ Object

Return true if the #alcn matches the pattern.

See Webgen::Path.matches_pattern? for more information.



153
154
155
# File 'lib/webgen/node.rb', line 153

def =~(pattern)
  Webgen::Path.matches_pattern?(@alcn, pattern)
end

#[](key) ⇒ Object

Return the meta information item for key.



107
108
109
# File 'lib/webgen/node.rb', line 107

def [](key)
  @meta_info[key]
end

#inspectObject

:nodoc:



146
147
148
# File 'lib/webgen/node.rb', line 146

def inspect #:nodoc:
  "<##{self.class.name}: alcn=#{@alcn}>"
end

#is_ancestor_of?(node) ⇒ Boolean

Check if the this node is an ancestor of node.

The check is performed using only the parent information of the involved nodes, NOT the actual alcn values!

Returns:

  • (Boolean)


135
136
137
138
139
# File 'lib/webgen/node.rb', line 135

def is_ancestor_of?(node)
  node = node.parent
  node = node.parent while node != tree.dummy_root && node != self
  node != tree.dummy_root
end

#is_directory?Boolean

Check if the node is a directory.

Returns:

  • (Boolean)


112
113
114
# File 'lib/webgen/node.rb', line 112

def is_directory?
  @cn[-1] == ?/ && !is_fragment?
end

#is_file?Boolean

Check if the node is a file.

Returns:

  • (Boolean)


117
118
119
# File 'lib/webgen/node.rb', line 117

def is_file?
  !is_directory? && !is_fragment?
end

#is_fragment?Boolean

Check if the node is a fragment.

Returns:

  • (Boolean)


122
123
124
# File 'lib/webgen/node.rb', line 122

def is_fragment?
  @cn[0] == ?#
end

#is_root?Boolean

Check if the node is the root node.

Returns:

  • (Boolean)


127
128
129
# File 'lib/webgen/node.rb', line 127

def is_root?
  self == tree.root
end

Return a HTML link from this node to the given node.

If the lang parameter is not used, it defaults to the language of the current node.

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.

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.



209
210
211
212
213
214
215
216
217
218
# File 'lib/webgen/node.rb', line 209

def link_to(node, lang = @lang, attr = {})
  rnode = node.proxy_node(lang)
  attr = (rnode['link_attrs'].kind_of?(Hash) ? rnode['link_attrs'] : {}).merge(attr)
  link_text = attr.delete('link_text') || (rnode != node && rnode['routed_title']) || node['title']

  attr['href'] = route_to(node, lang)
  attr['hreflang'] = rnode.lang.to_s if rnode.lang
  attrs = attr.collect {|name,value| "#{name.to_s}=\"#{value}\"" }.sort.unshift('').join(' ')
  "<a#{attrs}>#{link_text}</a>"
end

#proxy_node(lang = @lang) ⇒ Object

Return the proxy node in language lang.

This node should be used, for example, when routing to this node. The proxy node is found by using the proxy_path meta information. This meta information is usually set on directories to specify the node that should be used for the “directory index”.

If the lang parameter is not used, it defaults to the language of the current node.



194
195
196
# File 'lib/webgen/node.rb', line 194

def proxy_node(lang = @lang)
  @meta_info['proxy_path'] && resolve(@meta_info['proxy_path'], lang, true) || self
end

#resolve(path, lang = @lang, msg_on_failure = false) ⇒ Object

Return the node representing the given path in the given language.

The path can be absolute (i.e. starting with a slash) or relative to the current node. Relative paths are made absolute by using the #alcn of the current node.

If the lang parameter is not used, it defaults to the language of the current node.

See Tree#resolve_node for detailed information on how the correct node for the path is found and for the msg_on_failure parameter.



166
167
168
# File 'lib/webgen/node.rb', line 166

def resolve(path, lang = @lang, msg_on_failure = false)
  @tree.resolve_node(Webgen::Path.append(@alcn, path), lang, msg_on_failure)
end

#route_to(node, lang = @lang) ⇒ Object

Return the relative path to the given node.

If the lang parameter is not used, it defaults to the language of the current node.



173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/webgen/node.rb', line 173

def route_to(node, lang = @lang)
  my_url = Webgen::Path.url(@dest_path)
  pnode = node.proxy_node(lang)
  other_url = Webgen::Path.url(pnode['routing_path'] || pnode.dest_path)

  # resolve any '.' and '..' paths in the target url
  if other_url.path =~ /\/\.\.?\// && other_url.scheme == 'webgen'
    other_url = other_url.dup
    other_url.path = Pathname.new(other_url.path).cleanpath.to_s
  end
  route = my_url.route_to(other_url).to_s
  (route == '' ? File.basename(@dest_path) : route)
end

#to_sObject

Return the string representation of the node which is just the #alcn.



142
143
144
# File 'lib/webgen/node.rb', line 142

def to_s
  @alcn
end

#versionsObject

Return all versions of this node.



221
222
223
224
# File 'lib/webgen/node.rb', line 221

def versions
  tree.node_access[:alcn].select {|alcn, n| n.node_info[:path] == node_info[:path]}.
    each_with_object({}) {|(_, v), h| h[v['version']] = v}
end