add missing files for the last commit about the control editable element + implement feature #326
This commit is contained in:
parent
b3b0a5ac16
commit
6b8e3db8c3
BIN
app/assets/images/locomotive/icons/start.png
Normal file
BIN
app/assets/images/locomotive/icons/start.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.3 KiB |
@ -0,0 +1,24 @@
|
||||
Locomotive.Views.EditableElements ||= {}
|
||||
|
||||
class Locomotive.Views.EditableElements.ControlView extends Backbone.View
|
||||
|
||||
tagName: 'li'
|
||||
|
||||
className: 'control input'
|
||||
|
||||
render: ->
|
||||
$(@el).html(ich.editable_control_input(@model.toJSON()))
|
||||
|
||||
@bind_model()
|
||||
|
||||
return @
|
||||
|
||||
after_render: ->
|
||||
# do nothing
|
||||
|
||||
refresh: ->
|
||||
@bind_model()
|
||||
|
||||
bind_model: ->
|
||||
Backbone.ModelBinding.bind @, { select: 'class' }
|
||||
|
@ -1,24 +0,0 @@
|
||||
module Locomotive
|
||||
class InlineEditorMiddleware
|
||||
|
||||
def initialize(app, opts = {})
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
response = @app.call(env)
|
||||
|
||||
unless response[1]['Editable'].blank?
|
||||
html = response.last.body.to_s.gsub '</body>', %(
|
||||
<a href="_admin">Admin</a>
|
||||
</body>
|
||||
)
|
||||
[response[0], response[1], [html]]
|
||||
else
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
56
app/models/locomotive/editable_control.rb
Normal file
56
app/models/locomotive/editable_control.rb
Normal file
@ -0,0 +1,56 @@
|
||||
module Locomotive
|
||||
class EditableControl < EditableElement
|
||||
|
||||
## fields ##
|
||||
field :content
|
||||
field :options, :type => Array, :default => []
|
||||
|
||||
## methods ##
|
||||
|
||||
def options=(value)
|
||||
if value.respond_to?(:split)
|
||||
value = value.split(/\s*\,\s*/).map do |option|
|
||||
first, last = *option.split(/\s*=\s*/)
|
||||
last ||= first
|
||||
{ 'value' => first, 'text' => last }
|
||||
end
|
||||
end
|
||||
|
||||
super(value)
|
||||
end
|
||||
|
||||
def default_content?
|
||||
false
|
||||
end
|
||||
|
||||
def copy_attributes_from(el)
|
||||
super(el)
|
||||
|
||||
%w(content options).each do |meth|
|
||||
self.attributes[meth] = el.attributes[meth]
|
||||
end
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
||||
Locomotive::EditableControlPresenter.new(self).as_json
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def propagate_content
|
||||
if self.content_changed?
|
||||
operations = {
|
||||
'$set' => {
|
||||
'editable_elements.$.content' => self.content,
|
||||
'editable_elements.$.options' => self.options,
|
||||
}
|
||||
}
|
||||
|
||||
self.page.collection.update self._selector, operations, :multi => true
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
18
app/presenters/locomotive/editable_control_presenter.rb
Normal file
18
app/presenters/locomotive/editable_control_presenter.rb
Normal file
@ -0,0 +1,18 @@
|
||||
module Locomotive
|
||||
class EditableControlPresenter < EditableElementPresenter
|
||||
|
||||
delegate :content, :to => :source
|
||||
|
||||
def options
|
||||
self.source.options.map do |option|
|
||||
option['selected'] = option['value'] == self.source.content
|
||||
option
|
||||
end
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + %w(content options)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
4
doc/TODO
4
doc/TODO
@ -111,10 +111,10 @@ x missing custom_fields
|
||||
x many_to_many
|
||||
x simplify cells integration when modifying a menu from the main app
|
||||
x heroku module for locomotive
|
||||
- refactoring
|
||||
x refactoring
|
||||
x remove the import / export scripts
|
||||
x remove the cross domain authentication (use auth_token instead)
|
||||
- where to put Locomotive::InlineEditorMiddleware ?
|
||||
x where to put Locomotive::InlineEditorMiddleware ?
|
||||
x global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
|
||||
x override sort for contents
|
||||
|
||||
|
22
features/backoffice/editable_elements.feature
Normal file
22
features/backoffice/editable_elements.feature
Normal file
@ -0,0 +1,22 @@
|
||||
Feature: Manage Pages
|
||||
In order to manage pages
|
||||
As an administrator
|
||||
I want to add/edit/delete editable elements of my pages
|
||||
|
||||
Background:
|
||||
Given I have the site: "test site" set up
|
||||
And I am an authenticated user
|
||||
|
||||
@javascript
|
||||
Scenario: Insert a control element
|
||||
Given a page named "hello-world" with the template:
|
||||
"""
|
||||
{% block menu %}{% editable_control 'Menu position', options: 'top=Top of the Page,bottom=Bottom of the Page' %}bottom{% endeditable_control %}{% endblock %}
|
||||
"""
|
||||
When I go to the "hello-world" edition page
|
||||
Then "Bottom of the Page" should be selected for "page[editable_elements_attributes][0][content]"
|
||||
When I select "Top of the Page" from "page[editable_elements_attributes][0][content]"
|
||||
And I press "Save"
|
||||
Then I should see "Page was successfully updated."
|
||||
When I reload the page
|
||||
Then "Top of the Page" should be selected for "page[editable_elements_attributes][0][content]"
|
@ -77,7 +77,7 @@ module Locomotive
|
||||
self.app_middleware.insert_before Rack::Lock, '::Locomotive::Middlewares::Fonts', :path => %r{^/fonts}
|
||||
self.app_middleware.use '::Locomotive::Middlewares::SeoTrailingSlash'
|
||||
|
||||
self.app_middleware.use '::Locomotive::InlineEditorMiddleware' # TODO
|
||||
self.app_middleware.use '::Locomotive::Middlewares::InlineEditor'
|
||||
end
|
||||
|
||||
def self.configure_multi_sites
|
||||
|
31
lib/locomotive/liquid/tags/editable/control.rb
Normal file
31
lib/locomotive/liquid/tags/editable/control.rb
Normal file
@ -0,0 +1,31 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Tags
|
||||
module Editable
|
||||
class Control < Base
|
||||
|
||||
protected
|
||||
|
||||
def default_element_attributes
|
||||
if @nodelist.first.is_a?(String)
|
||||
super.merge(:content => @nodelist.first.try(:to_s), :options => @options[:options])
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def render_element(context, element)
|
||||
element.content
|
||||
end
|
||||
|
||||
def document_type
|
||||
EditableControl
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
::Liquid::Template.register_tag('editable_control', Control)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,3 +1,4 @@
|
||||
require 'locomotive/middlewares/fonts'
|
||||
require 'locomotive/middlewares/seo_trailing_slash'
|
||||
require 'locomotive/middlewares/cache'
|
||||
require 'locomotive/middlewares/cache'
|
||||
require 'locomotive/middlewares/inline_editor'
|
31
lib/locomotive/middlewares/inline_editor.rb
Normal file
31
lib/locomotive/middlewares/inline_editor.rb
Normal file
@ -0,0 +1,31 @@
|
||||
module Locomotive
|
||||
module Middlewares
|
||||
class InlineEditor
|
||||
|
||||
def initialize(app, opts = {})
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
response = @app.call(env)
|
||||
|
||||
unless response[1]['Editable'].blank?
|
||||
html = response.last.body.to_s.gsub '</body>', %(
|
||||
<a href="_admin"
|
||||
onmouseout="this.style.backgroundPosition='0px 0px'"
|
||||
onmouseover="this.style.backgroundPosition='0px -45px'"
|
||||
onmousedown="this.style.backgroundPosition='0px -90px'"
|
||||
onmouseup="this.style.backgroundPosition='0px 0px'"
|
||||
style="display: block;position:fixed;top: 10px; right: 10px;width: 48px; height: 45px;text-indent:-9999px;text-decoration:none;background: transparent url\('/assets/locomotive/icons/start.png'\) no-repeat 0 0;">
|
||||
Admin</a>
|
||||
</body>
|
||||
)
|
||||
[response[0], response[1], [html]]
|
||||
else
|
||||
response
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
70
spec/models/locomotive/editable_control_spec.rb
Normal file
70
spec/models/locomotive/editable_control_spec.rb
Normal file
@ -0,0 +1,70 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Locomotive::EditableControl do
|
||||
|
||||
before(:each) do
|
||||
@site = FactoryGirl.create(:site)
|
||||
@home = @site.pages.root.first
|
||||
end
|
||||
|
||||
describe '#simple' do
|
||||
|
||||
before(:each) do
|
||||
@home.update_attributes :raw_template => "{% block body %}{% editable_control 'menu', options: 'true=Yes,false=No' %}false{% endeditable_control %}{% endblock %}"
|
||||
|
||||
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
end
|
||||
|
||||
it 'exists' do
|
||||
@sub_page_1.editable_elements.size.should == 1
|
||||
end
|
||||
|
||||
it 'has a non-nil slug' do
|
||||
@sub_page_1.editable_elements.first.slug.should == 'menu'
|
||||
end
|
||||
|
||||
it 'has a default value' do
|
||||
@sub_page_1.editable_elements.first.content.should == 'false'
|
||||
end
|
||||
|
||||
it 'has a list of options' do
|
||||
@sub_page_1.editable_elements.first.options.should == [{ 'value' => 'true', 'text' => 'Yes' }, { 'value' => 'false', 'text' => 'No' }]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '"sticky" elements' do
|
||||
|
||||
before(:each) do
|
||||
@home.update_attributes :raw_template => "{% block body %}{% editable_control 'menu', options: 'true=Yes,false=No', fixed: true %}false{% endeditable_control %}{% endblock %}"
|
||||
@home_el = @home.editable_elements.first
|
||||
|
||||
@sub_page_1 = FactoryGirl.create(:page, :slug => 'sub_page_1', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
@sub_page_2 = FactoryGirl.create(:page, :slug => 'sub_page_2', :parent => @home, :raw_template => "{% extends 'parent' %}")
|
||||
|
||||
@sub_page_1_el = @sub_page_1.editable_elements.first
|
||||
@sub_page_2_el = @sub_page_2.editable_elements.first
|
||||
end
|
||||
|
||||
it 'exists in sub pages' do
|
||||
@sub_page_1.editable_elements.size.should == 1
|
||||
@sub_page_2.editable_elements.size.should == 1
|
||||
end
|
||||
|
||||
it 'is marked as fixed' do
|
||||
@sub_page_1_el.fixed?.should be_true
|
||||
@sub_page_2_el.fixed?.should be_true
|
||||
end
|
||||
|
||||
it 'gets also updated when updating the very first element' do
|
||||
@home_el.content = 'true'
|
||||
@home.save
|
||||
@sub_page_1.reload; @sub_page_1_el = @sub_page_1.editable_elements.first
|
||||
@sub_page_2.reload; @sub_page_2_el = @sub_page_2.editable_elements.first
|
||||
@sub_page_1_el.content.should == 'true'
|
||||
@sub_page_2_el.content.should == 'true'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue
Block a user