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/markup.rb,
lib/utopia/content/response.rb,
lib/utopia/content/transaction.rb

Defined Under Namespace

Classes: Link, Links, MarkupParser, Node, Response, SymbolicHash, Tag, Transaction, UnbalancedTagError

Constant Summary collapse

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

Compatibility with older versions of rack:

'Expires'.freeze
CACHE_CONTROL =
'Cache-Control'.freeze
CONTENT_TYPE =
'Content-Type'.freeze
DEFERRED_TAG_NAME =
"deferred".freeze
CONTENT_TAG_NAME =
"content".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

#root ⇒ Object (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



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/utopia/content.rb', line 130

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)
			attributes = request.env.fetch(VARIABLES_KEY, {}).to_hash
			
			return node.process!(request, attributes)
		elsif redirect_uri = link[:uri]
			return [307, {HTTP::LOCATION => redirect_uri}, []]
		end
	end
	
	return @app.call(env)
end

#fetch_template(path) ⇒ Object



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

def fetch_template(path)
	if @template_cache
		@template_cache.fetch_or_store(path.to_s) do
			Trenni::MarkupTemplate.load_file(path)
		end
	else
		Trenni::MarkupTemplate.load_file(path)
	end
end

#freeze ⇒ Object



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.



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/utopia/content.rb', line 117

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



108
109
110
111
112
113
114
# File 'lib/utopia/content.rb', line 108

def lookup_tag(name, parent_path)
	if @tags.key? name
		return @tags[name]
	end
	
	return fetch_tag(name, parent_path)
end