Class: Utopia::Content

Inherits:
Object
  • Object
show all
Defined in:
lib/utopia/content.rb,
lib/utopia/content/tag.rb,
lib/utopia/content/link.rb,
lib/utopia/content/node.rb,
lib/utopia/content/links.rb,
lib/utopia/content/processor.rb,
lib/utopia/content/transaction.rb

Defined Under Namespace

Classes: Link, Links, Node, Processor, Tag, Transaction, UnbalancedTagError

Constant Summary collapse

INDEX =
'index'.freeze
XNODE_EXTENSION =
'.xnode'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, **options) ⇒ Content

Returns a new instance of Content.



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/utopia/content.rb', line 35

def initialize(app, **options)
  @app = app
  
  @root = File.expand_path(options[:root] || Utopia::default_root)
  
  if options[:cache_templates]
    @templates = Concurrent::Map.new
  end
  
  @tags = options.fetch(:tags, {})
  
  self.freeze
end

Instance Attribute Details

#rootObject (readonly)

Returns the value of attribute root.



56
57
58
# File 'lib/utopia/content.rb', line 56

def root
  @root
end

Instance Method Details

#call(env) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/utopia/content.rb', line 119

def call(env)
  request = Rack::Request.new(env)
  path = Path.create(request.path_info)
  
  # Check if the request is to a non-specific index. This only works for requests with a given name:
  basename = path.basename
  directory_path = File.join(@root, path.dirname.components, basename.name)

  # If the request for /foo/bar{extensions} is actually a directory, rewrite it to /foo/bar/index{extensions}:
  if File.directory? directory_path
    index_path = [basename.name, basename.rename(INDEX)]
    
    return [307, {HTTP::LOCATION => path.dirname.join(index_path).to_s}, []]
  end

  locale = env[Localization::CURRENT_LOCALE_KEY]
  if link = Links.for(@root, path, locale)
    if link.path and node = lookup_node(link.path)
      response = Rack::Response.new
      
      attributes = request.env.fetch(VARIABLES_KEY, {}).to_hash
      
      node.process!(request, response, attributes)
      
      return response.finish
    elsif redirect_uri = link[:uri]
      return [307, {HTTP::LOCATION => redirect_uri}, []]
    end
  end
  
  return @app.call(env)
end

#fetch_xml(path) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/utopia/content.rb', line 58

def fetch_xml(path)
  if @templates
    @templates.fetch_or_store(path.to_s) do
      Trenni::Template.load(path)
    end
  else
    Trenni::Template.load(path)
  end
end

#freezeObject



49
50
51
52
53
54
# File 'lib/utopia/content.rb', line 49

def freeze
  @root.freeze
  @tags.freeze
  
  super
end

#lookup_node(request_path) ⇒ Object

The request_path is an absolute uri path, e.g. /foo/bar. If an xnode file exists on disk for this exact path, it is instantiated, otherwise nil.



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/utopia/content.rb', line 106

def lookup_node(request_path)
  name = request_path.last
  name_xnode = name.to_s + XNODE_EXTENSION

  node_path = File.join(@root, request_path.dirname.components, name_xnode)

  if File.exist? node_path
    return Node.new(self, request_path.dirname + name, request_path, node_path)
  end

  return nil
end

#lookup_tag(name, parent_path) ⇒ Object

Look up a named tag such as <entry />



69
70
71
72
73
74
75
76
77
78
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
# File 'lib/utopia/content.rb', line 69

def lookup_tag(name, parent_path)
  if @tags.key? name
    return @tags[name]
  end
  
  if String === name && name.index('/')
    name = Path.create(name)
  end
  
  if Path === name
    name = parent_path + name
    name_path = name.components.dup
    name_path[-1] += XNODE_EXTENSION
  else
    name_path = name + XNODE_EXTENSION
  end

  parent_path.ascend do |dir|
    tag_path = File.join(root, dir.components, name_path)

    if File.exist? tag_path
      return Node.new(self, dir + name, parent_path + name, tag_path)
    end

    if String === name_path
      tag_path = File.join(root, dir.components, '_' + name_path)

      if File.exist? tag_path
        return Node.new(self, dir + name, parent_path + name, tag_path)
      end
    end
  end
  
  return nil
end