plezi 0.12.22 → 0.14.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/LICENSE.txt +17 -18
- data/README.md +54 -698
- data/Rakefile +7 -4
- data/bin/config.ru +22 -0
- data/{test → bin}/console +4 -6
- data/bin/hello_world +52 -0
- data/bin/setup +8 -0
- data/exe/plezi +145 -0
- data/lib/plezi.rb +24 -137
- data/lib/plezi/activation.rb +28 -0
- data/lib/plezi/api.rb +62 -0
- data/lib/plezi/controller/controller.rb +259 -0
- data/lib/plezi/controller/controller_class.rb +176 -0
- data/lib/plezi/controller/cookies.rb +40 -0
- data/lib/plezi/helpers.rb +60 -0
- data/lib/plezi/rake.rb +2 -24
- data/lib/plezi/render/erb.rb +34 -0
- data/lib/plezi/render/has_cache.rb +36 -0
- data/lib/plezi/render/markdown.rb +63 -0
- data/lib/plezi/render/render.rb +49 -0
- data/lib/plezi/render/sass.rb +55 -0
- data/lib/plezi/render/slim.rb +33 -0
- data/lib/plezi/router/adclient.rb +23 -0
- data/lib/plezi/router/assets.rb +67 -0
- data/lib/plezi/router/errors.rb +29 -0
- data/lib/plezi/router/route.rb +112 -0
- data/lib/plezi/router/router.rb +120 -0
- data/lib/plezi/version.rb +1 -1
- data/lib/plezi/websockets/message_dispatch.rb +91 -0
- data/lib/plezi/websockets/redis.rb +55 -0
- data/plezi.gemspec +25 -16
- data/resources/404.erb +5 -4
- data/resources/500.erb +5 -4
- data/resources/{500.html → 503.html} +8 -9
- data/resources/client.js +253 -0
- data/resources/config.ru +5 -36
- data/resources/ctrlr.rb +34 -0
- data/resources/gemfile +4 -0
- data/resources/mini_app.rb +28 -82
- data/resources/mini_exec +7 -0
- data/resources/mini_welcome_page.html +0 -0
- data/resources/procfile +3 -0
- data/resources/rakefile +4 -8
- data/resources/routes.rb +9 -26
- data/resources/{websockets.js → simple-client.js} +3 -3
- metadata +60 -85
- data/bin/plezi +0 -104
- data/docs/async_helpers.md +0 -245
- data/docs/controllers.md +0 -27
- data/docs/logging.md +0 -49
- data/docs/routes.md +0 -209
- data/docs/websockets.md +0 -213
- data/lib/plezi/builders/ac_model.rb +0 -59
- data/lib/plezi/builders/app_builder.rb +0 -137
- data/lib/plezi/builders/builder.rb +0 -43
- data/lib/plezi/builders/form_builder.rb +0 -27
- data/lib/plezi/common/api.rb +0 -92
- data/lib/plezi/common/cache.rb +0 -122
- data/lib/plezi/common/defer.rb +0 -21
- data/lib/plezi/common/dsl.rb +0 -94
- data/lib/plezi/common/redis.rb +0 -65
- data/lib/plezi/common/renderer.rb +0 -141
- data/lib/plezi/common/settings.rb +0 -52
- data/lib/plezi/handlers/controller_core.rb +0 -106
- data/lib/plezi/handlers/controller_magic.rb +0 -284
- data/lib/plezi/handlers/http_router.rb +0 -205
- data/lib/plezi/handlers/placebo.rb +0 -112
- data/lib/plezi/handlers/route.rb +0 -216
- data/lib/plezi/handlers/session.rb +0 -109
- data/lib/plezi/handlers/stubs.rb +0 -156
- data/lib/plezi/handlers/ws_identity.rb +0 -253
- data/lib/plezi/handlers/ws_object.rb +0 -308
- data/lib/plezi/helpers/http_sender.rb +0 -84
- data/lib/plezi/helpers/magic_helpers.rb +0 -104
- data/lib/plezi/helpers/mime_types.rb +0 -1995
- data/lib/plezi/oauth.rb +0 -5
- data/lib/plezi/oauth/auth_controller.rb +0 -229
- data/logo/dark.png +0 -0
- data/logo/light.png +0 -0
- data/logo/sign.png +0 -0
- data/resources/404.haml +0 -121
- data/resources/404.html +0 -124
- data/resources/404.slim +0 -120
- data/resources/500.haml +0 -120
- data/resources/500.slim +0 -120
- data/resources/Gemfile +0 -86
- data/resources/code.rb +0 -8
- data/resources/controller.rb +0 -142
- data/resources/database.yml +0 -33
- data/resources/db_ac_config.rb +0 -59
- data/resources/db_dm_config.rb +0 -51
- data/resources/db_sequel_config.rb +0 -33
- data/resources/en.yml +0 -204
- data/resources/haml_config.rb +0 -6
- data/resources/i18n_config.rb +0 -14
- data/resources/initialize.rb +0 -49
- data/resources/mini_exec.rb +0 -7
- data/resources/oauth_config.rb +0 -24
- data/resources/plezi_client.js +0 -198
- data/resources/plezi_websockets.html +0 -47
- data/resources/redis_config.rb +0 -42
- data/resources/slim_config.rb +0 -11
- data/resources/welcome_page.html +0 -272
- data/test/dispatch +0 -58
- data/test/hello_world +0 -13
- data/test/plezi_tests.rb +0 -581
data/lib/plezi/oauth.rb
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
module Plezi
|
6
|
-
|
7
|
-
#########################################
|
8
|
-
# This is a social Authentication Controller for OAuth2 services.
|
9
|
-
# This controller allows you to easily deploy Facebook Login, Google Login and any other OAuth2 complient login service.
|
10
|
-
#
|
11
|
-
# To include this controller in your application, you need to require it using:
|
12
|
-
#
|
13
|
-
# require 'plezi/oauth'
|
14
|
-
#
|
15
|
-
# It is possible to manualy register any OAuth 2.0 authentication service using the `register_service` method:
|
16
|
-
#
|
17
|
-
# register_service(:foo,
|
18
|
-
# app_id: 'registered app id / client id',
|
19
|
-
# app_secret: 'registered app secret / client secret',
|
20
|
-
# auth_url: "https://foo.bar.com/o/oauth2/auth",
|
21
|
-
# token_url: "https://foo.bar.com/oauth2/v3/token",
|
22
|
-
# profile_url: "https://foo.bar/oauth2/v1/userinfo",
|
23
|
-
# scope: "profile email")
|
24
|
-
#
|
25
|
-
# The `.register_service` method will be automatically called for the following login services:
|
26
|
-
#
|
27
|
-
# - Facebook authentication using the Graph API, v. 2.3 - [see Facebook documentation](https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3).
|
28
|
-
# - Google authentication using the OAuth 2.0 API - [see Google documentation](https://developers.google.com/identity/protocols/OAuth2WebServer).
|
29
|
-
#
|
30
|
-
# To enjoy autorgistration for Facebook or Google, make sure the following environment variables are set:
|
31
|
-
# ENV['FB_APP_ID'] = {facebook_app_id}
|
32
|
-
# ENV['FB_APP_SECRET'] = {facebook_app_secret}
|
33
|
-
# ENV['GOOGLE_APP_ID'] = {google_app_id}
|
34
|
-
# ENV['GOOGLE_APP_SECRET'] = {google_app_secret}
|
35
|
-
#
|
36
|
-
# To add the OAuth routes to the routes, use the following short-cut method (add it to the `routes.rb`) file:
|
37
|
-
#
|
38
|
-
# create_auth_shared_route do |service, remote_user_id, email, full_remote_response|
|
39
|
-
# # perform any specific app authentication logic such as saving the info.
|
40
|
-
# # return the current user or false if the callback is called with an authentication failure.
|
41
|
-
# end
|
42
|
-
#
|
43
|
-
# \* Notice that, as always, route placement order effects behavior, so that routes are checked according to order of creation.
|
44
|
-
#
|
45
|
-
# The `create_auth_shared_route` method is a shortcut taht calls the `#shared_route` method with the relevant arguments and sets the OAuth2Ctrl callback.
|
46
|
-
#
|
47
|
-
# Use the following links for social authentication:
|
48
|
-
#
|
49
|
-
# - Facebook: "/auth/facebook"
|
50
|
-
# - Google: "/auth/google"
|
51
|
-
# - foo_service: "/auth/foo_service"
|
52
|
-
#
|
53
|
-
# You can control the page to which the user will return once authentication is complete
|
54
|
-
# (even when authentication fails) by setting the "redirect_after" parameter into the GET request in the url. for example:
|
55
|
-
#
|
56
|
-
# - Google: "/auth/google?redirect_after=/foo/bar"
|
57
|
-
class OAuth2Ctrl
|
58
|
-
|
59
|
-
# Sets (or gets) the global callback to be called after authentication is attempeted.
|
60
|
-
#
|
61
|
-
# Accepts a block that will be called with the following parameters:
|
62
|
-
# service_name:: the name of the service. i.e. :facebook, :google, etc'.
|
63
|
-
# service_token:: the authentication token returned by the service. This token should be stored for future access
|
64
|
-
# remote_user_id:: service's user id.
|
65
|
-
# remote_user_email:: user's primamry email, as (and if) registed with the service.
|
66
|
-
# remote_response:: a Hash with the complete user data response (including email and id).
|
67
|
-
#
|
68
|
-
# If the authentication fails for the service, the block will be called with the following values `auth_callback.call(nil, ni, {server: :responce, might_be: :empty})`
|
69
|
-
#
|
70
|
-
# The block will be run in the context of the controller and all the controller's methods will be available to it.
|
71
|
-
#
|
72
|
-
# i.e.:
|
73
|
-
# OAuth2Ctrl.auth_callback |service, service_token, id, email, full_res| PL.info "OAuth got: #{full_res.to_s}"; cookies["#{service}_pl_auth_token".to_sym], cookies["#{service}_user_id".to_sym], cookies["#{service}_user_email".to_sym] = service_token, id, email }
|
74
|
-
#
|
75
|
-
# defaults to the example above, which isn't a very sercure behavior, but allows for easy testing.
|
76
|
-
def self.auth_callback &block
|
77
|
-
block_given? ? (@@auth_callback = block) : ( @@auth_callback ||= (Proc.new {|service, service_token, id, email, res| Plezi.info "deafult callback called for #{service}, with response: #{res.to_s}"; session["#{service}_pl_auth_token"], session["#{service}_user_id"], session["#{service}_user_email"] = service_token, id, email}) )
|
78
|
-
end
|
79
|
-
|
80
|
-
|
81
|
-
# Stores the registered services library
|
82
|
-
SERVICES = {}
|
83
|
-
|
84
|
-
# This method registers a social login service that conforms to the OAuth2 model.
|
85
|
-
#
|
86
|
-
# Accepts the following required parameters:
|
87
|
-
# service_name:: a Symbol naming the service. i.e. :facebook or :google .
|
88
|
-
# options:: a Hash of options, some of which are required.
|
89
|
-
#
|
90
|
-
# The options are:
|
91
|
-
# app_id:: Required. The aplication's unique ID (sometimes called `client_id`) registered with the service. i.e. ENV [FB_APP_ID] (storing these in environment variables is safer then hardcoding them)
|
92
|
-
# app_secret:: Required. The aplication's unique secret registered with the service (sometimes called `client_secret`).
|
93
|
-
# auth_url:: Required. The authentication URL. This is the url to which the user is redirected. i.e.: "https://www.facebook.com/dialog/oauth"
|
94
|
-
# token_url:: Required. The token request URL. This is the url used to switch the single-use code into a persistant authentication token. i.e.: "https://www.googleapis.com/oauth2/v3/token"
|
95
|
-
# profile_url:: Required. The URL used to ask the service for the user's profile (the service's API url). i.e.: "https://graph.facebook.com/v2.3/me"
|
96
|
-
# scope:: a String representing the scope requested. i.e. 'email profile'.
|
97
|
-
#
|
98
|
-
# There will be an attempt to automatically register Facebook and Google login services under these conditions:
|
99
|
-
#
|
100
|
-
# * For Facebook: Both ENV ['FB_APP_ID'] && ENV ['FB_APP_SECRET'] have been defined.
|
101
|
-
# * For Google: Both ENV ['GOOGLE_APP_ID'] && ENV ['GOOGLE_APP_SECRET'] have been defined.
|
102
|
-
#
|
103
|
-
#
|
104
|
-
# The auto registration uses the following urls (updated to June 5, 2015):
|
105
|
-
#
|
106
|
-
# * facebook auth_url: "https://www.facebook.com/dialog/oauth"
|
107
|
-
# * facebook token_url: "https://graph.facebook.com/v2.3/oauth/access_token"
|
108
|
-
# * facebook profile_url: "https://graph.facebook.com/v2.3/me"
|
109
|
-
# * google auth_url: "https://accounts.google.com/o/oauth2/auth"
|
110
|
-
# * google token_url: "https://www.googleapis.com/oauth2/v3/token"
|
111
|
-
# * google profile_url: "https://www.googleapis.com/plus/v1/people/me"
|
112
|
-
#
|
113
|
-
# to change the default scope or url's for Facebook or Google, simpley re-register the service using this method.
|
114
|
-
#
|
115
|
-
def self.register_service service_name, options
|
116
|
-
raise "Cannot register service, missing required information." unless service_name && options[:auth_url] && options[:token_url] && options[:profile_url] && options[:app_id] && options[:app_secret]
|
117
|
-
# for google, scope is space delimited. for facebook it's comma delimited
|
118
|
-
options[:scope] ||= 'profile, email'
|
119
|
-
SERVICES[service_name] = options
|
120
|
-
end
|
121
|
-
|
122
|
-
# Called to manually run through the authentication logic for the requested service,
|
123
|
-
# without performing any redirections.
|
124
|
-
#
|
125
|
-
# Use this method to attempt and re-login a user using an existing login token:
|
126
|
-
#
|
127
|
-
# token = 'google_token_could_be_recieved_also_from_javascript_sdk'
|
128
|
-
# OAuth2Ctrl.auth :google, token, self
|
129
|
-
#
|
130
|
-
# The method will return false if re-login fails and it will otherwise return the callback's return value.
|
131
|
-
#
|
132
|
-
# Call this method from within a controller, passing the controller (self) to the method, like so:
|
133
|
-
#
|
134
|
-
# OAuth2Ctrl.auth :facebook, token, self
|
135
|
-
#
|
136
|
-
# This is especially effective if `auth_callback` returns the user object, as it would allow to chain
|
137
|
-
# different login methods, i.e.:
|
138
|
-
#
|
139
|
-
# @user ||= app_login || OAuth2Ctrl.auth(:facebook, fb_token, self) || OAuth2Ctrl.auth(:google, google_token, self) || ....
|
140
|
-
def self.auth service_name, service_token, controller
|
141
|
-
service = SERVICES[service_name]
|
142
|
-
return false unless service
|
143
|
-
# auth_res = controller.cookies[c_name] ? (JSON.parse URI.parse("#{service[:profile_url]}?access_token=#{controller.cookies[c_name]}").read rescue ({}) ) : {}
|
144
|
-
# controller.cookies[c_name] = nil unless auth_res['id']
|
145
|
-
# auth_res['id'] ? controller.instance_exec( service_name, auth_res['id'], auth_res['email'], auth_res, &auth_callback) : ( controller.instance_exec( service_name, nil, nil, auth_res, &auth_callback) && false)
|
146
|
-
auth_res = {}
|
147
|
-
uri = URI.parse("#{service[:profile_url]}?access_token=#{service_token}")
|
148
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
149
|
-
req = Net::HTTP::Get.new(uri)
|
150
|
-
res = http.request(req).body
|
151
|
-
auth_res = (JSON.parse res) rescue ({})
|
152
|
-
end if service_token
|
153
|
-
auth_res['id'] ? controller.instance_exec( service_name, service_token, auth_res['id'], auth_res['email'], auth_res, &auth_callback) : ( controller.instance_exec( service_name, nil, nil, nil, auth_res, &auth_callback) && false)
|
154
|
-
end
|
155
|
-
|
156
|
-
def update
|
157
|
-
service_name = params[:id].to_s.to_sym
|
158
|
-
service = SERVICES[service_name]
|
159
|
-
return false unless service
|
160
|
-
if params[:error]
|
161
|
-
instance_exec( service_name, nil, nil, nil, {}, &self.class.auth_callback)
|
162
|
-
return redirect_to(flash[:redirect_after])
|
163
|
-
end
|
164
|
-
unless params[:code]
|
165
|
-
flash[:redirect_after] = params[:redirect_after] || '/'
|
166
|
-
return redirect_to _auth_url_for(service_name)
|
167
|
-
end
|
168
|
-
uri = URI.parse service[:token_url]
|
169
|
-
service_token = nil
|
170
|
-
Net::HTTP.start(uri.host, uri.port, use_ssl: (uri.scheme == "https"), verify_mode: OpenSSL::SSL::VERIFY_NONE) do |http|
|
171
|
-
req = Net::HTTP::Post.new(uri)
|
172
|
-
req.form_data = {"client_id" => service[:app_id],
|
173
|
-
"client_secret" => service[:app_secret], "code" => params[:code] ,
|
174
|
-
"grant_type" => "authorization_code","redirect_uri" => "#{request.base_url}/auth/#{service_name.to_s}"}
|
175
|
-
res = http.request(req).body
|
176
|
-
service_token = ((JSON.parse res)['access_token'] rescue nil)
|
177
|
-
end
|
178
|
-
|
179
|
-
self.class.auth service_name, service_token, self
|
180
|
-
redirect_to(flash[:redirect_after])
|
181
|
-
end
|
182
|
-
alias :show :update
|
183
|
-
|
184
|
-
protected
|
185
|
-
|
186
|
-
# returns a url for the requested service's social login.
|
187
|
-
#
|
188
|
-
# this is used internally. Normal behavior would be to set a link to '/auth/{service_name}', where correct redirection will be automatic.
|
189
|
-
#
|
190
|
-
def _auth_url_for service_name
|
191
|
-
service = SERVICES[service_name]
|
192
|
-
return nil unless service
|
193
|
-
redirect_uri = Plezi::Base::Helpers.encode_url "#{request.base_url}/auth/#{service_name.to_s}" #response_type
|
194
|
-
return "#{service[:auth_url]}?client_id=#{service[:app_id]}&redirect_uri=#{redirect_uri}&scope=#{service[:scope]}&response_type=code"
|
195
|
-
end
|
196
|
-
|
197
|
-
register_service(:facebook, app_id: ENV['FB_APP_ID'],
|
198
|
-
app_secret: ENV['FB_APP_SECRET'],
|
199
|
-
auth_url: "https://www.facebook.com/dialog/oauth",
|
200
|
-
token_url: "https://graph.facebook.com/v2.3/oauth/access_token",
|
201
|
-
profile_url: "https://graph.facebook.com/v2.3/me",
|
202
|
-
scope: "public_profile,email") if ENV['FB_APP_ID'] && ENV['FB_APP_SECRET']
|
203
|
-
register_service(:google, app_id: ENV['GOOGLE_APP_ID'],
|
204
|
-
app_secret: ENV['GOOGLE_APP_SECRET'],
|
205
|
-
auth_url: "https://accounts.google.com/o/oauth2/auth",
|
206
|
-
token_url: "https://www.googleapis.com/oauth2/v3/token",
|
207
|
-
profile_url: "https://www.googleapis.com/oauth2/v1/userinfo",
|
208
|
-
scope: "profile email") if ENV['GOOGLE_APP_ID'] && ENV['GOOGLE_APP_SECRET']
|
209
|
-
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
# This method creates the OAuth2Ctrl route.
|
214
|
-
# This is actually a short-cut for:
|
215
|
-
#
|
216
|
-
# shared_route "auth/(:id)/(:code)" , Plezi::OAuth2Ctrl
|
217
|
-
# Plezi::OAuth2Ctrl.auth_callback = Proc.new {|service, user_id, user_email, service_response| ... }
|
218
|
-
#
|
219
|
-
# the `:id` parameter is used to identify the service (facebook, google. etc').
|
220
|
-
#
|
221
|
-
# The method accepts a block that will be used to set the authentication callback. See the Plezi::OAuth2Ctrl documentation for details.
|
222
|
-
#
|
223
|
-
# The method can be called only once and will self-destruct.
|
224
|
-
def create_auth_shared_route options = {}, &block
|
225
|
-
shared_route "auth/(:id)" , Plezi::OAuth2Ctrl
|
226
|
-
undef create_auth_shared_route
|
227
|
-
Plezi::OAuth2Ctrl.auth_callback &block if block
|
228
|
-
Plezi::OAuth2Ctrl
|
229
|
-
end
|
data/logo/dark.png
DELETED
Binary file
|
data/logo/light.png
DELETED
Binary file
|
data/logo/sign.png
DELETED
Binary file
|
data/resources/404.haml
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
!!!5
|
2
|
-
%head
|
3
|
-
:css
|
4
|
-
/*
|
5
|
-
med-blue: #44518E
|
6
|
-
dark-gray: #424A70
|
7
|
-
blue: #1B2864
|
8
|
-
light-blue: #818ECE
|
9
|
-
light-gray: #99A3CE
|
10
|
-
*/
|
11
|
-
body, html
|
12
|
-
{
|
13
|
-
background-color: #99A3CE;
|
14
|
-
padding: 0; margin: 0;
|
15
|
-
width: 100%;
|
16
|
-
font-size: 1em;
|
17
|
-
}
|
18
|
-
|
19
|
-
h1
|
20
|
-
{
|
21
|
-
font-family: 'Shadows Into Light', cursive;
|
22
|
-
background-color: #1B2864;
|
23
|
-
color: #99A3CE;
|
24
|
-
text-align: center;
|
25
|
-
border-bottom: 4px solid #424A70;
|
26
|
-
margin: 0 0 1em 0;
|
27
|
-
padding: 0.4em 0;
|
28
|
-
width: 100%;
|
29
|
-
}
|
30
|
-
h2
|
31
|
-
{
|
32
|
-
background-color: #44518E;
|
33
|
-
color: #C6CCE7;
|
34
|
-
text-align: left;
|
35
|
-
margin: 0 0 1em 0;
|
36
|
-
padding: 0.5em 5%;
|
37
|
-
border-radius: 20px 20px 0 0;
|
38
|
-
font-family: 'Architects Daughter', cursive;
|
39
|
-
border-bottom: 3px solid #424A70;
|
40
|
-
font-size: 1.2em;
|
41
|
-
}
|
42
|
-
h3
|
43
|
-
{
|
44
|
-
font-family: 'Architects Daughter', cursive;
|
45
|
-
background-color: #44518E;
|
46
|
-
color: #C6CCE7;
|
47
|
-
text-align: left;
|
48
|
-
margin: 0 0 1em 0;
|
49
|
-
padding: 0.5em 5%;
|
50
|
-
border-radius: 1em 1em 0 0;
|
51
|
-
border-bottom: 2px solid #424A70;
|
52
|
-
font-size: 1.1em;
|
53
|
-
}
|
54
|
-
h2:before {
|
55
|
-
content: "|||";
|
56
|
-
color: #99A3CE;
|
57
|
-
padding-right: 0.3em;
|
58
|
-
margin-left: -0.5em;
|
59
|
-
}
|
60
|
-
h3:before {
|
61
|
-
content: "|||||";
|
62
|
-
color: #99A3CE;
|
63
|
-
padding-right: 0.3em;
|
64
|
-
margin-left: -1em;
|
65
|
-
}
|
66
|
-
h1 a, h2 a, h3 a
|
67
|
-
{
|
68
|
-
color: #EBCD86;
|
69
|
-
}
|
70
|
-
h1 a:hover, h2 a:hover, h3 a:hover
|
71
|
-
{
|
72
|
-
color: #EBD7A6;
|
73
|
-
}
|
74
|
-
p
|
75
|
-
{
|
76
|
-
font-size: 1em;
|
77
|
-
padding: 0 1em;
|
78
|
-
margin: 0.5em 0;
|
79
|
-
}
|
80
|
-
a
|
81
|
-
{
|
82
|
-
color: #D0AC54;
|
83
|
-
text-decoration: none;
|
84
|
-
}
|
85
|
-
a:hover
|
86
|
-
{
|
87
|
-
color: #927121;
|
88
|
-
text-decoration: underline;
|
89
|
-
}
|
90
|
-
#wrapper
|
91
|
-
{
|
92
|
-
background-color: #fff;
|
93
|
-
margin: 1em 5%;
|
94
|
-
padding: 0 0 2%;
|
95
|
-
border-radius: 20px;
|
96
|
-
min-height: 50%;
|
97
|
-
color: #007;
|
98
|
-
}
|
99
|
-
|
100
|
-
#wrapper p{ padding: 0 2%;}
|
101
|
-
.bold { font-weight: bold; }
|
102
|
-
#wrapper ol li{ padding: 0 2%;}
|
103
|
-
pre
|
104
|
-
{
|
105
|
-
border-radius: 20px;
|
106
|
-
padding: 0.5em 0;
|
107
|
-
background-color: #444;
|
108
|
-
color: #ddd;
|
109
|
-
}
|
110
|
-
@media screen and (max-width: 680px)
|
111
|
-
{
|
112
|
-
}
|
113
|
-
%body
|
114
|
-
%h1< Plezi 404 error code (missing, not broken)...
|
115
|
-
#wrapper
|
116
|
-
%h2#missing
|
117
|
-
couldn't find
|
118
|
-
= defined?(request) ? request.path : "what you're looking for..."
|
119
|
-
%p Sorry, we couldn't find what you're looking for...
|
120
|
-
%p ... but we can always bring you something nice from another location, right?
|
121
|
-
/ want to use your layout? use the :haml_concat method to wrap the 404 error code message. see http://haml.info/docs/yardoc/Haml/Helpers.html#haml_concat-instance_method .
|
data/resources/404.html
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<head>
|
3
|
-
<style>
|
4
|
-
/*
|
5
|
-
med-blue: #44518E
|
6
|
-
dark-gray: #424A70
|
7
|
-
blue: #1B2864
|
8
|
-
light-blue: #818ECE
|
9
|
-
light-gray: #99A3CE
|
10
|
-
*/
|
11
|
-
body, html
|
12
|
-
{
|
13
|
-
background-color: #99A3CE;
|
14
|
-
padding: 0; margin: 0;
|
15
|
-
width: 100%;
|
16
|
-
font-size: 1em;
|
17
|
-
}
|
18
|
-
|
19
|
-
h1
|
20
|
-
{
|
21
|
-
font-family: 'Shadows Into Light', cursive;
|
22
|
-
background-color: #1B2864;
|
23
|
-
color: #99A3CE;
|
24
|
-
text-align: center;
|
25
|
-
border-bottom: 4px solid #424A70;
|
26
|
-
margin: 0 0 1em 0;
|
27
|
-
padding: 0.4em 0;
|
28
|
-
width: 100%;
|
29
|
-
}
|
30
|
-
h2
|
31
|
-
{
|
32
|
-
background-color: #44518E;
|
33
|
-
color: #C6CCE7;
|
34
|
-
text-align: left;
|
35
|
-
margin: 0 0 1em 0;
|
36
|
-
padding: 0.5em 5%;
|
37
|
-
border-radius: 20px 20px 0 0;
|
38
|
-
font-family: 'Architects Daughter', cursive;
|
39
|
-
border-bottom: 3px solid #424A70;
|
40
|
-
font-size: 1.2em;
|
41
|
-
}
|
42
|
-
h3
|
43
|
-
{
|
44
|
-
font-family: 'Architects Daughter', cursive;
|
45
|
-
background-color: #44518E;
|
46
|
-
color: #C6CCE7;
|
47
|
-
text-align: left;
|
48
|
-
margin: 0 0 1em 0;
|
49
|
-
padding: 0.5em 5%;
|
50
|
-
border-radius: 1em 1em 0 0;
|
51
|
-
border-bottom: 2px solid #424A70;
|
52
|
-
font-size: 1.1em;
|
53
|
-
}
|
54
|
-
h2:before {
|
55
|
-
content: "|||";
|
56
|
-
color: #99A3CE;
|
57
|
-
padding-right: 0.3em;
|
58
|
-
margin-left: -0.5em;
|
59
|
-
}
|
60
|
-
h3:before {
|
61
|
-
content: "|||||";
|
62
|
-
color: #99A3CE;
|
63
|
-
padding-right: 0.3em;
|
64
|
-
margin-left: -1em;
|
65
|
-
}
|
66
|
-
h1 a, h2 a, h3 a
|
67
|
-
{
|
68
|
-
color: #EBCD86;
|
69
|
-
}
|
70
|
-
h1 a:hover, h2 a:hover, h3 a:hover
|
71
|
-
{
|
72
|
-
color: #EBD7A6;
|
73
|
-
}
|
74
|
-
p
|
75
|
-
{
|
76
|
-
font-size: 1em;
|
77
|
-
padding: 0 1em;
|
78
|
-
margin: 0.5em 0;
|
79
|
-
}
|
80
|
-
a
|
81
|
-
{
|
82
|
-
color: #D0AC54;
|
83
|
-
text-decoration: none;
|
84
|
-
}
|
85
|
-
a:hover
|
86
|
-
{
|
87
|
-
color: #927121;
|
88
|
-
text-decoration: underline;
|
89
|
-
}
|
90
|
-
#wrapper
|
91
|
-
{
|
92
|
-
background-color: #fff;
|
93
|
-
margin: 1em 5%;
|
94
|
-
padding: 0 0 2%;
|
95
|
-
border-radius: 20px;
|
96
|
-
min-height: 50%;
|
97
|
-
color: #007;
|
98
|
-
}
|
99
|
-
|
100
|
-
#wrapper p{ padding: 0 2%;}
|
101
|
-
.bold { font-weight: bold; }
|
102
|
-
#wrapper ol li{ padding: 0 2%;}
|
103
|
-
pre
|
104
|
-
{
|
105
|
-
border-radius: 20px;
|
106
|
-
padding: 0.5em 0;
|
107
|
-
background-color: #444;
|
108
|
-
color: #ddd;
|
109
|
-
}
|
110
|
-
@media screen and (max-width: 680px)
|
111
|
-
{
|
112
|
-
}
|
113
|
-
</style>
|
114
|
-
</head>
|
115
|
-
<body>
|
116
|
-
<h1>Plezi 404 error code (missing, not broken)...</h1>
|
117
|
-
<div id='wrapper'>
|
118
|
-
<h2 id='missing'>
|
119
|
-
couldn't find your request...
|
120
|
-
</h2>
|
121
|
-
<p>Sorry, we couldn't find what you're looking for...</p>
|
122
|
-
<p>... but we can always bring you something nice from another location, right?</p>
|
123
|
-
</div>
|
124
|
-
</body>
|