fix the template_for method of the page repository + implement the sitemap middleware (feature #36)

did committed Mar 24, 2015
commit aa2885c13738c9a83c5c971f0a97abd0f9908cce
Showing 8 changed files with 185 additions and 8 deletions
locomotive/steam/adapters/filesystem/sanitizers/page.rb b/lib/locomotive/steam/adapters/filesystem/sanitizers/page.rb +9 -3
@@ @@ -73,7 +73,7 @@ module Locomotive::Steam
if content_type = fetch_content_type(parent_fullpath(page))
# not a templatized page but it becomes one because
# its parent is one of them
- page[:content_type] = content_type
+ _modify_if_templatized(page, content_type)
end
end
@@ @@ -140,12 +140,18 @@ module Locomotive::Steam
end
def modify_if_templatized(page, locale)
- if page.templatized?
+ if content_type = page[:content_type]
+ _modify_if_templatized(page, content_type)
page[:slug][locale] = Locomotive::Steam::WILDCARD
- set_content_type(page[:_fullpath], page.content_type)
+ set_content_type(page[:_fullpath], content_type)
end
end
+ def _modify_if_templatized(page, content_type)
+ page[:templatized] = true
+ page[:target_klass_name] = "Locomotive::ContentEntry#{content_type}"
+ end
+
end
end
locomotive/steam/entities/content_entry.rb b/lib/locomotive/steam/entities/content_entry.rb +4 -0
@@ @@ -53,6 +53,10 @@ module Locomotive::Steam
content_type.slug
end
+ def _class_name
+ "Locomotive::ContentEntry#{content_type_id}"
+ end
+
def _label
self[content_type.label_field_name]
end
locomotive/steam/entities/page.rb b/lib/locomotive/steam/entities/page.rb +5 -2
@@ @@ -11,8 +11,10 @@ module Locomotive::Steam
handle: nil,
listed: false,
published: true,
+ templatized: false,
fullpath: {},
content_type: nil,
+ target_klass_name: nil,
position: 99,
raw_template: nil,
source: nil,
@@ @@ -26,9 +28,10 @@ module Locomotive::Steam
def listed?; !!listed; end
def published?; !!published; end
+ def templatized?; !!templatized; end
- def templatized?
- !!content_type
+ def content_type_id
+ # TODO
end
def index?
locomotive/steam/middlewares/sitemap.rb b/lib/locomotive/steam/middlewares/sitemap.rb +103 -0
@@ @@ -0,0 +1,103 @@
+ module Locomotive::Steam
+ module Middlewares
+
+ class Sitemap < ThreadSafe
+
+ include Helpers
+
+ def _call
+ if env['PATH_INFO'] == '/sitemap.xml'
+ render_response(build_xml.tap { |o| puts o }, 200, 'text/plain')
+ end
+ end
+
+ private
+
+ def build_xml
+ <<-EOF
+ <?xml version="1.0" encoding="UTF-8"?>
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+ <url>
+ <loc>#{base_url}</loc>
+ <priority>1.0</priority>
+ </url>
+ #{build_pages_to_xml}
+ </urlset>
+ EOF
+ end
+
+ def build_pages_to_xml
+ repositories.page.published.map do |page|
+ next if page.index? || page.not_found?
+
+ build_page_xml(page)
+ end.flatten.join
+ end
+
+ def build_page_xml(page)
+ _page = Locomotive::Steam::Decorators::I18nDecorator.new(page)
+
+ site.locales.map do |locale|
+ _page.__locale__ = locale
+
+ if _page.templatized?
+ build_templatized_page_xml(_page, locale)
+ elsif !_page.title.blank? # should be translated
+ page_to_xml(_page, locale)
+ end
+ end
+ end
+
+ def build_templatized_page(page, locale)
+ content_type = repositories.content_type.
+ # TODO
+ end
+
+ def page_to_xml(page, locale)
+ <<-EOF
+ <url>
+ <loc>#{base_url}#{url_for(page, locale)}</loc>
+ <lastmod>#{page.updated_at.to_date.to_s('%Y-%m-%d')}</lastmod>
+ <priority>0.9</priority>
+ </url>
+ EOF
+ end
+
+ def repositories
+ services.repositories
+ end
+
+ def url_for(page, locale = nil)
+ services.url_builder.url_for(page, locale)
+ end
+
+ def base_url
+ "#{request.scheme}://#{request.host_with_port}"
+ end
+
+ end
+
+ # @pages.each do |page|
+ # if not page.index_or_not_found?
+ # if page.templatized?
+ # page.fetch_target_entries(_visible: true).each do |c|
+ # if c._slug.present?
+ # xml.url do
+ # xml.loc public_page_url(page, { content: c })
+ # xml.lastmod c.updated_at.to_date.to_s('%Y-%m-%d')
+ # xml.priority 0.9
+ # end
+ # end
+ # end
+ # else
+ # xml.url do
+ # xml.loc public_page_url(page)
+ # xml.lastmod page.updated_at.to_date.to_s('%Y-%m-%d')
+ # xml.priority 0.9
+ # end
+ # end
+ # end
+ # end
+
+ end
+ end
locomotive/steam/repositories/page_repository.rb b/lib/locomotive/steam/repositories/page_repository.rb +8 -1
@@ @@ -19,6 +19,13 @@ module Locomotive
end.all
end
+ def published
+ query do
+ where(published: true).
+ order_by(depth: :asc, position: :asc)
+ end.all
+ end
+
def by_handle(handle)
first { where(handle: handle) }
end
@@ @@ -32,7 +39,7 @@ module Locomotive
end
def template_for(entry, handle = nil)
- conditions = { templatized?: true, content_type: entry.try(:content_type_slug) }
+ conditions = { templatized: true, target_klass_name: entry.try(:_class_name) }
conditions[:handle] = handle if handle
locomotive/steam/server.rb b/lib/locomotive/steam/server.rb +1 -0
@@ @@ -49,6 +49,7 @@ module Locomotive::Steam
Middlewares::Site,
Middlewares::Logging,
Middlewares::Robots,
+ Middlewares::Sitemap,
Middlewares::Timezone,
Middlewares::EntrySubmission,
Middlewares::Locale,
spec/integration/repositories/page_repository_spec.rb +11 -2
@@ @@ -31,6 +31,15 @@ describe Locomotive::Steam::PageRepository do
it { expect(subject.title[:en]).to eq 'News archive' }
end
+ describe '#template_for' do
+ let(:type_repository) { Locomotive::Steam::ContentTypeRepository.new(adapter, site, locale) }
+ let(:type) { type_repository.by_slug('songs') }
+ let(:entry_repository) { Locomotive::Steam::ContentEntryRepository.new(adapter, site, locale, type_repository).with(type) }
+ let(:entry) { entry_repository.by_slug('song-number-1') }
+ subject { repository.template_for(entry) }
+ it { expect(subject.title[:en]).to eq 'A song template' }
+ end
+
describe '#matching_fullpath' do
subject { repository.matching_fullpath(['songs/content_type_template', 'content_type_template/songs', 'songs/song-number-1']) }
it { expect(subject.size).to eq 2 }
@@ @@ -73,8 +82,8 @@ describe Locomotive::Steam::PageRepository do
it_should_behave_like 'a repository' do
- let(:site_id) { BSON::ObjectId.from_string('54eb49c12475804b2b000002') }
- let(:adapter) { Locomotive::Steam::MongoDBAdapter.new(database: 'steam_test', hosts: ['127.0.0.1:27017']) }
+ let(:site_id) { BSON::ObjectId.from_string('54eb49c12475804b2b000002') }
+ let(:adapter) { Locomotive::Steam::MongoDBAdapter.new(database: 'steam_test', hosts: ['127.0.0.1:27017']) }
end
spec/integration/server/sitemap_spec.rb +44 -0
@@ @@ -0,0 +1,44 @@
+ require File.dirname(__FILE__) + '/../integration_helper'
+
+ describe Locomotive::Steam::Server do
+
+ include Rack::Test::Methods
+
+ def app
+ run_server
+ end
+
+ describe 'sitemap.xml' do
+
+ subject { get '/sitemap.xml'; last_response.body }
+
+ it 'displays code for the first time' do
+ is_expected.to eq <<-EOF
+ <?xml version="1.0" encoding="UTF-8"?>
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+ <url>
+ <loc>http://example.org</loc>
+ <priority>1.0</priority>
+ </url>
+ <url>
+ <loc>http://example.org/articles</loc>
+ <lastmod>:now</lastmod>
+ <priority>0.9</priority>
+ </url>
+ <url>
+ <loc>http://example.org/articles/hello-world</loc>
+ <lastmod>:now</lastmod>
+ <priority>0.9</priority>
+ </url>
+ <url>
+ <loc>http://example.org/articles/lorem-ipsum</loc>
+ <lastmod>:now</lastmod>
+ <priority>0.9</priority>
+ </url>
+ </urlset>
+ EOF
+ end
+
+ end
+
+ end