made very good progress, almost usable

This commit is contained in:
did 2011-08-17 22:32:39 +02:00
parent c68eb321ff
commit ad68826e84
22 changed files with 265 additions and 47 deletions

View File

@ -27,7 +27,7 @@ gem 'carrierwave', '0.5.6'
gem 'dragonfly', '~> 0.9.1'
gem 'rack-cache', :require => 'rack/cache'
gem 'custom_fields', '1.0.0.beta.22'
gem 'custom_fields', '1.0.0.beta.23'
gem 'cancan'
gem 'fog', '0.8.2'
gem 'mimetype-fu'

View File

@ -87,7 +87,7 @@ GEM
capybara (>= 1.0.0)
cucumber (~> 1.0.0)
nokogiri (>= 1.4.6)
custom_fields (1.0.0.beta.22)
custom_fields (1.0.0.beta.23)
activesupport (~> 3.0.9)
mongoid (= 2.0.2)
daemons (1.1.4)
@ -300,7 +300,7 @@ DEPENDENCIES
carrierwave (= 0.5.6)
cells
cucumber-rails (= 1.0.2)
custom_fields (= 1.0.0.beta.22)
custom_fields (= 1.0.0.beta.23)
database_cleaner
delayed_job (= 2.1.4)
delayed_job_mongoid (= 1.0.2)

View File

@ -90,6 +90,10 @@ module Admin
I18n.site_locale = session[:site_locale]
end
def back_to_default_site_locale
session[:site_locale] = I18n.site_locale = current_site.default_locale
end
# ___ site/page urls builder ___
def current_site_url

View File

@ -11,6 +11,8 @@ module Admin
before_filter :authorize_content
before_filter :back_to_default_site_locale, :only => %w(new create)
helper_method :breadcrumb_root, :breadcrumb_url, :back_url
def index

View File

@ -5,6 +5,8 @@ module Admin
respond_to :json, :only => [:update, :sort, :get_path]
before_filter :back_to_default_site_locale, :only => %w(new create)
def index
@pages = current_site.all_pages_in_once
end

View File

@ -9,6 +9,8 @@ class ContentInstance
include Extensions::Shared::Seo
## fields (dynamic fields) ##
localized_fields :_position_in_list, /^custom_field_/
field :_slug
field :_position_in_list, :type => Integer, :default => 0
field :_visible, :type => Boolean, :default => true

View File

@ -1,23 +1,24 @@
class EditableElement
include Mongoid::Document
include Mongoid::Document
include Mongoid::I18n
## fields ##
field :slug
field :block
field :default_content
field :default_attribute
field :hint
field :disabled, :type => Boolean, :default => false
field :assignable, :type => Boolean, :default => true
field :from_parent, :type => Boolean, :default => false
## fields ##
field :slug
field :block
localized_field :default_content
field :default_attribute
field :hint
field :disabled, :type => Boolean, :default => false
field :assignable, :type => Boolean, :default => true
field :from_parent, :type => Boolean, :default => false
## associations ##
embedded_in :page, :inverse_of => :editable_elements
## associations ##
embedded_in :page, :inverse_of => :editable_elements
## validations ##
validates_presence_of :slug
## validations ##
validates_presence_of :slug
## methods ##
## methods ##
end

View File

@ -1,7 +1,11 @@
class EditableFile < EditableElement
localized_fields :source_filename
mount_uploader :source, EditableFileUploader
# localized_field :source
def content
self.source? ? self.source.url : self.default_content
end

View File

@ -1,12 +1,19 @@
class EditableShortText < EditableElement
## fields ##
field :content
localized_field :content
## methods ##
def content
self.read_attribute(:content).blank? ? self.default_content : self.read_attribute(:content)
# def content
# self.read_attribute(:content).blank? ? self.default_content : self.read_attribute(:content)
# end
def content_with_localization
value = self.content_without_localization
value.blank? ? self.default_content : value
end
alias_method_chain :content, :localization
end

View File

@ -5,9 +5,9 @@ module Extensions
extend ActiveSupport::Concern
included do
field :serialized_template, :type => Binary
field :template_dependencies, :type => Array, :default => []
field :snippet_dependencies, :type => Array, :default => []
localized_field :serialized_template, :type => Binary
localized_field :template_dependencies, :type => Array, :default => []
localized_field :snippet_dependencies, :type => Array, :default => []
attr_reader :template_changed
@ -22,7 +22,7 @@ module Extensions
module InstanceMethods
def template
@template ||= Marshal.load(read_attribute(:serialized_template).to_s) rescue nil
@template ||= Marshal.load(self.serialized_template.to_s) rescue nil
end
protected

View File

@ -1,3 +1,5 @@
require 'ruby-debug'
module Extensions
module Page
module Render

View File

@ -17,7 +17,7 @@ class Page
localized_field :title
localized_field :slug
localized_field :fullpath
field :raw_template
localized_field :raw_template
field :published, :type => Boolean, :default => false
field :cache_strategy, :default => 'none'
@ -62,6 +62,10 @@ class Page
self.index? || self.not_found?
end
def default_slug
I18n.with_site_locale(I18n.default_site_locale) { self.slug }
end
def fullpath_with_building(force = false)
if self.fullpath_without_building.present? && !force
self.fullpath_without_building
@ -78,6 +82,16 @@ class Page
alias_method_chain :fullpath, :building
def fullpath_with_locale(locale)
url, locale = self.fullpath(true), locale.to_s
if locale != self.site.default_locale
url = File.join(locale, url)
end
url
end
def with_cache?
self.cache_strategy != 'none'
end

View File

@ -11,24 +11,26 @@ BOARD:
x rendering engine
x get locale
x render the right version
- contents
x contents
x store the site locale value
- pages
x pages
x title / slug / fullpath / seo
- template ?
- editable contents
- custom contents
- snippets
x template
x editable contents
x custom contents (models)
(- snippets)
x site
x seo
x locale picker
- liquid tags:
x locale switcher
x nav
- link_to (new)
- nav
- locale switcher
- others ? -
(- others ?) -
- other problems to solve:
- If you create a new page it shall always be created in the default_language, not depending on the used language in the backend.
x If you create a new page it shall always be created in the default_language, not depending on the used language in the backend.
- redirect for the default site locale if urls like /<default_site_locale>/....
- inline editing
BACKLOG:

View File

@ -24,7 +24,7 @@ module CustomFields
class Item
def to_liquid
{ 'id' => self._id, 'name' => self.name }
{ 'id' => self._id.to_s, 'name' => self.name }
end
end

View File

@ -1,3 +1,4 @@
# require 'ruby-debug'
## patches for the i18n support (aka multi languages support)
require 'i18n'
@ -33,13 +34,91 @@ module I18n
end
DELEGATORS
end
# Executes block with given I18n.site_locale set.
def with_site_locale(tmp_locale = nil)
if tmp_locale
current_locale = self.site_locale
self.site_locale = tmp_locale
end
yield
ensure
self.site_locale = current_locale if tmp_locale
end
end
end
## CARRIERWAVE ##
require 'carrierwave/orm/mongoid'
module CarrierWave
module Mongoid
def mount_uploader_with_localization(column, uploader=nil, options={}, &block)
mount_uploader_without_localization(column, uploader, options, &block)
define_method(:read_uploader) { |name| self.send(name.to_sym) }
define_method(:write_uploader) { |name, value| self.send(:"#{name.to_sym}=", value) }
end
alias_method_chain :mount_uploader, :localization
end
end
## MONGOID-I18n ##
# TODO: fork https://github.com/Papipo/mongoid_i18n
module Mongoid
module Criterion
class Selector< Hash
def []=(key, value)
key = "#{key}.#{::I18n.site_locale}" if fields[key.to_s].try(:type) == Mongoid::I18n::LocalizedField
super
end
end
end
module I18n
included do
cattr_accessor :localized_fields_list
end
module ClassMethods
def localized_fields(*args)
self.localized_fields_list = [*args].collect
end
def field(name, options = {})
if localized_field?(name)
options.merge!(:type => LocalizedField, :default => LocalizedField.new)
end
super
end
protected
def localized_field?(name)
# puts "options[:type] = #{options[:type].inspect} / #{(options[:type] == LocalizedField).inspect}"
# return true if options[:type] == LocalizedField
# puts "self.localized_fields_list = #{self.localized_fields_list.inspect} / #{meth.inspect}"
(self.localized_fields_list || []).any? do |rule|
case rule
when String, Symbol then name.to_s == rule.to_s
when Regexp then !(name.to_s =~ rule).nil?
else
false
end
end.tap do |result|
# options[:type] = LocalizedField if result
# puts "#{name.inspect}... localized ? #{result.inspect}"
end
end
def create_accessors(name, meth, options = {})
if options[:type] == LocalizedField
if options[:use_default_if_empty] != false # nil or true
@ -62,12 +141,13 @@ module Mongoid
end
end
define_method("#{meth}=") do |value|
puts "@attributes[name].present? = #{@attributes[name].present?.inspect} / !@attributes[name].is_a?(Hash) #{(!@attributes[name].is_a?(Hash)).inspect}"
# debugger
# puts "@attributes[name].present? = #{@attributes[name].present?.inspect} / !@attributes[name].is_a?(Hash) #{(!@attributes[name].is_a?(Hash)).inspect}"
if !@attributes[name].nil? && !@attributes[name].is_a?(Hash)
@attributes[name] = { ::I18n.default_site_locale.to_s => @attributes[name] }
end
puts "value = #{value.inspect} / #{meth}"
# puts "value = #{value.inspect} / #{meth}"
value = if value.is_a?(Hash)
(@attributes[name] || {}).merge(value)

View File

@ -21,6 +21,10 @@ module Locomotive
self._source.highlighted_field_value
end
def _permalink
self._source._permalink
end
end
end
end

View File

@ -30,7 +30,8 @@ module Locomotive
:default_content => default_content_option,
:assignable => @options[:assignable],
:disabled => false,
:from_parent => false
:from_parent => false,
:_type => self.document_type.to_s
}, document_type)
end
end

View File

@ -0,0 +1,76 @@
module Locomotive
module Liquid
module Tags
# Display the links to change the locale of the current page
#
# Usage:
#
# {% locale_switcher %} => <div id="locale-switcher"><a href="/features" class="current en">Features</a><a href="/fr/fonctionnalites" class="fr">Fonctionnalités</a></div>
#
# {% locale_switcher label: locale, sep: ' - ' }
#
# options:
# - label: iso (de, fr, en, ...etc), locale (Deutsch, Français, English, ...etc), title (page title)
# - sep: piece of html code seperating 2 locales
#
# notes:
# - "iso" is the default choice for label
# - " | " is the default seperating code
#
class LocaleSwitcher < ::Liquid::Tag
Syntax = /(#{::Liquid::Expression}+)?/
def initialize(tag_name, markup, tokens, context)
@options = { :label => 'iso', :sep => ' | ' }
if markup =~ Syntax
markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value.gsub(/"|'/, '') }
@options[:exclude] = Regexp.new(@options[:exclude]) if @options[:exclude]
else
raise ::Liquid::SyntaxError.new("Syntax Error in 'locale_switcher' - Valid syntax: locale_switcher <options>")
end
super
end
def render(context)
site = context.registers[:site]
current_page = context.registers[:page]
output = %(<div id="locale-switcher">)
output += site.locales.collect do |locale|
I18n.with_site_locale(locale) do
url = current_page.fullpath_with_locale(locale)
if current_page.templatized?
url.gsub!('content_type_template', context['content_instance']._permalink)
end
%(<a href="/#{url}" class="#{locale} #{'current' if locale == context['current_locale']}">#{link_label(current_page)}</a>)
end
end.join(@options[:sep])
output += %(</div>)
end
private
def link_label(current_page)
case @options[:label]
when :iso then I18n.site_locale
when :locale then I18n.t("admin.locales.#{I18n.site_locale}", :locale => I18n.site_locale)
when :title then current_page.title
else
I18n.site_locale
end
end
end
::Liquid::Template.register_tag('locale_switcher', LocaleSwitcher)
end
end
end

View File

@ -76,8 +76,8 @@ module Locomotive
icon = @options[:icon] ? '<span></span>' : ''
label = %{#{icon if @options[:icon] != 'after' }#{page.title}#{icon if @options[:icon] == 'after' }}
output = %{<li id="#{page.slug.dasherize}-link" class="link#{selected} #{css}">}
output << %{<a href="/#{page.fullpath}">#{label}</a>}
output = %{<li id="#{page.default_slug.dasherize}-link" class="link#{selected} #{css}">}
output << %{<a href="/#{page.fullpath_with_locale(I18n.site_locale)}">#{label}</a>}
output << render_entry_children(page, depth.succ) if (depth.succ <= @options[:depth].to_i)
output << %{</li>}
@ -90,7 +90,7 @@ module Locomotive
children = page.children_with_minimal_attributes.reject { |c| !include_page?(c) }
if children.present?
output = %{<ul id="#{@options[:id]}-#{page.slug.dasherize}">}
output = %{<ul id="#{@options[:id]}-#{page.default_slug.dasherize}">}
children.each do |c, page|
css = []
css << 'first' if children.first == c
@ -115,8 +115,9 @@ module Locomotive
end
end
::Liquid::Template.register_tag('nav', Nav)
end
::Liquid::Template.register_tag('nav', Nav)
end
end
end

View File

@ -42,7 +42,7 @@ module Locomotive
page_count, current_page = pagination['total_pages'], pagination['current_page']
path = context.registers[:page].fullpath
path = context.registers[:page].fullpath_with_locale(I18n.site_locale)
pagination['previous'] = link(I18n.t('pagination.previous'), current_page - 1, path) if pagination['previous_page']
pagination['next'] = link(I18n.t('pagination.next'), current_page + 1, path) if pagination['next_page']

View File

@ -17,7 +17,9 @@ module Locomotive
render_no_page_error and return if @page.nil?
output = @page.render(locomotive_context)
output = I18n.with_locale(I18n.site_locale) do
@page.render(locomotive_context)
end
self.prepare_and_set_response(output)
end
@ -96,7 +98,7 @@ module Locomotive
:current_admin => current_admin
}
::Liquid::Context.new({}, assigns, registers)
::Liquid::Context.new({}, assigns, registers, true)
end
def prepare_and_set_response(output)

View File

@ -29,6 +29,20 @@ namespace :locomotive do
end
end
desc 'Prepare for i18n'
task :prepare_for_i18n => :environment do
Page.skip_callback(:validate, :before)
Page.skip_callback(:save, :after)
I18n.with_site_locale(ENV['LOCALE'] || Locomotive.config.site_locales.first) do
Page.all.each do |page|
page.template_dependencies = page.template_dependencies
page.snippet_dependencies = page.snippet_dependencies
page.save(:validate => false)
end
end
end
desc 'Import a remote template described by its URL -- 2 options: SITE=name or id, RESET=by default false'
task :import => :environment do
url, site_name_or_id, reset = ENV['URL'], ENV['SITE'], Boolean.set(ENV['RESET']) || false