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
48
49
# 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]
		@template_cache = Concurrent::Map.new
	else
		@template_cache = nil
	end
	
	@tags = options.fetch(:tags, {})
	
	self.freeze
end

Instance Attribute Details

#rootObject (readonly)

Returns the value of attribute root.



58
59
60
# File 'lib/utopia/content.rb', line 58

def root
  @root
end

Instance Method Details

#call(env) ⇒ Object



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
151
152
# File 'lib/utopia/content.rb', line 121

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



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

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

#freezeObject



51
52
53
54
55
56
# File 'lib/utopia/content.rb', line 51

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.



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

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 />



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
104
105
# File 'lib/utopia/content.rb', line 71

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