landable 1.7.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 +7 -0
- data/.gitignore +13 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +56 -0
- data/Rakefile +22 -0
- data/app/controllers/concerns/landable/variables_concern.rb +38 -0
- data/app/controllers/landable/api/access_tokens_controller.rb +48 -0
- data/app/controllers/landable/api/assets_controller.rb +55 -0
- data/app/controllers/landable/api/categories_controller.rb +13 -0
- data/app/controllers/landable/api/directories_controller.rb +19 -0
- data/app/controllers/landable/api/page_revisions_controller.rb +38 -0
- data/app/controllers/landable/api/pages_controller.rb +96 -0
- data/app/controllers/landable/api/templates_controller.rb +33 -0
- data/app/controllers/landable/api/themes_controller.rb +57 -0
- data/app/controllers/landable/api_controller.rb +75 -0
- data/app/controllers/landable/application_controller.rb +4 -0
- data/app/controllers/landable/public/pages_controller.rb +25 -0
- data/app/controllers/landable/public/preview/page_revisions_controller.rb +16 -0
- data/app/controllers/landable/public/preview/pages_controller.rb +16 -0
- data/app/controllers/landable/public/sitemap_controller.rb +18 -0
- data/app/decorators/landable/null_page_decorator.rb +26 -0
- data/app/decorators/landable/page_decorator.rb +40 -0
- data/app/helpers/landable/application_helper.rb +13 -0
- data/app/helpers/landable/pages_helper.rb +20 -0
- data/app/models/concerns/landable/has_assets.rb +74 -0
- data/app/models/concerns/landable/table_name.rb +12 -0
- data/app/models/concerns/landable/traffic/table_name.rb +14 -0
- data/app/models/landable/access_token.rb +20 -0
- data/app/models/landable/asset.rb +63 -0
- data/app/models/landable/asset_search_engine.rb +20 -0
- data/app/models/landable/author.rb +12 -0
- data/app/models/landable/category.rb +27 -0
- data/app/models/landable/directory.rb +23 -0
- data/app/models/landable/page.rb +259 -0
- data/app/models/landable/page_revision.rb +74 -0
- data/app/models/landable/page_search_engine.rb +20 -0
- data/app/models/landable/search_engine.rb +39 -0
- data/app/models/landable/template.rb +24 -0
- data/app/models/landable/theme.rb +20 -0
- data/app/models/landable/traffic/access.rb +11 -0
- data/app/models/landable/traffic/ad_group.rb +11 -0
- data/app/models/landable/traffic/ad_type.rb +11 -0
- data/app/models/landable/traffic/attribution.rb +38 -0
- data/app/models/landable/traffic/bid_match_type.rb +11 -0
- data/app/models/landable/traffic/browser.rb +11 -0
- data/app/models/landable/traffic/campaign.rb +11 -0
- data/app/models/landable/traffic/city.rb +11 -0
- data/app/models/landable/traffic/content.rb +11 -0
- data/app/models/landable/traffic/cookie.rb +16 -0
- data/app/models/landable/traffic/country.rb +11 -0
- data/app/models/landable/traffic/creative.rb +11 -0
- data/app/models/landable/traffic/device.rb +11 -0
- data/app/models/landable/traffic/device_type.rb +11 -0
- data/app/models/landable/traffic/domain.rb +12 -0
- data/app/models/landable/traffic/event.rb +12 -0
- data/app/models/landable/traffic/event_type.rb +11 -0
- data/app/models/landable/traffic/experiment.rb +11 -0
- data/app/models/landable/traffic/http_method.rb +11 -0
- data/app/models/landable/traffic/ip_address.rb +11 -0
- data/app/models/landable/traffic/ip_lookup.rb +12 -0
- data/app/models/landable/traffic/keyword.rb +11 -0
- data/app/models/landable/traffic/location.rb +11 -0
- data/app/models/landable/traffic/match_type.rb +11 -0
- data/app/models/landable/traffic/medium.rb +11 -0
- data/app/models/landable/traffic/mime_type.rb +11 -0
- data/app/models/landable/traffic/network.rb +11 -0
- data/app/models/landable/traffic/owner.rb +10 -0
- data/app/models/landable/traffic/ownership.rb +10 -0
- data/app/models/landable/traffic/page_view.rb +24 -0
- data/app/models/landable/traffic/path.rb +13 -0
- data/app/models/landable/traffic/placement.rb +11 -0
- data/app/models/landable/traffic/platform.rb +11 -0
- data/app/models/landable/traffic/position.rb +11 -0
- data/app/models/landable/traffic/query_string.rb +12 -0
- data/app/models/landable/traffic/referer.rb +11 -0
- data/app/models/landable/traffic/region.rb +11 -0
- data/app/models/landable/traffic/search_term.rb +11 -0
- data/app/models/landable/traffic/source.rb +11 -0
- data/app/models/landable/traffic/target.rb +11 -0
- data/app/models/landable/traffic/user_agent.rb +28 -0
- data/app/models/landable/traffic/user_agent_type.rb +11 -0
- data/app/models/landable/traffic/visit.rb +15 -0
- data/app/models/landable/traffic/visitor.rb +13 -0
- data/app/responders/landable/api_responder.rb +76 -0
- data/app/responders/landable/page_render_responder.rb +15 -0
- data/app/serializers/landable/access_token_serializer.rb +6 -0
- data/app/serializers/landable/asset_serializer.rb +14 -0
- data/app/serializers/landable/author_serializer.rb +5 -0
- data/app/serializers/landable/category_serializer.rb +5 -0
- data/app/serializers/landable/directory_serializer.rb +8 -0
- data/app/serializers/landable/page_revision_serializer.rb +15 -0
- data/app/serializers/landable/page_serializer.rb +31 -0
- data/app/serializers/landable/template_serializer.rb +5 -0
- data/app/serializers/landable/theme_serializer.rb +7 -0
- data/app/services/landable/authentication_service.rb +44 -0
- data/app/services/landable/registration_service.rb +13 -0
- data/app/services/landable/render_service.rb +86 -0
- data/app/services/landable/tidy_service.rb +155 -0
- data/app/uploaders/landable/asset_uploader.rb +9 -0
- data/app/validators/path_validator.rb +12 -0
- data/app/validators/url_validator.rb +13 -0
- data/app/views/templates/preview.liquid +122 -0
- data/bin/rails +8 -0
- data/bin/redb +7 -0
- data/config.ru +7 -0
- data/config/cucumber.yml +5 -0
- data/config/routes.rb +62 -0
- data/db/migrate/20130510221424_create_landable_schema.rb +338 -0
- data/db/migrate/20130909182713_landable_pages__add_updated_by.rb +11 -0
- data/db/migrate/20130909182715_landable_page_revisions__break_out_snapshot.rb +72 -0
- data/db/migrate/20130909191153_landable_pages__add_lock_version.rb +5 -0
- data/db/migrate/20131002220041_file_based_themes.rb +12 -0
- data/db/migrate/20131008164204_create_head_tag_on_page.rb +19 -0
- data/db/migrate/20131008193544_drop_status_codes_model.rb +44 -0
- data/db/migrate/20131028145652_add_traffic_schema.rb +276 -0
- data/db/migrate/20131101213623_add_dnt_column_to_visits.rb +7 -0
- data/db/migrate/20131104224120_add_meta_on_events.rb +7 -0
- data/db/migrate/20131106185946_add_index_on_page_revisions_path.rb +6 -0
- data/db/migrate/20131106193021_page_revisisons__path_status_code_index.rb +9 -0
- data/db/migrate/20131108212501_traffic_owner_ids_are_serials.rb +20 -0
- data/db/migrate/20131121150902_add_attribution_id_to_unique_index.rb +10 -0
- data/db/migrate/20131216214027_drop_browser_screenshot_tables.rb +6 -0
- data/db/migrate/20140128170659_file_backed_templates.rb +8 -0
- data/db/migrate/20140205193757_fix_status_codes.rb +24 -0
- data/db/migrate/20140206211322_add_response_time_to_traffic_page_views.rb +7 -0
- data/db/migrate/20140220170324_add_slug_to_categories.rb +14 -0
- data/db/migrate/20140220174630_add_abstract_and_hero_asset_to_pages_and_page_revisions.rb +8 -0
- data/db/migrate/20140224205516_rename_traffic_schema.rb +40 -0
- data/db/pgtap/pgtap.sql +9034 -0
- data/db/test/landable.access_tokens.sql +13 -0
- data/db/test/landable.assets.sql +16 -0
- data/db/test/landable.authors.sql +22 -0
- data/db/test/landable.categories.sql +9 -0
- data/db/test/landable.page_revisions.sql +41 -0
- data/db/test/landable.pages.sql +19 -0
- data/db/test/landable.templates.sql +15 -0
- data/db/test/landable.themes.sql +25 -0
- data/doc/schema/access_token.json +22 -0
- data/doc/schema/asset.json +65 -0
- data/doc/schema/author.json +30 -0
- data/doc/schema/directory.json +24 -0
- data/doc/schema/page.json +95 -0
- data/doc/schema/page_revision.json +70 -0
- data/doc/schema/theme.json +37 -0
- data/doc/schema/uuid.json +6 -0
- data/features/api/access_tokens.feature +84 -0
- data/features/api/assets.feature +46 -0
- data/features/api/cors.feature +25 -0
- data/features/api/pages.feature +42 -0
- data/features/api/preview.feature +16 -0
- data/features/api/templates.feature +33 -0
- data/features/api/themes.feature +33 -0
- data/features/liquid/body.feature +35 -0
- data/features/liquid/drops/categories.feature +54 -0
- data/features/liquid/tags.feature +168 -0
- data/features/public/content_types.feature +17 -0
- data/features/public/publishing.feature +45 -0
- data/features/public/status_codes.feature +25 -0
- data/features/public/views.feature +17 -0
- data/features/step_definitions/asset_steps.rb +60 -0
- data/features/step_definitions/core_api_steps.rb +139 -0
- data/features/step_definitions/debug_steps.rb +3 -0
- data/features/step_definitions/factory_steps.rb +124 -0
- data/features/step_definitions/html_steps.rb +9 -0
- data/features/step_definitions/liquid_steps.rb +79 -0
- data/features/step_definitions/revision_steps.rb +5 -0
- data/features/step_definitions/theme_steps.rb +43 -0
- data/features/support/env.rb +66 -0
- data/features/support/usefulness.rb +13 -0
- data/landable.gemspec +54 -0
- data/lib/generators/landable/collection/collection_generator.rb +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%.less +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/mixins.less +0 -0
- data/lib/generators/landable/collection/templates/stylesheets/landable/%file_name%/variables.less +0 -0
- data/lib/generators/landable/component/component_generator.rb +0 -0
- data/lib/generators/landable/component/templates/javascripts/landable/%file_name%.less +0 -0
- data/lib/generators/landable/component/templates/stylesheets/landable/%file_name%.less +0 -0
- data/lib/generators/landable/install_generator.rb +19 -0
- data/lib/generators/landable/landable_generator.rb +22 -0
- data/lib/generators/templates/landable.rb +34 -0
- data/lib/landable.rb +30 -0
- data/lib/landable/configuration.rb +115 -0
- data/lib/landable/core_ext/ipaddr.rb +18 -0
- data/lib/landable/engine.rb +69 -0
- data/lib/landable/error.rb +16 -0
- data/lib/landable/inflections.rb +4 -0
- data/lib/landable/layout.rb +60 -0
- data/lib/landable/liquid.rb +27 -0
- data/lib/landable/liquid/asset_tags.rb +76 -0
- data/lib/landable/liquid/drops.rb +46 -0
- data/lib/landable/liquid/filters.rb +11 -0
- data/lib/landable/liquid/tags.rb +91 -0
- data/lib/landable/migration.rb +40 -0
- data/lib/landable/mime_types.rb +15 -0
- data/lib/landable/partial.rb +46 -0
- data/lib/landable/seeds.rb +36 -0
- data/lib/landable/traffic.rb +34 -0
- data/lib/landable/traffic/crawl_tracker.rb +9 -0
- data/lib/landable/traffic/noop_tracker.rb +8 -0
- data/lib/landable/traffic/ping_tracker.rb +9 -0
- data/lib/landable/traffic/scan_tracker.rb +9 -0
- data/lib/landable/traffic/scrape_tracker.rb +9 -0
- data/lib/landable/traffic/tracker.rb +283 -0
- data/lib/landable/traffic/user_tracker.rb +65 -0
- data/lib/landable/version.rb +10 -0
- data/lib/tasks/landable/cucumber.rake +67 -0
- data/lib/tasks/landable/data.rake +166 -0
- data/lib/tasks/landable/pgtap.rake +26 -0
- data/lib/tasks/landable/rdoc.rake +11 -0
- data/lib/tasks/landable/seed.rake +16 -0
- data/lib/tasks/landable/spec.rake +15 -0
- data/script/cucumber +10 -0
- data/spec/concerns/landable/has_assets_spec.rb +75 -0
- data/spec/concerns/landable/table_name_spec.rb +15 -0
- data/spec/concerns/landable/traffic/table_name_spec.rb +16 -0
- data/spec/controllers/concerns/landable/variables_concern_spec.rb +66 -0
- data/spec/controllers/landable/api/assets_controller_spec.rb +24 -0
- data/spec/controllers/landable/api/categories_controller_spec.rb +45 -0
- data/spec/controllers/landable/api/directories_controller_spec.rb +56 -0
- data/spec/controllers/landable/api/page_revisions_controller_spec.rb +29 -0
- data/spec/controllers/landable/api/pages_controller_spec.rb +271 -0
- data/spec/controllers/landable/api_controller_spec.rb +189 -0
- data/spec/controllers/public/preview/page_revisions_controller_spec.rb +41 -0
- data/spec/controllers/public/preview/pages_controller_spec.rb +36 -0
- data/spec/controllers/public/sitemap_controller_spec.rb +25 -0
- data/spec/decorators/page_decorator_spec.rb +90 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/foo.jpg +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +10 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/controllers/priority_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/priority.html.erb +18 -0
- data/spec/dummy/app/views/partials/_foobazz.html +1 -0
- data/spec/dummy/app/views/priority/show.html.erb +11 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +21 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +60 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/landable.rb +22 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/structure.sql +3736 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/asset.rb +29 -0
- data/spec/factories/authors.rb +12 -0
- data/spec/factories/category.rb +6 -0
- data/spec/factories/page_revision.rb +6 -0
- data/spec/factories/pages.rb +33 -0
- data/spec/factories/template.rb +13 -0
- data/spec/factories/theme.rb +14 -0
- data/spec/fixtures/assets/cthulhu.jpg +0 -0
- data/spec/fixtures/assets/panda.png +0 -0
- data/spec/fixtures/assets/sloth.png +0 -0
- data/spec/fixtures/assets/small.pdf +0 -0
- data/spec/helpers/pages_helper_spec.rb +35 -0
- data/spec/lib/landable/configuration_spec.rb +20 -0
- data/spec/lib/landable/layout_spec.rb +25 -0
- data/spec/lib/landable/liquid_spec.rb +24 -0
- data/spec/lib/landable/migration_spec.rb +51 -0
- data/spec/lib/landable/partial_spec.rb +84 -0
- data/spec/lib/landable/tracking_spec.rb +62 -0
- data/spec/lib/landable/traffic_spec.rb +45 -0
- data/spec/models/landable/access_token_spec.rb +13 -0
- data/spec/models/landable/asset_spec.rb +48 -0
- data/spec/models/landable/directory_spec.rb +36 -0
- data/spec/models/landable/page/errors_spec.rb +30 -0
- data/spec/models/landable/page_revision_spec.rb +75 -0
- data/spec/models/landable/page_spec.rb +377 -0
- data/spec/models/landable/template_spec.rb +47 -0
- data/spec/models/landable/theme_spec.rb +8 -0
- data/spec/responders/page_render_responder_spec.rb +43 -0
- data/spec/routing/public_page_route_spec.rb +36 -0
- data/spec/services/landable/authentication_service_spec.rb +61 -0
- data/spec/services/landable/render_service_spec.rb +103 -0
- data/spec/services/landable/tidy_service_spec.rb +157 -0
- data/spec/spec_helper.rb +38 -0
- data/spec/support/behaviors.rb +107 -0
- data/spec/support/carrier_wave.rb +17 -0
- data/spec/support/categories.yml +2 -0
- data/spec/support/helpers.rb +22 -0
- metadata +795 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
class PathValidator < ActiveModel::Validator
|
|
2
|
+
def validate(record)
|
|
3
|
+
if match?(record.path)
|
|
4
|
+
record.errors[:path] << "is Reserved!"
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def match?(path)
|
|
9
|
+
# See if the applying path matches any reserved_paths via a Regex
|
|
10
|
+
Landable.configuration.reserved_paths.any? { |reserved| Regexp.new("^#{reserved}$", 'i').match(path) }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class UrlValidator < ActiveModel::EachValidator
|
|
2
|
+
|
|
3
|
+
def validate_each(record, attribute, value)
|
|
4
|
+
valid = begin
|
|
5
|
+
value =~ /^[a-z]+\:\/\// or value =~ /^\//
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
unless valid
|
|
9
|
+
record.errors[attribute] << ("Invalid URL! Make sure it starts with http:// or /")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{% if is_redirect %}
|
|
2
|
+
<!DOCTYPE html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<style type="text/css">
|
|
6
|
+
body {
|
|
7
|
+
font-family: sans-serif;
|
|
8
|
+
margin: 0;
|
|
9
|
+
background: #eee;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.message-wrapper, iframe {
|
|
13
|
+
position: absolute;
|
|
14
|
+
border: 0;
|
|
15
|
+
top: 0;
|
|
16
|
+
right: 0;
|
|
17
|
+
bottom: 0;
|
|
18
|
+
left: 0;
|
|
19
|
+
width: 100%;
|
|
20
|
+
height: 100%;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
iframe {
|
|
24
|
+
z-index: 100;
|
|
25
|
+
-webkit-filter: blur(10px);
|
|
26
|
+
-moz-filter: blur(10px);
|
|
27
|
+
filter: blur(10px);
|
|
28
|
+
background: transparent;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.message-wrapper {
|
|
32
|
+
z-index: 200;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.message {
|
|
36
|
+
background: #fff;
|
|
37
|
+
width: 80%;
|
|
38
|
+
max-width: 400px;
|
|
39
|
+
padding: 1em;
|
|
40
|
+
margin: 10% auto auto auto;
|
|
41
|
+
text-align: center;
|
|
42
|
+
-moz-border-radius: 2px;
|
|
43
|
+
-webkit-border-radius: 2px;
|
|
44
|
+
border-radius: 2px;
|
|
45
|
+
border: 1px #ccc solid;
|
|
46
|
+
border-bottom-color: #aaa;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.status-code {
|
|
50
|
+
font-weight: bold;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.redirect-url {
|
|
54
|
+
display: block;
|
|
55
|
+
margin-top: 0.8em;
|
|
56
|
+
font-size: 1.2em;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.redirect-url a {
|
|
60
|
+
color: #466cd2;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.preview-mode {
|
|
64
|
+
font-size: 0.9em;
|
|
65
|
+
color: #777;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<div class="message-wrapper">
|
|
71
|
+
<div class="message">
|
|
72
|
+
<p>
|
|
73
|
+
This page will redirect (<span class="status-code">{{ status_code }}</span>) to:
|
|
74
|
+
<span class="redirect-url">
|
|
75
|
+
<a href="{{ redirect_url }}">{{ redirect_url }}</a>
|
|
76
|
+
</span>
|
|
77
|
+
</p>
|
|
78
|
+
<p class="preview-mode">(preview mode)</p>
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
<iframe src="{{ redirect_url }}" seamless="seamless">
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
{% else %}
|
|
85
|
+
<!-- pretty invalid, this is -->
|
|
86
|
+
<style type="text/css">
|
|
87
|
+
body {
|
|
88
|
+
padding-top: 40px;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
body:before {
|
|
92
|
+
text-align: center;
|
|
93
|
+
font-weight: bold;
|
|
94
|
+
background-color: #FFDA73;
|
|
95
|
+
font-family: Roboto;
|
|
96
|
+
width: 100%;
|
|
97
|
+
position: absolute;
|
|
98
|
+
top: 0;
|
|
99
|
+
left: 0;
|
|
100
|
+
font-size: 20px;
|
|
101
|
+
padding: 5px 0;
|
|
102
|
+
line-height: 30px;
|
|
103
|
+
border-bottom: 1px #e2bd56 solid;
|
|
104
|
+
content: "Preview Mode (Test your unpublished changes with this page. Share this URL!)";
|
|
105
|
+
box-sizing: border-box;
|
|
106
|
+
height: 40px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
body.publicist-preview {
|
|
110
|
+
padding-top: 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
body.publicist-preview:before {
|
|
114
|
+
display: none;
|
|
115
|
+
}
|
|
116
|
+
</style>
|
|
117
|
+
<!-- Body Tag for handling Preview Message -->
|
|
118
|
+
<body>
|
|
119
|
+
{{ content }}
|
|
120
|
+
</body>
|
|
121
|
+
|
|
122
|
+
{% endif %}
|
data/bin/rails
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/landable/engine', __FILE__)
|
|
6
|
+
|
|
7
|
+
require 'rails/all'
|
|
8
|
+
require 'rails/engine/commands'
|
data/bin/redb
ADDED
data/config.ru
ADDED
data/config/cucumber.yml
ADDED
data/config/routes.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
Landable::Engine.routes.draw do
|
|
2
|
+
scope path: Landable.configuration.api_namespace, module: 'api' do
|
|
3
|
+
resources :access_tokens, only: [:create, :update, :destroy]
|
|
4
|
+
resources :categories, only: [:index, :show]
|
|
5
|
+
resources :status_codes, only: [:index]
|
|
6
|
+
|
|
7
|
+
resources :directories, only: [:index, :show], constraints: {
|
|
8
|
+
id: /[%a-zA-Z0-9\/_.~-]*/
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
resources :assets, only: [:index, :show, :create, :update]
|
|
12
|
+
|
|
13
|
+
concern :has_assets do
|
|
14
|
+
resources :assets, only: [:index, :update, :destroy]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
concern :has_screenshots do
|
|
18
|
+
post 'screenshots', on: :member
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
resources :themes, only: [:index, :show, :create, :update], concerns: :has_assets do
|
|
22
|
+
post 'preview', on: :collection
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
resources :templates, only: [:index, :show, :create, :update]
|
|
26
|
+
|
|
27
|
+
resources :pages, concerns: [:has_assets, :has_screenshots] do
|
|
28
|
+
post 'preview', on: :collection
|
|
29
|
+
post 'publish', on: :member
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
resources :page_revisions, only: [:index, :show], concerns: [:has_screenshots] do
|
|
33
|
+
post 'revert_to', on: :member
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
resources :access_tokens, only: [:create, :destroy, :show]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# coming soon: screenshots!
|
|
40
|
+
|
|
41
|
+
# resources :screenshots, only: [:index, :show, :create] do
|
|
42
|
+
# post 'callback', on: :collection
|
|
43
|
+
# post 'resubmit', on: :member
|
|
44
|
+
# end
|
|
45
|
+
|
|
46
|
+
# resources :browsers, only: [:index, :show]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
scope module: 'public', as: :public do
|
|
50
|
+
scope '-', module: 'preview', as: :preview do
|
|
51
|
+
resources :pages, path: 'p', only: [:show]
|
|
52
|
+
resources :page_revisions, path: 'pr', only: [:show]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
get '/sitemap.xml' => 'sitemap#index', as: :sitemap
|
|
56
|
+
|
|
57
|
+
get '*url' => 'pages#show', as: :page, format: false, constraints: lambda { |request|
|
|
58
|
+
# Published Landable Page
|
|
59
|
+
Landable::PageRevision.table_exists? && Landable::PageRevision.where(path: request.path, is_published: true).any?
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
class CreateLandableSchema < Landable::Migration
|
|
2
|
+
def change
|
|
3
|
+
# This really should not be in this migration, but it's a convenient location
|
|
4
|
+
# while everything's still under development.
|
|
5
|
+
#
|
|
6
|
+
# TODO extract to a separate migration, check if it exists, maybe check if we
|
|
7
|
+
# actually have permission to do it, etc.
|
|
8
|
+
enable_extension "uuid-ossp"
|
|
9
|
+
enable_extension "hstore"
|
|
10
|
+
enable_extension "pg_trgm"
|
|
11
|
+
|
|
12
|
+
execute "CREATE SCHEMA #{Landable.configuration.database_schema_prefix}landable;"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## status_codes
|
|
16
|
+
|
|
17
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.status_code_categories", id: :uuid, primary_key: :status_code_category_id do |t|
|
|
18
|
+
t.text :name, null: false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_status_code_categories__u_name ON #{Landable.configuration.database_schema_prefix}landable.status_code_categories(lower(name))"
|
|
22
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.status_code_categories IS
|
|
23
|
+
$$Categories that status codes belong to. Used to affect behavior when viewing a page.$$"
|
|
24
|
+
|
|
25
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.status_codes", id: :uuid, primary_key: :status_code_id do |t|
|
|
26
|
+
t.uuid :status_code_category_id, null: false
|
|
27
|
+
t.integer :code, null: false, limit: 2 # Creates as smallint
|
|
28
|
+
t.text :description, null: false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_status_codes__u_code ON #{Landable.configuration.database_schema_prefix}landable.status_codes(code)"
|
|
32
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.status_codes ADD CONSTRAINT status_code_category_fk FOREIGN KEY(status_code_category_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.status_code_categories(status_code_category_id)"
|
|
33
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.status_codes IS
|
|
34
|
+
$$Allowed status codes that pages can be set to.$$"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## themes
|
|
38
|
+
|
|
39
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.themes", id: :uuid, primary_key: :theme_id do |t|
|
|
40
|
+
t.text :name, null: false
|
|
41
|
+
t.text :body, null: false
|
|
42
|
+
t.text :description, null: false
|
|
43
|
+
t.text :thumbnail_url
|
|
44
|
+
t.timestamps
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_themes__u_name ON #{Landable.configuration.database_schema_prefix}landable.themes(lower(name))"
|
|
48
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.themes IS
|
|
49
|
+
$$Created themes to be consumed by pages. Themes supply formatting (css) rules and can supply header/footer content as well.$$"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## templates
|
|
53
|
+
|
|
54
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.templates", id: :uuid, primary_key: :template_id do |t|
|
|
55
|
+
t.text :name, null: false
|
|
56
|
+
t.text :slug, null: false
|
|
57
|
+
t.text :body, null: false
|
|
58
|
+
t.text :description, null: false
|
|
59
|
+
t.text :thumbnail_url
|
|
60
|
+
t.boolean :is_layout, null: false, default: false
|
|
61
|
+
t.timestamps
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_templates__u_name ON #{Landable.configuration.database_schema_prefix}landable.templates(lower(name))"
|
|
65
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.templates IS
|
|
66
|
+
$$Created templates to be consumed by pages.
|
|
67
|
+
A template can supply 'starter' code for a page.
|
|
68
|
+
A template can also supply code to create elements on a page (sidebars, for example).$$"
|
|
69
|
+
|
|
70
|
+
## pages
|
|
71
|
+
|
|
72
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.pages", id: :uuid, primary_key: :page_id do |t|
|
|
73
|
+
t.uuid :published_revision_id
|
|
74
|
+
t.boolean :is_publishable, null: false, default: true
|
|
75
|
+
|
|
76
|
+
t.uuid :theme_id
|
|
77
|
+
t.uuid :category_id
|
|
78
|
+
t.uuid :status_code_id, null: false
|
|
79
|
+
|
|
80
|
+
t.text :path, null: false
|
|
81
|
+
|
|
82
|
+
t.text :title
|
|
83
|
+
t.text :body
|
|
84
|
+
|
|
85
|
+
t.text :redirect_url
|
|
86
|
+
|
|
87
|
+
t.hstore :meta_tags
|
|
88
|
+
|
|
89
|
+
t.timestamp :imported_at
|
|
90
|
+
t.timestamps
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_pages__u_path ON #{Landable.configuration.database_schema_prefix}landable.pages(lower(path))"
|
|
94
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_pages__trgm_path ON #{Landable.configuration.database_schema_prefix}landable.pages USING gin(path gin_trgm_ops)"
|
|
95
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.pages IS
|
|
96
|
+
$$Pages serve as a draft, where you can make changes, preview and save those changes without having to update the live page on the website.
|
|
97
|
+
Pages also point to their published version, where applicable.$$"
|
|
98
|
+
|
|
99
|
+
## head_tags
|
|
100
|
+
|
|
101
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.head_tags", id: :uuid, primary_key: :head_tag_id do |t|
|
|
102
|
+
t.uuid :page_id
|
|
103
|
+
t.text :content, null: false
|
|
104
|
+
t.timestamps
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.head_tags ADD CONSTRAINT page_id_fk FOREIGN KEY (page_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.pages(page_id)"
|
|
108
|
+
|
|
109
|
+
## authors
|
|
110
|
+
|
|
111
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.authors", id: :uuid, primary_key: :author_id do |t|
|
|
112
|
+
t.text :email, null: false
|
|
113
|
+
t.text :username, null: false
|
|
114
|
+
t.text :first_name, null: false
|
|
115
|
+
t.text :last_name, null: false
|
|
116
|
+
t.timestamps
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_authors__u_email ON #{Landable.configuration.database_schema_prefix}landable.authors(lower(email))"
|
|
120
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_authors__u_username ON #{Landable.configuration.database_schema_prefix}landable.authors(username)"
|
|
121
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.authors IS
|
|
122
|
+
$$A list of authors that have accessed the website. Feeds foreign keys so we know which authors have published pages and updated assets.$$"
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
## access_tokens
|
|
126
|
+
|
|
127
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.access_tokens", id: :uuid, primary_key: :access_token_id do |t|
|
|
128
|
+
t.uuid :author_id, null: false
|
|
129
|
+
t.timestamp :expires_at, null: false
|
|
130
|
+
t.timestamps
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_access_tokens__author_id ON #{Landable.configuration.database_schema_prefix}landable.access_tokens(author_id)"
|
|
134
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.access_tokens ADD CONSTRAINT author_id_fk FOREIGN KEY (author_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.authors(author_id)"
|
|
135
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.access_tokens IS
|
|
136
|
+
$$Access tokens provide authentication information for specific users.$$"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
## page_revisions
|
|
140
|
+
|
|
141
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.page_revisions", id: :uuid, primary_key: :page_revision_id do |t|
|
|
142
|
+
t.integer :ordinal
|
|
143
|
+
t.text :notes
|
|
144
|
+
t.boolean :is_minor, default: false
|
|
145
|
+
t.boolean :is_published, default: true
|
|
146
|
+
|
|
147
|
+
t.uuid :page_id, null: false
|
|
148
|
+
t.uuid :author_id, null: false
|
|
149
|
+
|
|
150
|
+
t.text :snapshot_attributes, null: false
|
|
151
|
+
|
|
152
|
+
t.timestamps
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.page_revisions IS
|
|
156
|
+
$$Page revisions serve as a historical reference to pages as they were published.
|
|
157
|
+
The attributes of the page at the time of publishing are stored in snapshot_attributes, as essentially a text representation of a hash.
|
|
158
|
+
The current/active/live revision can be identified by referring to its corresponding PAGES record, OR by looking for the max(ordinal) for a given page_id.$$"
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
## categories
|
|
162
|
+
|
|
163
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.categories", id: :uuid, primary_key: :category_id do |t|
|
|
164
|
+
t.text :name
|
|
165
|
+
t.text :description
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_categories__u_name ON #{Landable.configuration.database_schema_prefix}landable.categories(lower(name))"
|
|
169
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.categories IS
|
|
170
|
+
$$Categories are used to sort pages.
|
|
171
|
+
Examples could include SEO, PPC.$$"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
## assets
|
|
175
|
+
|
|
176
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.assets", id: :uuid, primary_key: :asset_id do |t|
|
|
177
|
+
t.uuid :author_id, null: false
|
|
178
|
+
t.text :name, null: false
|
|
179
|
+
t.text :description
|
|
180
|
+
t.text :data, null: false
|
|
181
|
+
t.text :md5sum, null: false, length: 32
|
|
182
|
+
t.text :mime_type, null: false
|
|
183
|
+
t.integer :file_size
|
|
184
|
+
t.timestamps
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_assets__u_lower_name ON #{Landable.configuration.database_schema_prefix}landable.assets(lower(name))"
|
|
188
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_assets__u_data ON #{Landable.configuration.database_schema_prefix}landable.assets(data)"
|
|
189
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_assets__u_md5sum ON #{Landable.configuration.database_schema_prefix}landable.assets(md5sum)"
|
|
190
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_assets__author_id ON #{Landable.configuration.database_schema_prefix}landable.assets(author_id)"
|
|
191
|
+
|
|
192
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.assets ADD CONSTRAINT author_id_fk FOREIGN KEY (author_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.authors(author_id)"
|
|
193
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.assets IS
|
|
194
|
+
$$List of all assets uploaded.
|
|
195
|
+
Examples of assets include images (jpg, png, gif) and documents (PDF).
|
|
196
|
+
data, md5sum, mime_type, file_size are populated via the rails gem CarrierWave when a record is created.$$"
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
## browsers
|
|
200
|
+
|
|
201
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.browsers", id: :uuid, primary_key: :browser_id do |t|
|
|
202
|
+
t.text :device
|
|
203
|
+
t.text :os, null: false
|
|
204
|
+
t.text :os_version, null: false
|
|
205
|
+
t.text :browser
|
|
206
|
+
t.text :browser_version
|
|
207
|
+
|
|
208
|
+
t.boolean :screenshots_supported, null: false, default: false
|
|
209
|
+
t.boolean :is_primary, null: false, default: false
|
|
210
|
+
|
|
211
|
+
t.timestamps
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_screenshots__device_browser_browser_version ON #{Landable.configuration.database_schema_prefix}landable.browsers(device, browser, browser_version)"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
## screenshots
|
|
218
|
+
|
|
219
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.screenshots", id: :uuid, primary_key: :screenshot_id do |t|
|
|
220
|
+
t.uuid :screenshotable_id, null: false
|
|
221
|
+
t.text :screenshotable_type, null: false
|
|
222
|
+
|
|
223
|
+
t.uuid :browser_id
|
|
224
|
+
|
|
225
|
+
t.text :state
|
|
226
|
+
t.text :thumb_url
|
|
227
|
+
t.text :image_url
|
|
228
|
+
|
|
229
|
+
t.text :browserstack_id
|
|
230
|
+
t.text :browserstack_job_id
|
|
231
|
+
|
|
232
|
+
t.timestamps
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_screenshots__screenshotable_id_screenshotable_type_state ON #{Landable.configuration.database_schema_prefix}landable.screenshots(screenshotable_id, screenshotable_type, state)"
|
|
236
|
+
execute "CREATE INDEX #{Landable.configuration.database_schema_prefix}landable_screenshots__state ON #{Landable.configuration.database_schema_prefix}landable.screenshots(state)"
|
|
237
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_screenshots__u_browserstack_id ON #{Landable.configuration.database_schema_prefix}landable.screenshots(browserstack_id)"
|
|
238
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.screenshots ADD CONSTRAINT browser_id_fk FOREIGN KEY (browser_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.browsers(browser_id)"
|
|
239
|
+
execute "COMMENT ON TABLE #{Landable.configuration.database_schema_prefix}landable.screenshots IS
|
|
240
|
+
$$Stores saved screenshots (taken of pages) and the URLs to retrieve the actual image.$$"
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
## asset associations table
|
|
244
|
+
|
|
245
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.page_assets", id: :uuid, primary_key: :page_asset_id do |t|
|
|
246
|
+
t.uuid :page_id, null: false
|
|
247
|
+
t.uuid :asset_id, null: false
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_page_assets__u_page_id_asset_id ON #{Landable.configuration.database_schema_prefix}landable.page_assets (page_id, asset_id)"
|
|
251
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_assets ADD CONSTRAINT page_id_fk FOREIGN KEY (page_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.pages(page_id)"
|
|
252
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_assets ADD CONSTRAINT asset_id_fk FOREIGN KEY (asset_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.assets(asset_id)"
|
|
253
|
+
|
|
254
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.page_revision_assets", id: :uuid, primary_key: :page_revision_asset_id do |t|
|
|
255
|
+
t.uuid :page_revision_id, null: false
|
|
256
|
+
t.uuid :asset_id, null: false
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_page_revision_assets__u_page_revision_id_asset_id ON #{Landable.configuration.database_schema_prefix}landable.page_revision_assets (page_revision_id, asset_id)"
|
|
260
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_revision_assets ADD CONSTRAINT page_revision_id_fk FOREIGN KEY (page_revision_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.page_revisions(page_revision_id)"
|
|
261
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_revision_assets ADD CONSTRAINT asset_id_fk FOREIGN KEY (asset_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.assets(asset_id)"
|
|
262
|
+
|
|
263
|
+
create_table "#{Landable.configuration.database_schema_prefix}landable.theme_assets", id: :uuid, primary_key: :theme_asset_id do |t|
|
|
264
|
+
t.uuid :theme_id, null: false
|
|
265
|
+
t.uuid :asset_id, null: false
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
execute "CREATE UNIQUE INDEX #{Landable.configuration.database_schema_prefix}landable_theme_assets__u_theme_id_asset_id ON #{Landable.configuration.database_schema_prefix}landable.theme_assets (theme_id, asset_id)"
|
|
269
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.theme_assets ADD CONSTRAINT theme_id_fk FOREIGN KEY (theme_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.themes(theme_id)"
|
|
270
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.theme_assets ADD CONSTRAINT asset_id_fk FOREIGN KEY (asset_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.assets(asset_id)"
|
|
271
|
+
|
|
272
|
+
## other stuff
|
|
273
|
+
|
|
274
|
+
# Constraints for page_revisions
|
|
275
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_revisions ADD CONSTRAINT page_id_fk FOREIGN KEY (page_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.pages(page_id)"
|
|
276
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.page_revisions ADD CONSTRAINT author_id_fk FOREIGN KEY (author_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.authors(author_id)"
|
|
277
|
+
|
|
278
|
+
# Constraints for pages
|
|
279
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.pages ADD CONSTRAINT revision_id_fk FOREIGN KEY (published_revision_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.page_revisions(page_revision_id)"
|
|
280
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.pages ADD CONSTRAINT theme_id_fk FOREIGN KEY (theme_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.themes(theme_id)"
|
|
281
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.pages ADD CONSTRAINT category_id_fk FOREIGN KEY (category_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.categories(category_id)"
|
|
282
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.pages ADD CONSTRAINT status_code_fk FOREIGN KEY (status_code_id) REFERENCES #{Landable.configuration.database_schema_prefix}landable.status_codes(status_code_id)"
|
|
283
|
+
execute "ALTER TABLE #{Landable.configuration.database_schema_prefix}landable.pages ADD CONSTRAINT only_valid_paths CHECK (path ~ '^/[a-zA-Z0-9/_.~-]*$');"
|
|
284
|
+
|
|
285
|
+
# Revision-tracking trigger to automatically update ordinal
|
|
286
|
+
execute "CREATE FUNCTION #{Landable.configuration.database_schema_prefix}landable.pages_revision_ordinal()
|
|
287
|
+
RETURNS TRIGGER
|
|
288
|
+
AS
|
|
289
|
+
$TRIGGER$
|
|
290
|
+
BEGIN
|
|
291
|
+
|
|
292
|
+
IF NEW.ordinal IS NOT NULL THEN
|
|
293
|
+
RAISE EXCEPTION $$Must not supply ordinal value manually.$$;
|
|
294
|
+
END IF;
|
|
295
|
+
|
|
296
|
+
NEW.ordinal = (SELECT COALESCE(MAX(ordinal)+1,1)
|
|
297
|
+
FROM #{Landable.configuration.database_schema_prefix}landable.page_revisions
|
|
298
|
+
WHERE page_id = NEW.page_id);
|
|
299
|
+
|
|
300
|
+
RETURN NEW;
|
|
301
|
+
|
|
302
|
+
END
|
|
303
|
+
$TRIGGER$
|
|
304
|
+
LANGUAGE plpgsql;"
|
|
305
|
+
|
|
306
|
+
execute "CREATE TRIGGER #{Landable.configuration.database_schema_prefix}landable_page_revisions__bfr_insert
|
|
307
|
+
BEFORE INSERT ON #{Landable.configuration.database_schema_prefix}landable.page_revisions
|
|
308
|
+
FOR EACH ROW EXECUTE PROCEDURE #{Landable.configuration.database_schema_prefix}landable.pages_revision_ordinal();"
|
|
309
|
+
|
|
310
|
+
# Trigger disallowing deletes on page_revisions
|
|
311
|
+
execute "CREATE FUNCTION #{Landable.configuration.database_schema_prefix}landable.tg_disallow()
|
|
312
|
+
RETURNS TRIGGER
|
|
313
|
+
AS
|
|
314
|
+
$TRIGGER$
|
|
315
|
+
BEGIN
|
|
316
|
+
|
|
317
|
+
IF TG_LEVEL <> 'STATEMENT' THEN
|
|
318
|
+
RAISE EXCEPTION $$You should use a statement-level trigger (trigger %, table %)$$, TG_NAME, TG_RELID::regclass;
|
|
319
|
+
END IF;
|
|
320
|
+
|
|
321
|
+
RAISE EXCEPTION $$%s are not allowed on table %$$, TG_OP, TG_RELNAME;
|
|
322
|
+
|
|
323
|
+
RETURN NULL;
|
|
324
|
+
|
|
325
|
+
END
|
|
326
|
+
$TRIGGER$
|
|
327
|
+
LANGUAGE plpgsql;"
|
|
328
|
+
|
|
329
|
+
execute "CREATE TRIGGER #{Landable.configuration.database_schema_prefix}landable_page_revisions__no_delete
|
|
330
|
+
BEFORE DELETE ON #{Landable.configuration.database_schema_prefix}landable.page_revisions
|
|
331
|
+
FOR EACH STATEMENT EXECUTE PROCEDURE #{Landable.configuration.database_schema_prefix}landable.tg_disallow();"
|
|
332
|
+
|
|
333
|
+
execute "CREATE TRIGGER #{Landable.configuration.database_schema_prefix}landable_page_revisions__no_update
|
|
334
|
+
BEFORE UPDATE OF notes, is_minor, page_id, author_id, created_at, ordinal ON #{Landable.configuration.database_schema_prefix}landable.page_revisions
|
|
335
|
+
FOR EACH STATEMENT EXECUTE PROCEDURE #{Landable.configuration.database_schema_prefix}landable.tg_disallow();"
|
|
336
|
+
|
|
337
|
+
end
|
|
338
|
+
end
|