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,33 @@
|
|
|
1
|
+
require_dependency "landable/api_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Api
|
|
5
|
+
class TemplatesController < ApiController
|
|
6
|
+
def index
|
|
7
|
+
respond_with Template.all
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create
|
|
11
|
+
template = Template.new(template_params)
|
|
12
|
+
template.save!
|
|
13
|
+
respond_with template, status: :created, location: template_url(template)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def show
|
|
17
|
+
respond_with Template.find(params[:id])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update
|
|
21
|
+
template = Template.find(params[:id])
|
|
22
|
+
template.update_attributes! template_params
|
|
23
|
+
respond_with template
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def template_params
|
|
29
|
+
params.require(:template).permit(:id, :name, :body, :description, :thumbnail_url, :slug, :is_layout)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require_dependency "landable/api_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Api
|
|
5
|
+
class ThemesController < ApiController
|
|
6
|
+
def index
|
|
7
|
+
respond_with Theme.all
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def create
|
|
11
|
+
theme = Theme.new(theme_params)
|
|
12
|
+
theme.save!
|
|
13
|
+
respond_with theme, status: :created, location: theme_url(theme)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def show
|
|
17
|
+
respond_with Theme.find(params[:id])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update
|
|
21
|
+
theme = Theme.find(params[:id])
|
|
22
|
+
theme.update_attributes! theme_params
|
|
23
|
+
respond_with theme
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def preview
|
|
27
|
+
theme = Theme.new(theme_params)
|
|
28
|
+
page = Page.example(theme: theme)
|
|
29
|
+
|
|
30
|
+
params[:theme][:asset_ids].try(:each) do |asset_id|
|
|
31
|
+
theme.attachments.add Asset.find(asset_id)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
content = render_to_string(
|
|
35
|
+
text: RenderService.call(page),
|
|
36
|
+
layout: page.theme.file || false
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
respond_to do |format|
|
|
40
|
+
format.html do
|
|
41
|
+
render text: content, layout: false, content_type: 'text/html'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
format.json do
|
|
45
|
+
render json: {theme: {preview: content}}
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def theme_params
|
|
53
|
+
params.require(:theme).permit(:id, :name, :body, :description, :thumbnail_url)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require_dependency "landable/application_controller"
|
|
2
|
+
require_dependency "landable/api_responder"
|
|
3
|
+
require_dependency "landable/author"
|
|
4
|
+
|
|
5
|
+
module Landable
|
|
6
|
+
class ApiController < ApplicationController
|
|
7
|
+
# skip any of these that may have been inherited from ::ApplicationController
|
|
8
|
+
skip_before_filter :protect_from_forgery
|
|
9
|
+
skip_before_action :verify_authenticity_token
|
|
10
|
+
|
|
11
|
+
# tracking is not necessary for API calls
|
|
12
|
+
skip_around_action :track_with_landable!
|
|
13
|
+
|
|
14
|
+
before_filter :require_author!
|
|
15
|
+
|
|
16
|
+
respond_to :json
|
|
17
|
+
self.responder = Landable::ApiResponder
|
|
18
|
+
|
|
19
|
+
rescue_from ActiveRecord::RecordNotFound do |ex|
|
|
20
|
+
head 404
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
rescue_from ActiveRecord::RecordInvalid do |ex|
|
|
24
|
+
render json: { errors: ex.record.errors }, status: :unprocessable_entity
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
rescue_from ActionController::UnknownFormat do |ex|
|
|
28
|
+
head :not_acceptable
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
rescue_from ActiveRecord::StaleObjectError do |ex|
|
|
32
|
+
render json: { author: ex.record.updated_by_author }, status: 409
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
rescue_from PG::Error do |ex|
|
|
36
|
+
if ex.message =~ /invalid input syntax for uuid/
|
|
37
|
+
head :not_found
|
|
38
|
+
else
|
|
39
|
+
raise ex
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# here's looking at you, http://developer.github.com/v3/media/
|
|
45
|
+
# mime type matching is still handled by rails - see lib/landable/mime_types.rb
|
|
46
|
+
|
|
47
|
+
API_MEDIA_REGEX = /^application\/vnd\.landable(\.v(?<version>[\w\-]+))?(\.(?<param>(?:[\w\-]+)))?(\+(?<format>[\w\-]+))?/
|
|
48
|
+
|
|
49
|
+
def api_media
|
|
50
|
+
@api_media ||= begin
|
|
51
|
+
accept = request.headers['Accept'].match(API_MEDIA_REGEX) || {}
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
version: Landable::VERSION::STRING,
|
|
55
|
+
format: request.format.symbol,
|
|
56
|
+
param: accept['param'].presence,
|
|
57
|
+
}
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
protected
|
|
62
|
+
|
|
63
|
+
def require_author!
|
|
64
|
+
head :unauthorized if current_author.nil?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def current_author
|
|
68
|
+
return @current_author if @current_author
|
|
69
|
+
authenticate_with_http_basic do |username, token|
|
|
70
|
+
@current_author = Author.authenticate!(username, token)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require_dependency "landable/application_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Public
|
|
5
|
+
class PagesController < ApplicationController
|
|
6
|
+
respond_to :html
|
|
7
|
+
|
|
8
|
+
self.responder = Landable::PageRenderResponder
|
|
9
|
+
|
|
10
|
+
def show
|
|
11
|
+
respond_with current_snapshot
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def current_page
|
|
17
|
+
@current_page ||= Page.by_path(request.path)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def current_snapshot
|
|
21
|
+
@current_snapshot ||= current_page.published_revision.try(:snapshot) or Page.missing
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_dependency "landable/application_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Public
|
|
5
|
+
module Preview
|
|
6
|
+
class PageRevisionsController < ApplicationController
|
|
7
|
+
respond_to :html
|
|
8
|
+
|
|
9
|
+
def show
|
|
10
|
+
revision = PageRevision.find params[:id]
|
|
11
|
+
respond_with revision.snapshot, responder: Landable::PageRenderResponder
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_dependency "landable/application_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Public
|
|
5
|
+
module Preview
|
|
6
|
+
class PagesController < ApplicationController
|
|
7
|
+
respond_to :html
|
|
8
|
+
|
|
9
|
+
def show
|
|
10
|
+
page = Page.find params[:id]
|
|
11
|
+
respond_with page, responder: Landable::PageRenderResponder, preview: true
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_dependency "landable/application_controller"
|
|
2
|
+
|
|
3
|
+
module Landable
|
|
4
|
+
module Public
|
|
5
|
+
class SitemapController < ApplicationController
|
|
6
|
+
def index
|
|
7
|
+
sitemap = Landable::Page.generate_sitemap(
|
|
8
|
+
host: Landable.configuration.sitemap_host || request.host,
|
|
9
|
+
protocol: Landable.configuration.sitemap_protocol,
|
|
10
|
+
exclude_categories: Landable.configuration.sitemap_exclude_categories,
|
|
11
|
+
sitemap_additional_paths: Landable.configuration.sitemap_additional_paths,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
render xml: sitemap
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Landable
|
|
2
|
+
class NullPageDecorator < Landable::PageDecorator
|
|
3
|
+
def initialize
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def title
|
|
7
|
+
# Obviously, this should instead be configured with Landable in some way,
|
|
8
|
+
# such that you can register the titles you want everywhere. Or, of course,
|
|
9
|
+
# a more reasonable way to bypass Landable entirely yet still use the
|
|
10
|
+
# `landable` helper. Just waiting to tease out what features we need.
|
|
11
|
+
content_tag('title', 'No current page; default title')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def meta_tags
|
|
15
|
+
''
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def path
|
|
19
|
+
''
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def body
|
|
23
|
+
''
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Landable
|
|
2
|
+
class PageDecorator
|
|
3
|
+
include ActionView::Helpers::TagHelper
|
|
4
|
+
|
|
5
|
+
def initialize(page)
|
|
6
|
+
raise TypeError.new("Use Landable::NullPageDecorator") if page.nil?
|
|
7
|
+
@page = page
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def title
|
|
11
|
+
content_tag('title', page.title) if page.title?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def path
|
|
15
|
+
page.path
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def body
|
|
19
|
+
page.body.try(:html_safe)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def head_content
|
|
23
|
+
page.head_content.try(:html_safe)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def meta_tags
|
|
27
|
+
return unless tags = page.meta_tags
|
|
28
|
+
Rails.logger.info "Meta tags string: #{tags}" if tags.is_a? String
|
|
29
|
+
return if tags.empty? or !tags.is_a? Hash
|
|
30
|
+
|
|
31
|
+
tags.map { |name, value|
|
|
32
|
+
tag('meta', name: name, content: value) if value.present?
|
|
33
|
+
}.compact.join("\n").html_safe
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
attr_reader :page # Keeping it private until there's a compelling reason not to
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Landable
|
|
2
|
+
module ApplicationHelper
|
|
3
|
+
def method_missing(method, *args, &block)
|
|
4
|
+
return main_app.send(method, *args) if method =~ /_(path|url)$/ && main_app.respond_to?(method)
|
|
5
|
+
super
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def respond_to?(method)
|
|
9
|
+
return true if method =~ /_(path|url)$/ && main_app.respond_to?(method)
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Landable
|
|
2
|
+
module PagesHelper
|
|
3
|
+
def landable(page = current_page)
|
|
4
|
+
return Landable::NullPageDecorator.new if page.nil?
|
|
5
|
+
@landable ||= Landable::PageDecorator.new(page)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def current_page
|
|
9
|
+
if params[:controller] == "landable/public/preview/page_revisions"
|
|
10
|
+
current_page = PageRevision.find(params[:id])
|
|
11
|
+
elsif params[:controller] == "landable/public/preview/pages"
|
|
12
|
+
current_page = Page.find(params[:id])
|
|
13
|
+
else
|
|
14
|
+
current_page = Page.by_path(request.path)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@current_page ||= current_page
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Pages, page revisions, and themes are all renderable. Rendering potentially
|
|
2
|
+
# involves assets. Rather than having to query for each asset as it's
|
|
3
|
+
# discovered, this concern allows retrieval of all asset names for a given
|
|
4
|
+
# body (#asset_names), and commits the habtm relation on save (#save_assets!;
|
|
5
|
+
# allows us to say "this asset belongs to 3 pages"). #assets is overridden to
|
|
6
|
+
# ensure that the assets returned /always/ reflect assets present in the Liquid
|
|
7
|
+
# template.
|
|
8
|
+
|
|
9
|
+
require_dependency 'landable/liquid'
|
|
10
|
+
|
|
11
|
+
module Landable
|
|
12
|
+
module HasAssets
|
|
13
|
+
extend ActiveSupport::Concern
|
|
14
|
+
|
|
15
|
+
included do
|
|
16
|
+
has_and_belongs_to_many :assets, class_name: 'Landable::Asset', join_table: assets_join_table_name
|
|
17
|
+
|
|
18
|
+
before_save :save_assets!
|
|
19
|
+
|
|
20
|
+
def asset_names
|
|
21
|
+
# sticking with what we know about liquid, rather than doing regex.
|
|
22
|
+
# (though regex may be faster, should we need that optimization later.)
|
|
23
|
+
@asset_names ||= begin
|
|
24
|
+
template = ::Liquid::Template.parse(body)
|
|
25
|
+
asset_names_for_node template.root
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def assets
|
|
30
|
+
Landable::Asset.where(name: asset_names)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# {asset_name: asset}
|
|
34
|
+
def assets_as_hash
|
|
35
|
+
Hash[assets.map { |asset| [asset.name, asset] }]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# passthrough for body=; clears the asset_names cache in the process
|
|
39
|
+
def body= body_val
|
|
40
|
+
@asset_names = nil
|
|
41
|
+
self[:body] = body_val
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# this looks weird; I swear it works
|
|
45
|
+
def save_assets!
|
|
46
|
+
self.assets = self.assets
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def asset_names_for_node node, names = []
|
|
53
|
+
# set up a recursing function to search for asset tags
|
|
54
|
+
if node.is_a? Landable::Liquid::AssetTag
|
|
55
|
+
names << node.asset_name unless names.include? node.asset_name
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
if node.respond_to? :nodelist and node.nodelist
|
|
59
|
+
node.nodelist.each { |node| asset_names_for_node node, names }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
names
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
module ClassMethods
|
|
68
|
+
def assets_join_table_name
|
|
69
|
+
"#{Landable.configuration.database_schema_prefix}landable.#{self.name.underscore.split('/').last}_assets"
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module Landable
|
|
2
|
+
module TableName
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
model_name = self.model_name.element.pluralize
|
|
7
|
+
schema_name = "#{Landable.configuration.database_schema_prefix}landable"
|
|
8
|
+
self.table_name = "#{schema_name}.#{model_name}"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
end
|
|
12
|
+
end
|