nesta-plugin-admin 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ require 'sinatra'
2
+ require "nesta-plugin-admin/version"
3
+
4
+ Nesta::Plugin.register(__FILE__)
5
+
@@ -0,0 +1,253 @@
1
+ require 'fileutils'
2
+ module Nesta
3
+ module Plugin
4
+ module Admin
5
+ module Helpers
6
+ ########################################################################
7
+ # Simple Authentication Helpers
8
+ ########################################################################
9
+
10
+ # throw [:halt] on failure
11
+ def protected!
12
+ unless authorized?
13
+ response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
14
+ throw(:halt, [401, "Not authorized\n"])
15
+ end
16
+ end
17
+
18
+ # Check [Rack::Auth::Basic::Requst] for valid username
19
+ # and password against [Nesta::Config.username] and
20
+ # [Nesta::Config.password] set in config/config.yml
21
+ #
22
+ # @return [Boolean]
23
+ def authorized?
24
+ @auth ||= Rack::Auth::Basic::Request.new(request.env)
25
+ @auth.provided? && @auth.basic? && @auth.credentials && @auth.credentials == [Nesta::Config.username, Nesta::Config.password]
26
+ end
27
+
28
+ ########################################################################
29
+ # View Helpers
30
+ ########################################################################
31
+
32
+ # Taken from Nesta helpers, as they weren't available in the
33
+ # Admin because it's a middleware.
34
+ #
35
+ # @return [String] clean path for linking
36
+ def path_to(page_path, absolute = false)
37
+ host = ''
38
+ if absolute
39
+ host << "http#{'s' if request.ssl?}://"
40
+ if (request.env.include?("HTTP_X_FORWARDED_HOST") or
41
+ request.port != (request.ssl? ? 443 : 80))
42
+ host << request.host_with_port
43
+ else
44
+ host << request.host
45
+ end
46
+ end
47
+ uri_parts = [host]
48
+ uri_parts << request.script_name.to_s if request.script_name
49
+ uri_parts << page_path
50
+ File.join(uri_parts)
51
+ end
52
+
53
+ # Taken from Nesta helpers, as they weren't available in the
54
+ # Admin because it's a middleware.
55
+ #
56
+ # @return [String] clean path for stylesheets
57
+ def local_stylesheet_link_tag(name)
58
+ pattern = File.expand_path("views/#{name}.s{a,c}ss", Nesta::App.root)
59
+ if Dir.glob(pattern).size > 0
60
+ haml_tag :link, :href => path_to("/css/#{name}.css"), :rel => "stylesheet"
61
+ end
62
+ end
63
+
64
+ # Override standard haml call to include special view location for
65
+ # admin templates. I know, I know, this will break templating for admin
66
+ # views, but it's a small price to pay.
67
+ #
68
+ # TODO: figure out a way to somehow inject these in to standard view path
69
+ #
70
+ # @return [String] rendered html from haml
71
+ def admin_haml template, options={}
72
+ haml template, { views: File.expand_path('../../views', File.dirname(__FILE__)), layout: :layout }.merge(options)
73
+ end
74
+ end
75
+
76
+ ########################################################################
77
+ # Core Modules
78
+ ########################################################################
79
+
80
+ # Write updates to disk:
81
+ # - strip begining slash
82
+ # - clean dirty chars
83
+ # - create directory if missing
84
+ #
85
+ # @param path [String] path to file being written
86
+ # @param params [String] params recieved by Sinatra from HTTP GET
87
+ def self.write path, params
88
+ path.gsub!(/^\//, '')
89
+ path.gsub!(/[\`\!\$\%\^\&\*\(\)\+\=\[\]\{\}\|\:\;\'\"\?\,\<\>\\]/, "-")
90
+ path = File.expand_path("#{path}.#{params["format"]}", File.join( Nesta::Env.root, Nesta::Config.page_path ))
91
+ FileUtils.mkdir_p(File.dirname(path)) unless File.directory?(File.dirname(path))
92
+ File.open(path, 'w') { |file| file.puts params["contents"] }
93
+ end
94
+
95
+ # Delete file from disk.
96
+ #
97
+ # @param path [String] path to file being deleted
98
+ def self.delete path
99
+ File.delete self.full_path(path).first
100
+ end
101
+
102
+ # Load file in raw form, existing Nesta load methods strip out metadata.
103
+ #
104
+ # @param path [String] path to file being loaded
105
+ def self.load_raw path
106
+ path, format = self.full_path(path)
107
+ [File.open(path, 'r').read, format]
108
+ end
109
+
110
+ # Load menu.txt file.
111
+ def self.load_menu
112
+ File.open(self.menu_path, 'r').read
113
+ end
114
+
115
+ # Write menu.txt file.
116
+ #
117
+ # @param params [String] params recieved by Sinatra from HTTP GET
118
+ def self.write_menu params
119
+ File.open(self.menu_path, 'w') { |file| file.puts params["contents"] }
120
+ end
121
+
122
+ # Build menu.txt path.
123
+ #
124
+ # @param path [String] path to menu.txt
125
+ def self.menu_path
126
+ File.expand_path("menu.txt", File.join( Nesta::Env.root, Nesta::Config.content_path ))
127
+ end
128
+
129
+ # Full path to page, technically a helper but here for plugins that use
130
+ # this plugin -- of which I may write.
131
+ #
132
+ # @param path [String] path to menu.txt
133
+ def self.full_path path
134
+ path.gsub!(/^\//, '')
135
+ Nesta::FileModel::FORMATS.each do |format|
136
+ [path, File.join(path, 'index')].each do |basename|
137
+ filename = File.expand_path("#{basename}.#{format}", File.join( Nesta::Env.root, Nesta::Config.page_path ))
138
+ if File.exist?(filename)
139
+ return [filename, format]
140
+ end
141
+ end
142
+ end
143
+ raise Sinatra::NotFound
144
+ end
145
+
146
+ # Expire all caches (both local and Sinatra::Cache).
147
+ def self.expire_caches
148
+ Nesta::Page.purge_cache
149
+ if Nesta::Config.cache
150
+ Nesta::Page.find_all.each do |page|
151
+ Sinatra::Cache.cache_expire(page.abspath)
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ # Adding username and password to settings list.
159
+ class Config
160
+ @settings += %w[ username password ]
161
+ end
162
+
163
+ class AdminScreens < Sinatra::Base
164
+ register Sinatra::Cache
165
+ set :cache_enabled, false
166
+
167
+ helpers Nesta::Plugin::Admin::Helpers
168
+
169
+ before '/admin*' do
170
+ protected!
171
+ headers['Cache-Control'] = 'no-cache'
172
+ end
173
+
174
+ after '/admin*', :method => :post do
175
+ Nesta::Plugin::Admin.expire_caches
176
+ end
177
+
178
+ after '/admin/*/delete' do
179
+ Nesta::Plugin::Admin.expire_caches
180
+ end
181
+
182
+ get '/admin/new' do
183
+ @action = "New Page"
184
+ @path, @content = nil
185
+ admin_haml :edit
186
+ end
187
+
188
+ post '/admin/new' do
189
+ response['Cache-Control'] = 'no-cache'
190
+ Nesta::Plugin::Admin.write(params["path"], params)
191
+ redirect "/"+params["path"]
192
+ end
193
+
194
+ get '/admin/*/delete' do
195
+ Nesta::Plugin::Admin.delete(File.join(params[:splat]))
196
+ redirect '/admin'
197
+ end
198
+
199
+ get '/admin' do
200
+ @action = "Pages"
201
+ @pages = Nesta::Page.find_all.sort { |a,b| a.title_for_admin <=> b.title_for_admin }
202
+ admin_haml :admin
203
+ end
204
+
205
+ get '/admin/menu' do
206
+ @action = "Edit Menu"
207
+ @path = "menu"
208
+ @format = nil
209
+ @content = Nesta::Plugin::Admin.load_menu
210
+ admin_haml :edit
211
+ end
212
+
213
+ post '/admin/menu' do
214
+ Nesta::Plugin::Admin.write_menu params
215
+ redirect "/"
216
+ end
217
+
218
+ post '/admin/*' do
219
+ path = File.join(params[:splat])
220
+ Nesta::Plugin::Admin.write(path, params)
221
+ redirect "/"+path
222
+ end
223
+
224
+ get '/admin/*' do
225
+ @action = "Edit Template"
226
+ @path = File.join(params[:splat])
227
+ @content, @format = Nesta::Plugin::Admin.load_raw @path
228
+ admin_haml :edit
229
+ end
230
+
231
+ end
232
+
233
+ # Adding special handlers for admin page. These may be better
234
+ # as helpers, but seemed to fix here within the context of
235
+ # the Page module.
236
+ class Page
237
+ attr_reader :format
238
+ def title_for_admin
239
+ t = self.title.gsub(" - #{Nesta::Config.title}","")
240
+ return (t.empty? ? 'Home' : t)
241
+ end
242
+ def path_for_admin
243
+ return (self.path.empty? ? 'index' : self.path)
244
+ end
245
+ end
246
+
247
+ # Include helpers and use AdminScreens.
248
+ class App
249
+ helpers Nesta::Plugin::Admin::Helpers
250
+ use AdminScreens
251
+ end
252
+ end
253
+
@@ -0,0 +1,7 @@
1
+ module Nesta
2
+ module Plugin
3
+ module Admin
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nesta-plugin-admin/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Joshua Mervine"]
6
+ gem.email = ["joshua@mervine.net"]
7
+ gem.description = %q{An admin interface for Nesta.}
8
+ gem.summary = %q{An admin interface for Nesta focusing around adding, removing and editing pages.}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "nesta-plugin-admin"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Nesta::Plugin::Admin::VERSION
17
+ gem.add_dependency("nesta", ">= 0.9.11")
18
+ gem.add_development_dependency("rake")
19
+ end
data/spec_helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require File.join("..", "lib", "nesta-plugin-admin")
2
+
3
+ module SpecHelpers
4
+ extend self
5
+ TEMP_DIR=File.expand_path("tmp", File.dirname(__FILE__))
6
+ def setup_project
7
+ [
8
+ "cd #{TEMP_DIR}",
9
+ "cp ../Gemfile.spec Gemfile",
10
+ "bundle exec install --path ./vendor/bundle",
11
+ "bundle exec nesta new spec_site",
12
+ ""
13
+ ].join(" && ")
14
+ end
15
+ def breakdown_project
16
+
17
+ end
18
+ end
data/views/admin.haml ADDED
@@ -0,0 +1,14 @@
1
+ #admin_links
2
+ %a{:href=>"/admin/new"}new page
3
+ %br
4
+ %a{:href=>"/admin/menu"}edit menu
5
+ #admin_content
6
+ - @pages.each do |page|
7
+ %section(role="main")<
8
+ %a{:href=>"/admin/#{page.path_for_admin}"}>edit
9
+ &nbsp;|&nbsp;
10
+ %a{:href=>"/admin/#{page.path_for_admin}/delete"}<delete
11
+ &nbsp;&nbsp;&nbsp;
12
+ ="#{page.title_for_admin} (#{page.path_for_admin}.#{page.format})"
13
+ %br
14
+
data/views/edit.haml ADDED
@@ -0,0 +1,19 @@
1
+ %form{:action=>"/admin/#{@path||'new'}", :method=>"post"}
2
+ #admin_content
3
+ - unless @path == "menu"
4
+ %label Page Path:
5
+ %br
6
+ %input.path{:type=>'text',:name=>'path',:value=>@path||''}>
7
+ %select{:name=>"format"}
8
+ - Nesta::FileModel::FORMATS.each do |format|
9
+ %option{:value=>format, :selected=>(@format==format)}= format
10
+ %br
11
+ %small (ex: article-name)
12
+ #contents
13
+ - unless @path == "menu"
14
+ %label Page Body:
15
+ %br
16
+ %textarea{:name=>'contents'}= @content||''
17
+ #buttons
18
+ %input.button{ :type => "button", "value" => "Cancel!", :onclick => "top.location.href='/admin';" }
19
+ %input.button{ :type => "submit", "value" => "Save!" }
data/views/footer.haml ADDED
@@ -0,0 +1,5 @@
1
+ %footer.branding
2
+ %p
3
+ Powered by Nesta, a
4
+ = succeed "." do
5
+ %a(href="http://nestacms.com") Ruby CMS
data/views/header.haml ADDED
@@ -0,0 +1,4 @@
1
+ %header(role="banner")
2
+ %hgroup
3
+ %h1 Admin
4
+ %h2= @action
data/views/layout.haml ADDED
@@ -0,0 +1,76 @@
1
+ <!DOCTYPE html>
2
+ %html(lang="en")
3
+ %head
4
+ %title Admin
5
+ <!--[if ! lte IE 6]><!-->
6
+ %link(href="#{path_to('/css/master.css')}" media="screen" rel="stylesheet")
7
+ <!--<![endif]-->
8
+ /[if lte IE 6]
9
+ %link(rel="stylesheet" href="http://universal-ie6-css.googlecode.com/files/ie6.1.1.css" media="screen, projection")
10
+ /[if lt IE 9]
11
+ %script(src="//html5shim.googlecode.com/svn/trunk/html5.js")
12
+ - local_stylesheet_link_tag('local')
13
+ :css
14
+ #admin_links {
15
+ float:right;
16
+ }
17
+ #admin_content {
18
+ width: 100%;
19
+ }
20
+ textarea {
21
+ font-face: monospace;
22
+ font-size: 10pt;
23
+ height: 500px;
24
+ padding: 3px;
25
+ width: 600px;
26
+ border: 1px solid #999;
27
+ border: inset 1px solid #333;
28
+ -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
29
+ -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
30
+ box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
31
+ }
32
+ input.path {
33
+ font-face: monospace;
34
+ font-size: 12pt;
35
+ height: 25px;
36
+ width: 500px;
37
+ padding: 3px;
38
+ border: 1px solid #999;
39
+ border: inset 1px solid #333;
40
+ -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
41
+ -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
42
+ box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
43
+ }
44
+ select {
45
+ font-face: monospace;
46
+ font-size: 12pt;
47
+ height: 25px;
48
+ padding: 8px;
49
+ margin: 0 0 0 5px;
50
+ position: relative;
51
+ border: 1px solid #999;
52
+ border: inset 1px solid #333;
53
+ -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
54
+ -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
55
+ box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
56
+ }
57
+ input.button {
58
+ font-size: 12pt;
59
+ width: 150px;
60
+ height: 30px;
61
+ background-color: #eee;
62
+ border: 1px solid #999;
63
+ border: inset 1px solid #333;
64
+ -webkit-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
65
+ -moz-box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
66
+ box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.3);
67
+ }
68
+ %body
69
+ #container
70
+ = admin_haml :header, :layout => false
71
+ %hr
72
+ %br
73
+ = yield
74
+ %br
75
+ %br
76
+ = admin_haml :footer, :layout => false
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nesta-plugin-admin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joshua Mervine
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nesta
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.9.11
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 0.9.11
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: An admin interface for Nesta.
47
+ email:
48
+ - joshua@mervine.net
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE
56
+ - README.md
57
+ - Rakefile
58
+ - doc/Nesta.html
59
+ - doc/Nesta/AdminScreens.html
60
+ - doc/Nesta/App.html
61
+ - doc/Nesta/Config.html
62
+ - doc/Nesta/Page.html
63
+ - doc/Nesta/Plugin.html
64
+ - doc/Nesta/Plugin/Admin.html
65
+ - doc/Nesta/Plugin/Admin/Helpers.html
66
+ - doc/_index.html
67
+ - doc/class_list.html
68
+ - doc/css/common.css
69
+ - doc/css/full_list.css
70
+ - doc/css/style.css
71
+ - doc/file.README.html
72
+ - doc/file_list.html
73
+ - doc/frames.html
74
+ - doc/index.html
75
+ - doc/js/app.js
76
+ - doc/js/full_list.js
77
+ - doc/js/jquery.js
78
+ - doc/method_list.html
79
+ - doc/top-level-namespace.html
80
+ - lib/nesta-plugin-admin.rb
81
+ - lib/nesta-plugin-admin/init.rb
82
+ - lib/nesta-plugin-admin/version.rb
83
+ - nesta-plugin-admin.gemspec
84
+ - spec_helper.rb
85
+ - views/admin.haml
86
+ - views/edit.haml
87
+ - views/footer.haml
88
+ - views/header.haml
89
+ - views/layout.haml
90
+ homepage: ''
91
+ licenses: []
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ none: false
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: An admin interface for Nesta focusing around adding, removing and editing
114
+ pages.
115
+ test_files: []
116
+ has_rdoc: