Class: MemoRack::MemoApp

Inherits:
Core
  • Object
show all
Defined in:
lib/memorack/memoapp.rb

Constant Summary

Constants inherited from Core

Core::DEFAULT_APP_OPTIONS, Core::DEFAULT_LOCALS, Core::DEFAULT_OPTIONS, Core::DEFAULT_TEMPLATE_OPTIONS

Instance Attribute Summary

Attributes inherited from Core

#options_chain, #root, #suffix, #themes

Instance Method Summary collapse

Methods inherited from Core

#add_config_chain, app, #collect_formats, #content_name, #contents, #css_exts, #default_locals, #embed_macro, #embed_macro_for_array, #enable_exts, #extnames, #file_search, #folder, #load_plugin, #load_plugins, #pages, #plugins_folders, #read_config, #read_data, #render, #render_content, #render_css, #render_menu, #render_page, #render_with_mustache, #require_plugin, #split_extname, template, template_method, #theme_path, #to_sym_keys, #update_locale, #use_engine, #value_to_locals

Constructor Details

#initialize(app, options = {}) ⇒ MemoApp

Returns a new instance of MemoApp.



14
15
16
17
18
19
20
21
22
# File 'lib/memorack/memoapp.rb', line 14

def initialize(app, options={})
	super(options)

	@app = app
	define_statics(@root, *@themes)

	# ファイル監視を行う
	watcher(@root, @directory_watcher) if @directory_watcher
end

Instance Method Details

#call(env) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/memorack/memoapp.rb', line 24

def call(env)
	content_type = 'text/html'

	path_info = unescape_path_info(env)

	# ロケールの更新
	update_locale(env)

	case path_info
	when '/'
		content = render_with_mustache :index, :markdown
	when /\.css$/
		result = pass(env, @statics)
		return result unless result.first == 404

		begin
			content_type = 'text/css'
			content = render_css(path_info)
		rescue Errno::ENOENT => e
			return error(env, 404)
		end
	else
		locals = {env: env, path_info: path_info}
		content ||= render_content(path_info, locals)
		content ||= render_page(path_info, locals)
	end

	return [200, {'Content-Type' => content_type}, [content.to_s]] if content

	pass(env) { |env, code|
		error(env, code)
	} 
end

#define_statics(*args) ⇒ Object

静的ファイルの参照先を定義する



59
60
61
62
63
# File 'lib/memorack/memoapp.rb', line 59

def define_statics(*args)
	@statics = [] unless @statics

	@statics |= args.collect { |root| Rack::File.new(root) }
end

#error(env, code, body = nil, content_type = 'text/plain; charset=utf-8') ⇒ Object

エラー



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/memorack/memoapp.rb', line 92

def error(env, code, body = nil, content_type = 'text/plain; charset=utf-8')
	path_info = unescape_path_info(env)

	if body
		body = [body.to_s, path_info] unless body.kind_of?(Array)
	else
		fullpath = file_search("/#{code}", {views: @themes})
		ext = split_extname(fullpath)[1]
		locals = {env: env, path_info: path_info, page: {name: "Error #{code}"}}

		if ext && Tilt.registered?(ext)
			template = Pathname.new(fullpath)
		else
			template = "Error #{code}: #{path_info}"
			ext = nil
		end

		content = render_with_mustache template, ext, {mustache: 'error.html'}, locals

		if content
			content_type = 'text/html'
			body = [content.to_s]
		else
			body = ["Error #{code}: ", path_info]
		end
	end

	[code, {'Content-Type' => content_type, }, body]
end

#pass(env, apps = @statics + [@app]) ⇒ Object

次のアプリにパスする



78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/memorack/memoapp.rb', line 78

def pass(env, apps = @statics + [@app])
	apps.each { |app|
		next unless app

		result =  app.call(env)
		return result unless result.first == 404
	}

	return yield(env, 404) if block_given?

	error(env, 404, 'File not found: ')
end

#redirect(url, code = 301) ⇒ Object

リダイレクト



72
73
74
75
# File 'lib/memorack/memoapp.rb', line 72

def redirect(url, code = 301)
	# 301 = 恒久的, 302 = 一時的, 303, 410
	[code, {'Content-Type' => 'text/html', 'Location' => url}, ['Redirect: ', url]]
end

#unescape_path_info(env) ⇒ Object

PATH_INFO を unescape して取出す



66
67
68
69
# File 'lib/memorack/memoapp.rb', line 66

def unescape_path_info(env)
	path_info = URI.unescape(env['PATH_INFO'])
	path_info.force_encoding('UTF-8')
end

#watcher(path = '.', interval = 1.0) ⇒ Object

ファイル監視を行う



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/memorack/memoapp.rb', line 123

def watcher(path = '.', interval = 1.0)
	require 'directory_watcher'

	interval = 1.0 if interval == true # 旧バージョンとの互換性のため

	dw = DirectoryWatcher.new path, :pre_load => true
	dw.interval = interval
	dw.stable = 2
	dw.glob = '**/*'
	dw.add_observer { |*args|
		t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
		puts "[#{t}] regeneration: #{args.size} files changed"

		@menu = nil
	}

	dw.start
end