use the last version of formtastic + tweak the css for formtastic with scss + compass (wip) + clean code (wip)

This commit is contained in:
did 2011-11-09 02:35:59 +01:00
parent 1b015efd48
commit 248d3803c2
35 changed files with 537 additions and 535 deletions

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
.bundle
db/*.sqlite3
log/*.log
log
tmp/**/*
.DS_Store
rerun.txt

View File

@ -29,8 +29,8 @@ gem 'rails-backbone', '0.5.4'
gem 'handlebars-rails', :git => 'git://github.com/yabawock/handlebars-rails.git'
gem 'locomotive_liquid', '2.2.2', :require => 'liquid'
gem 'formtastic', '~> 1.2.3' # TODO: UPGRADE IT
gem 'inherited_resources', '~> 1.3.0'
gem 'formtastic', '~> 2.0.2' # TODO: UPGRADE IT
gem 'responders', '~> 0.6.0'
gem 'cells', '~> 3.7.0'
gem 'RedCloth', '~> 4.2.8'
gem 'sanitize', '~> 2.0.3'

View File

@ -154,25 +154,19 @@ GEM
nokogiri (~> 1.5.0)
ruby-hmac
formatador (0.2.1)
formtastic (1.2.4)
actionpack (>= 2.3.7)
activesupport (>= 2.3.7)
i18n (~> 0.4)
formtastic (2.0.2)
rails (~> 3.0)
fssm (0.2.7)
gherkin (2.6.2)
json (>= 1.4.6)
growl-glue (1.0.7)
haml (3.1.3)
has_scope (0.5.1)
highline (1.6.2)
hike (1.2.1)
httparty (0.8.1)
multi_json
multi_xml
i18n (0.6.0)
inherited_resources (1.3.0)
has_scope (~> 0.5.0)
responders (~> 0.6.0)
jquery-rails (1.0.16)
railties (~> 3.0)
thor (~> 0.14)
@ -344,13 +338,12 @@ DEPENDENCIES
dragonfly (~> 0.9.8)
factory_girl_rails (~> 1.1)
fog (~> 1.0.0)
formtastic (~> 1.2.3)
formtastic (~> 2.0.2)
growl-glue
haml (~> 3.1.3)
handlebars-rails!
highline (~> 1.6.2)
httparty (~> 0.8.1)
inherited_resources (~> 1.3.0)
jquery-rails (~> 1.0.16)
launchy
linecache (= 0.43)
@ -365,6 +358,7 @@ DEPENDENCIES
rails (~> 3.1.1)
rails-backbone (= 0.5.4)
rake (= 0.9.2)
responders (~> 0.6.0)
rmagick (= 2.12.2)
rspec-cells
rspec-rails (= 2.6.1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -6,5 +6,6 @@
*= require_tree ../../../vendor/assets/stylesheets/jquery
*= require ../../../vendor/assets/stylesheets/blueprint/screen.css
*= require formtastic
*= require_tree ./locomotive
*/

View File

@ -13,9 +13,9 @@
border: 1px solid #000;
@include border-radius(5px);
line-height: 30px;
line-height: 17px !important;
padding: 0 10px;
padding: 5px 10px 7px 10px;
@include background-image(linear-gradient(top, #474850, #1f2027));
@include box-shadow(rgba(0, 0, 0, 0.3) 1px 1px 0px 0px);
@ -29,6 +29,37 @@
@include background-image(linear-gradient(top, #575862, #2f303b));
}
&:active {
top: 1px;
}
}
@mixin light-button {
display: inline-block;
font-family: "Lucida Grande";
position: relative;
cursor: pointer;
line-height: 12px;
padding: 8px 10px 10px 10px;
border: 0px;
border-top: 1px solid rgba(255, 255, 255, 0.6);
@include border-radius(5px);
@include background-image(linear-gradient(top, #ebedf4, #d2d6e1));
@include box-shadow(rgba(0, 0, 0, 0.3) 1px 1px 0px 0px);
font-size: 12px;
color: #6B6D7A;
text-decoration: none;
@include text-shadow(rgba(255, 255, 255, 0.8), 0px, 1px, 0px);
&:hover {
@include background-image(linear-gradient(top, #fff, #d7dbe7));
}
&:active {
top: 1px;
}

View File

@ -55,6 +55,11 @@ ul.list {
li {
position: relative;
height: 31px;
background: #ebedf4;
@include border-radius(16px);
border-bottom: 1px solid #d9d9d9;
margin-bottom: 10px;
clear: both;
@ -63,14 +68,14 @@ ul.list {
float: left;
height: 31px;
width: 18px;
background: transparent image-url("locomotive/list/item-left.png") no-repeat left 0;
// background: transparent image-url("locomotive/list/item-left.png") no-repeat left 0;
}
strong {
display: block;
height: 31px;
margin-left: 18px;
background: transparent image-url("locomotive/list/item-right.png") no-repeat right 0;
// background: transparent image-url("locomotive/list/item-right.png") no-repeat right 0;
a {
position: relative;
@ -113,3 +118,198 @@ ul.list {
} // li div.more
} // ul.list li
}
ul.theme-assets {
margin-left: 40px;
li.hidden strong a { font-style: italic; color: #8B8D9A; font-weight: normal; }
}
#contents-list li {
background: none;
li {
em {
background-position: left -31px;
cursor: move;
}
strong {
display: block;
height: 31px;
margin-left: 18px;
background: transparent image-url("locomotive/list/item-right.png") no-repeat right 0;
}
}
}
#pages-list {
margin: 0px 0 20px 0;
background: #fff;
li.sep {
margin: 11px 0 10px 0;
height: 1px;
border-top: 1px dotted #bbbbbd;
}
li.page {
.inner {
position: relative;
margin-bottom: 10px;
height: 30px;
clear: both;
background: #ebedf4;
@include border-radius(16px);
border-bottom: 1px solid #d9d9d9;
em {
display: block;
position: absolute;
top: 5px;
left: 0px;
height: 22px;
width: 18px;
background: transparent image-url("locomotive/list/item-left.png") no-repeat 0 0;
}
&.toggler {
position: absolute;
top: 9px;
left: -15px;
cursor: pointer;
}
a {
@include hover-link;
position: relative;
top: 4px;
margin-left: 26px;
color: #1f82bc;
font-size: 14px;
font-weight: bold;
@include single-text-shadow(#fff, 1px, 1px, 1px);
}
&.hidden a { font-style: italic; font-weight: normal; }
.more {
position: absolute;
top: 0px;
right: 20px;
font-size: 11px;
color: #8b8d9a;
a {
margin-left: 7px;
outline: none;
}
}
} // li .inner
&.index, &.not-found {
> .inner {
a {
margin-left: 20px;
}
.more {
padding-top: 7px;
}
}
}
} // #pages-list li
ul {
margin: 10px 0 10px 40px;
li {
.more {
padding-top: 3px !important;
}
}
&.folder {
li {
em {
background-position: left -31px;
cursor: move;
}
&.templatized > strong a {
padding-right: 24px;
background: transparent image-url("locomotive/list/icons/template.png") no-repeat right 3px;
}
&.redirect > strong a {
background: transparent image-url("locomotive/list/icons/redirect.png") no-repeat right 2px;
}
} // ul.folder li
} // ul.folder
} // ul
} // #pages-list
/* ___ Progress bar ___ */
#progressbar-wrapper {
margin: 40px 0;
height: 30px;
#progressbar {
height: 100%;
}
}
/* ___ import steps ___ */
#import-steps {
margin: 0px 200px;
li {
strong a { color: #b7baca; }
.more .states {
position: relative;
top: 4px;
height: 16px;
width: 16px;
background: transparent image-url("locomotive/list/icons/states.png") no-repeat 0 0;
}
&.done {
strong a { color: #1F82BC; }
.more .states {
background-position: 0 -16px;
}
}
&.failed .more .states {
background-position: 0 -32px;
}
}
}
/* ___ paragraph (for help for example) ___ */
p span.code {
padding: 2px 3px;
background: #EBEDF4;
color: #8B8D9A;
@include single-text-shadow(#fff, 0px, 0px, 1px);
}

View File

@ -0,0 +1,115 @@
@import "compass/css3";
@import "compass/css3/border-radius";
@import "compass/css3/images";
@import "compass/css3/text-shadow";
@import "helpers";
form.formtastic {
fieldset {
legend {
display: block;
width: 100%;
padding: 5px 0px;
@include border-top-radius(16px);
@include background-image(linear-gradient(#ebedf4, #d7dbe7));
span {
padding-left: 20px;
font-size: 13px;
font-weight: bold;
@include single-text-shadow(#fff, 1px, 1px, 1px);
}
} // legend
ol {
margin-bottom: 20px;
padding: 0px;
border-top: 1px solid #ccced7;
@include border-bottom-radius(16px);
background: #ebedf4;
> li {
margin: 0;
padding: 10px 20px 16px 20px;
background: transparent image-url("locomotive/form/input-sep.png") repeat-x 0 bottom;
&:last-child {
background: none;
// padding-bottom: 0px;
margin-bottom: 0px;
}
label {
width: 160px;
padding: 0px 0 0 0px;
font-size: 13px;
text-align: left;
color: #585A69;
@include single-text-shadow(#fff, 1px, 1px, 1px);
}
p.inline-hints {
margin: 5px 0 0 160px;
a {
color: #1f82bc;
}
.code {
background-color: #c8cad0;
color: #5E5F64;
@include single-text-shadow(rgba(255, 255, 255, 0.8), 0px, 1px, 1px);
}
} // p.inline-hints
div.inline-errors {
margin: 2px 0 0 160px;
padding: 8px 0 0 0;
background: transparent image-url("locomotive/form/error-arrow.png") no-repeat 17px 0;
p {
display: inline-block;
width: auto;
margin: 0px;
padding: 3px 12px 4px 30px;
background: #cd0f19 image-url("locomotive//form/icons/error.png") no-repeat 10px 6px;
color: #fff !important;
@include single-text-shadow(#000, 0px, 1px, 1px);
}
} // div.inline-errors
&.string {
label {
padding-top: 2px;
}
input[type=text] {
width: 700px;
padding: 4px 5px;
color: #17171B;
font-size: 14px;
font-weight: bold;
border: 1px solid #b5b7c4;
@include background-image(linear-gradient(top, #f0f0f0, #f9f9f9 25%, #f9f9f9 25%, #ffffff 50%, #ffffff));
}
} // li.string
} // > li
} //ol
} // fieldset
}

View File

@ -0,0 +1,7 @@
/*
* This is a manifest file that'll automatically include all the stylesheets available in this directory
* and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
* the top of the compiled file, but it's generally better to create a new file per style scope.
*= require_self
*= require ../../../../vendor/assets/stylesheets/blueprint/screen.css
*/

View File

@ -3,12 +3,18 @@
@import "compass/css3/images";
@import "compass/css3/text-shadow";
@import "helpers";
@import "buttons";
body {
background: #000 image-url("locomotive/background/body.png") repeat 0 0;
font-size: 12px;
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
ul {
list-style: none;
padding: 0px;
}
/* ___ Alignements ___ */
.tcenter { text-align: center; }
@ -86,6 +92,9 @@ body {
background: #fff;
@include box-shadow(rgba(0, 0, 0, 0.6) 0px 1px 4px 3px);
@include border-bottom-radius(3px);
min-height: 150px;
h2 {
@ -131,7 +140,7 @@ body {
#local-actions-bar {
position: absolute;
top: 13px;
top: 18px;
right: 15px;
a {
@ -177,16 +186,20 @@ body {
#local-actions-bottom-bar {
position: relative;
top: 27px;
top: 20px;
left: -15px;
width: 950px;
background: #8b8d9a;
border-top: 1px solid #5f6069;
@include border-bottom-radius(3px);
p {
padding: 15px;
margin: 0px;
line-height: 13px;
a {
position: relative;
top: 4px;
@ -199,6 +212,10 @@ body {
}
}
input[type=submit] {
@include light-button;
}
.last p { text-align: right; }
} // #content #local-actions-bottom-bar
} // #content

View File

@ -1,5 +1,5 @@
module Locomotive
class BaseController < InheritedResources::Base
class BaseController < ApplicationController
include Locomotive::Routing::SiteDispatcher
@ -25,9 +25,7 @@ module Locomotive
# helper "locomotive/#{File.basename(file, '.rb').gsub(/_helper$/, '')}"
# end
self.responder = Locomotive::AdminResponder # custom responder
defaults :route_prefix => 'locomotive'
self.responder = Locomotive::Responder # custom responder
respond_to :html
@ -66,15 +64,15 @@ module Locomotive
before_filter do |c|
sub = sub.call(c) if sub.respond_to?(:call)
sections = { :main => main, :sub => sub }
c.instance_variable_set(:@admin_sections, sections)
c.instance_variable_set(:@locomotive_sections, sections)
end
end
def sections(key = nil)
if !key.nil? && key.to_sym == :sub
@admin_sections[:sub] || self.controller_name.dasherize
@locomotive_sections[:sub] || self.controller_name.dasherize
else
@admin_sections[:main]
@locomotive_sections[:main]
end
end
@ -99,7 +97,7 @@ module Locomotive
url
end
def page_url(page, options = {})
def public_page_url(page, options = {})
if content = options.delete(:content)
File.join(current_site_url, page.fullpath.gsub('content_type_template', ''), content._slug)
else

View File

@ -3,19 +3,29 @@ module Locomotive
sections 'contents'
respond_to :json, :only => [:update, :sort, :get_path]
respond_to :json, :only => [:update, :sort, :get_path]
def index
@pages = current_site.all_pages_in_once
respond_with(@pages)
end
def new
@page = current_site.pages.build
respond_with @page
end
def create
@page = Page.create(params[:page])
respond_with @page
end
def update
update! do |success, failure|
success.json do
@page = Page.find(params[:id])
@page.update_attributes(params[:page])
respond_with @page do |format|
format.html { redirect_to edit_page_url(@page) }
format.json do
render :json => {
:notice => t('flash.locomotive.pages.update.notice'),
:editable_elements => @page.template_changed ?
@ -39,4 +49,4 @@ module Locomotive
end
end
end
end

View File

@ -1,5 +1,12 @@
module Locomotive::PagesHelper
def css_for_page(page)
%w(index not_found templatized redirect).inject([]) do |memo, state|
memo << state.dasherize if page.send(:"#{state}?")
memo
end.join(' ')
end
def parent_pages_options
roots = current_site.pages.roots.where(:slug.ne => '404').and(:_id.ne => @page.id)

View File

@ -0,0 +1,24 @@
module Locomotive
class CodeInput < Formtastic::Inputs::TextInput
def input_wrapping(&block)
template.content_tag(:li,
[template.capture(&block), error_html, image_picker_html, hint_html].join("\n").html_safe,
wrapper_html_options
)
end
def to_html
input_wrapping do
builder.text_area(method, input_html_options)
end
end
def image_picker_html
template.content_tag(:div,
template.link_to(template.t('locomotive.image_picker.link'), template.theme_assets_path, :id => 'image-picker-link', :class => 'picture'),
:class => 'more')
end
end
end

View File

@ -0,0 +1,17 @@
module Locomotive
class ToggleInput < Formtastic::Inputs::BooleanInput
# def label_text_with_embedded_checkbox
# label_text #<< "" << check_box_html
# end
def to_html
input_wrapping do
hidden_field_html <<
label_html <<
check_box_html
end
end
end
end

View File

@ -6,7 +6,7 @@ module Locomotive
extend ActiveSupport::Concern
included do
embeds_many :editable_elements
embeds_many :editable_elements, :class_name => 'Locomotive::EditableElement'
after_save :remove_disabled_editable_elements

View File

@ -69,7 +69,10 @@ module Locomotive
end
def template_must_be_valid
@parsing_errors.try(:each) { |msg| self.errors.add :template, msg }
@parsing_errors.try(:each) do |msg|
self.errors.add :template, msg
self.errors.add :raw_template, msg
end
end
def update_template_descendants
@ -84,7 +87,7 @@ module Locomotive
self._update_direct_template_descendants(template_descendants.clone, cached)
# finally save them all
::Page.without_callback(:save, :after, :update_template_descendants) do
::Locomotive::Page.without_callback(:save, :after, :update_template_descendants) do
template_descendants.each do |page|
page.save(:validate => false)
end

View File

@ -1,21 +1,17 @@
- content_for :head do
= include_javascripts :image_picker, :edit_page
= include_stylesheets :editable_elements, :fancybox
- if can?(:manage, @page)
= f.foldable_inputs :name => :information do
= f.inputs :name => :information do
= f.input :title, :wrapper_html => { :class => 'highlighted' }
- if not @page.index? and not @page.not_found?
= f.input :parent_id, :as => :select, :collection => parent_pages_options, :include_blank => false
= f.input :slug, :required => false, :hint => @page.slug.blank? ? '&nbsp;' : page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :wrapper_html => { :style => "#{'display: none' if @page.templatized?};" }
= f.input :slug, :required => false, :hint => @page.slug.blank? ? t('.empty_slug') : page_url(@page), :input_html => { :'data-url' => get_path_pages_url, :disabled => @page.index? || @page.not_found? }, :wrapper_html => { :style => "#{'display: none' if @page.templatized?};" }
= render 'editable_elements', :page => @page
= f.foldable_inputs :name => :seo do
= f.inputs :name => :seo do
= f.input :seo_title
= f.input :meta_keywords
@ -23,32 +19,22 @@
- if can?(:manage, @page)
= f.foldable_inputs :name => :advanced_options, :id => 'advanced-options' do
= f.inputs :name => :advanced_options, :id => 'advanced-options', :class => 'foldable' do
= f.input :content_type_id, :as => :select, :collection => current_site.content_types.all.to_a, :include_blank => false, :wrapper_html => { :style => "#{'display: none' unless @page.templatized?}" }
= f.custom_input :templatized, :css => 'toggle', :style => "#{'display: none' if @page.redirect?}" do
= f.check_box :templatized
= f.input :templatized, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.redirect?}"
= f.custom_input :published, :css => 'toggle' do
= f.check_box :published
= f.input :published, :as => :'Locomotive::Toggle'
= f.custom_input :listed, :css => 'toggle' do
= f.check_box :listed
= f.input :listed, :as => :'Locomotive::Toggle'
= f.custom_input :redirect, :css => 'toggle', :style => "#{'display: none' if @page.templatized?}" do
= f.check_box :redirect
= f.input :redirect, :as => :'Locomotive::Toggle', :style => "#{'display: none' if @page.templatized?}"
= f.input :cache_strategy, :as => :select, :collection => options_for_page_cache_strategy, :include_blank => false, :wrapper_html => { :style => "#{'display: none' if @page.redirect?}" }
= f.input :redirect_url, :required => true, :wrapper_html => { :style => "#{'display: none' unless @page.redirect?}" }
= f.inputs :name => :raw_template, :class => 'foldable' do
= f.foldable_inputs :name => :raw_template do
= f.custom_input :value, :css => 'code full', :with_label => false do
= f.label :raw_template
%code{ :class => 'html' }
= f.text_area :raw_template
= f.errors_on :template
.more
= link_to t('locomotive.image_picker.link'), admin_theme_assets_path, :id => 'image-picker-link', :class => 'picture'
= f.input :raw_template, :as => :'Locomotive::Code'

View File

@ -1,4 +1,7 @@
%li{ :id => "item-#{page.id}", :class => "#{'not-found' if page.not_found? } #{'templatized' if page.templatized?} #{'redirect' if page.redirect?}"}
- if page.not_found?
%li.sep &nbsp;
%li{ :id => "item-#{page.id}", :class => "page #{css_for_page(page)}" }
- children = can?(:manage, page) ? page.children : page.children.find_all { |p| !p.templatized? }
@ -7,17 +10,21 @@
- if not page.index? and with_children
= admin_item_toggler(page)
%em
%strong= link_to truncate(page.title, :length => 80), edit_page_url(page)
.inner
.more
%span!= t('.updated_at')
= l page.updated_at, :format => :short
- unless page.index_or_not_found?
%em
- if !page.index_or_not_found? && can?(:manage, page)
= link_to image_tag('admin/list/icons/trash.png'), page_url(page), :class => 'remove', :confirm => t('locomotive.messages.confirm'), :method => :delete
= link_to truncate(page.title, :length => 80), edit_page_url(page)
.more
%span!= t('.updated_at')
= l page.updated_at, :format => :short
- if !page.index_or_not_found? && can?(:manage, page)
= link_to image_tag('locomotive/list/icons/trash.png'), page_url(page), :class => 'remove', :confirm => t('locomotive.messages.confirm'), :method => :delete
- if with_children
%ul{ :id => "folder-#{page._id}", :class => "folder depth-#{(page.depth || 0) + 1}", :'data-url' => sort_page_url(page), :style => "display: #{cookies["folder-#{page._id}"] || 'block'}" }
%ul{ :id => "folder-#{page._id}", :class => "page folder depth-#{(page.depth || 0) + 1}", :'data-url' => sort_page_url(page), :style => "display: #{cookies["folder-#{page._id}"] || 'block'}" }
= render children

View File

@ -9,7 +9,6 @@
.span-12.last
%p
%button.button.light{ :type => 'submit' }
%span= button_label.is_a?(Symbol) ? t(".#{button_label}") : button_label
= submit_tag button_label.is_a?(Symbol) ? t(".#{button_label}") : button_label
.clear

View File

@ -12,212 +12,4 @@ module Locomotive
end
end
end
# Devise.mailer[:locomotive_account] = 'Locomotive::DeviseMailer'
# require 'devise'
#
# puts "overidding Devise::Mailer"
#
# # The devise mailer has also to know about the urls built in the engine
# class Devise::Mailer < ::ActionMailer::Base
# include Locomotive::Engine.routes.url_helpers
# end
# require 'locomotive'
#
# # Use this hook to configure devise mailer, warden hooks and so forth. The first
# # four configuration values can also be set straight in your models.
# Devise.setup do |config|
# # ==> Mailer Configuration
# # Configure the e-mail address which will be shown in DeviseMailer.
# config.mailer_sender = Locomotive.config.mailer_sender
#
# # Configure the class responsible to send e-mails.
# # config.mailer = "Devise::Mailer"
#
# # ==> ORM configuration
# # Load and configure the ORM. Supports :active_record (default) and
# # :mongoid (bson_ext recommended) by default. Other ORMs may be
# # available as additional gems.
# require 'devise/orm/mongoid'
#
# # ==> Configuration for any authentication mechanism
# # Configure which keys are used when authenticating a user. The default is
# # just :email. You can configure it to use [:username, :subdomain], so for
# # authenticating a user, both parameters are required. Remember that those
# # parameters are used only when authenticating and not when retrieving from
# # session. If you need permissions, you should implement that in a before filter.
# # You can also supply a hash where the value is a boolean determining whether
# # or not authentication should be aborted when the value is not present.
# # config.authentication_keys = [ :email ]
#
# # Configure parameters from the request object used for authentication. Each entry
# # given should be a request method and it will automatically be passed to the
# # find_for_authentication method and considered in your model lookup. For instance,
# # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
# # The same considerations mentioned for authentication_keys also apply to request_keys.
# # config.request_keys = []
#
# # Configure which authentication keys should be case-insensitive.
# # These keys will be downcased upon creating or modifying a user and when used
# # to authenticate or find a user. Default is :email.
# config.case_insensitive_keys = [ :email ]
#
# # Tell if authentication through request.params is enabled. True by default.
# # config.params_authenticatable = true
#
# # Tell if authentication through HTTP Basic Auth is enabled. False by default.
# # config.http_authenticatable = false
#
# # If http headers should be returned for AJAX requests. True by default.
# # config.http_authenticatable_on_xhr = true
#
# # The realm used in Http Basic Authentication. "Application" by default.
# # config.http_authentication_realm = "Application"
#
# # ==> Configuration for :database_authenticatable
# # For bcrypt, this is the cost for hashing the password and defaults to 10. If
# # using other encryptors, it sets how many times you want the password re-encrypted.
# config.stretches = 10
#
# # Setup a pepper to generate the encrypted password.
# # config.pepper = "de368d6a1517489510a2ae145328ff1c238f03b02da8f57032936a353835e2ca20561decfb5f7bfafad095fa73cee55b101ed11a0d0f913429d3d9bd114d810e"
#
# # ==> Configuration for :confirmable
# # The time you want to give your user to confirm his account. During this time
# # he will be able to access your application without confirming. Default is 0.days
# # When confirm_within is zero, the user won't be able to sign in without confirming.
# # You can use this to let your user access some features of your application
# # without confirming the account, but blocking it after a certain period
# # (ie 2 days).
# # config.confirm_within = 2.days
#
# # Defines which key will be used when confirming an account
# # config.confirmation_keys = [ :email ]
#
# # ==> Configuration for :rememberable
# # The time the user will be remembered without asking for credentials again.
# config.remember_for = 2.weeks
#
# # If true, a valid remember token can be re-used between multiple browsers.
# # config.remember_across_browsers = true
#
# # If true, extends the user's remember period when remembered via cookie.
# # config.extend_remember_period = false
#
# # If true, uses the password salt as remember token. This should be turned
# # to false if you are not using database authenticatable.
# config.use_salt_as_remember_token = true
#
# # Options to be passed to the created cookie. For instance, you can set
# # :secure => true in order to force SSL only cookies.
# # config.cookie_options = {}
#
# # ==> Configuration for :validatable
# # Range for password length. Default is 6..128.
# # config.password_length = 6..128
#
# # Regex to use to validate the email address
# # config.email_regexp = /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
#
# # ==> Configuration for :timeoutable
# # The time you want to timeout the user session without activity. After this
# # time the user will be asked for credentials again. Default is 30 minutes.
# # config.timeout_in = 30.minutes
#
# # ==> Configuration for :lockable
# # Defines which strategy will be used to lock an account.
# # :failed_attempts = Locks an account after a number of failed attempts to sign in.
# # :none = No lock strategy. You should handle locking by yourself.
# # config.lock_strategy = :failed_attempts
#
# # Defines which key will be used when locking and unlocking an account
# # config.unlock_keys = [ :email ]
#
# # Defines which strategy will be used to unlock an account.
# # :email = Sends an unlock link to the user email
# # :time = Re-enables login after a certain amount of time (see :unlock_in below)
# # :both = Enables both strategies
# # :none = No unlock strategy. You should handle unlocking by yourself.
# # config.unlock_strategy = :both
#
# # Number of authentication tries before locking an account if lock_strategy
# # is failed attempts.
# # config.maximum_attempts = 20
#
# # Time interval to unlock the account if :time is enabled as unlock_strategy.
# # config.unlock_in = 1.hour
#
# # ==> Configuration for :recoverable
# #
# # Defines which key will be used when recovering the password for an account
# # config.reset_password_keys = [ :email ]
#
# # Time interval you can reset your password with a reset password key.
# # Don't put a too small interval or your users won't have the time to
# # change their passwords.
# config.reset_password_within = 2.hours
#
# # ==> Configuration for :encryptable
# # Allow you to use another encryption algorithm besides bcrypt (default). You can use
# # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
# # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
# # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
# # REST_AUTH_SITE_KEY to pepper)
# # config.encryptor = :sha1
#
# # ==> Configuration for :token_authenticatable
# # Defines name of the authentication token params key
# # config.token_authentication_key = :auth_token
#
# # If true, authentication through token does not store user in session and needs
# # to be supplied on each request. Useful if you are using the token as API token.
# # config.stateless_token = false
#
# # ==> Scopes configuration
# # Turn scoped views on. Before rendering "sessions/new", it will first check for
# # "users/sessions/new". It's turned off by default because it's slower if you
# # are using only default views.
# config.scoped_views = true
#
# # Configure the default scope given to Warden. By default it's the first
# # devise role declared in your routes (usually :user).
# config.default_scope = :account
#
# # Configure sign_out behavior.
# # Sign_out action can be scoped (i.e. /users/sign_out affects only :user scope).
# # The default is true, which means any logout action will sign out all active scopes.
# # config.sign_out_all_scopes = true
#
# # ==> Navigation configuration
# # Lists the formats that should be treated as navigational. Formats like
# # :html, should redirect to the sign in page when the user does not have
# # access, but formats like :xml or :json, should return 401.
# #
# # If you have any extra navigational formats, like :iphone or :mobile, you
# # should add them to the navigational formats lists.
# #
# # The :"*/*" and "*/*" formats below is required to match Internet
# # Explorer requests.
# # config.navigational_formats = [:"*/*", "*/*", :html]
#
# # The default HTTP method used to sign out a resource. Default is :get.
# # config.sign_out_via = :get
#
# # ==> OmniAuth
# # Add a new OmniAuth provider. Check the wiki for more information on setting
# # up on your models and hooks.
# # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
#
# # ==> Warden configuration
# # If you want to use other strategies, that are not supported by Devise, or
# # change the failure app, you can configure them inside the config.warden block.
# #
# # config.warden do |manager|
# # manager.failure_app = AnotherApp
# # manager.intercept_401 = false
# # manager.default_strategies(:scope => :user).unshift :some_external_strategy
# # end
# end
end

View File

@ -1,14 +1,6 @@
# Locomotive::Application.routes.draw do |map|
Locomotive::Engine.routes.draw do
# # admin authentication
# devise_for :admin, :class_name => 'Account', :controllers => { :sessions => 'admin/sessions', :passwords => 'admin/passwords' }
#
# as :admin do
# get '/admin' => 'admin/sessions#new'
# end
# locomotive authentication
# authentication
devise_for :locomotive_account,
:class_name => 'Locomotive::Account',
:path => '',

View File

@ -1,18 +1,20 @@
require 'locomotive/engine'
require 'locomotive/dependencies'
require 'locomotive/version'
require 'locomotive/core_ext'
require 'locomotive/configuration'
require 'locomotive/logger'
require 'locomotive/devise'
require 'locomotive/formtastic'
require 'locomotive/dragonfly'
require 'locomotive/liquid'
require 'locomotive/mongoid'
require 'locomotive/carrierwave'
require 'locomotive/custom_fields'
require 'locomotive/httparty'
require 'locomotive/inherited_resources'
require 'locomotive/admin_responder'
require 'locomotive/responder'
require 'locomotive/routing'
require 'locomotive/regexps'
require 'locomotive/render'
@ -23,6 +25,7 @@ require 'locomotive/middlewares'
require 'locomotive/session_store'
module Locomotive
extend ActiveSupport::Autoload
class << self
attr_accessor :config

View File

@ -1,5 +1,3 @@
require 'carrierwave'
module CarrierWave
class SanitizedFile

View File

@ -0,0 +1,23 @@
require 'json/pure'
require 'devise'
require 'mongoid'
require 'mongoid/railtie'
require 'mongoid_acts_as_tree'
require 'will_paginate'
require 'haml'
require 'liquid'
require 'formtastic'
require 'responders'
require 'carrierwave'
require 'custom_fields'
require 'mimetype_fu'
require 'actionmailer_with_request'
require 'httparty'
require 'redcloth'
require 'delayed_job_mongoid'
require 'zip/zipfilesystem'
require 'dragonfly'
require 'cancan'
require 'RMagick'
require 'cells'
require 'sanitize'

View File

@ -1,48 +1 @@
# require 'devise/mailers/helpers'
# module Locomotive
# module Devise
#
# class FailureApp < ::Devise::FailureApp
#
# include ::Locomotive::Engine.routes.url_helpers
#
# def redirect_url
# new_locomotive_account_session_path
# end
#
# end
#
# end
# end
# puts Devise.warden_config.inspect
# monkey patch to let Devise know about custom Locomotive mailer views
# module Devise
# module Mailers
# module Helpers
#
# included do
# include Devise::Controllers::ScopedViews
# include Locomotive::Engine.routes.url_helpers
# attr_reader :scope_name, :resource
# end
#
# def template_paths_with_locomotive
# template_path = self.template_paths_without_locomotive
#
# if self.class.scoped_views?
# scoped_path = @devise_mapping.scoped_path
# scoped_path = 'locomotive' if scoped_path =~ /^locomotive_/
# template_path.unshift "#{scoped_path}/mailer"
# end
#
# template_path
# end
#
# alias_method_chain :template_paths, :locomotive
# end
# end
# end
# patches for devise here

View File

@ -1,32 +1,5 @@
puts "...loading Locomotive engine"
require 'rails'
require 'json/pure'
require 'devise'
require 'mongoid'
require 'mongoid/railtie'
require 'mongoid_acts_as_tree'
require 'will_paginate'
require 'haml'
require 'liquid'
require 'formtastic'
require 'inherited_resources'
require 'carrierwave'
require 'custom_fields'
require 'mimetype_fu'
require 'actionmailer_with_request'
require 'httparty'
require 'redcloth'
require 'delayed_job_mongoid'
require 'zip/zipfilesystem'
require 'dragonfly'
require 'cancan'
require 'RMagick'
require 'cells'
require 'sanitize'
$:.unshift File.dirname(__FILE__)
module Locomotive
class Engine < Rails::Engine

View File

@ -0,0 +1,13 @@
module Formtastic
module Inputs
module Base
module Errors
def error_sentence_html
error_class = options[:error_class] || builder.default_inline_error_class
template.content_tag(:div,
template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.html_safe)), :class => error_class)
end
end
end
end
end

View File

@ -1,47 +0,0 @@
require 'responders'
require 'inherited_resources'
require 'inherited_resources/actions'
require 'inherited_resources/responder'
module InheritedResources
# redirect to edit_resource_url instead of resource_url
module Actions
def create(options={}, &block)
object = build_resource
if create_resource(object)
options[:location] ||= edit_resource_url rescue nil # change here
end
respond_with_dual_blocks(object, options, &block)
end
alias :create! :create
# PUT /resources/1
def update(options={}, &block)
object = resource
if update_resource(object, params[resource_instance_name])
options[:location] ||= edit_resource_url rescue nil # change here
end
respond_with_dual_blocks(object, options, &block)
end
alias :update! :update
# DELETE /resources/1
def destroy(options={}, &block)
object = resource
options[:location] ||= collection_url rescue nil
destroy_resource(object)
options[:alert] = object.errors.full_messages.first # display the first error if present
respond_with_dual_blocks(object, options, &block)
end
alias :destroy! :destroy
end
end

View File

@ -1,112 +0,0 @@
module Locomotive
class MiscFormBuilder < Formtastic::SemanticFormBuilder
@@all_fields_required_by_default = false
def foldable_inputs(*args, &block)
opts = args.extract_options!
unfolded = !(opts[:class] || '').index('off').nil? || @object.new_record? || !@object.errors.empty?
opts[:class] = (opts[:class] || '') + " inputs foldable #{'folded' unless unfolded}"
args.push(opts)
self.inputs(*args, &block)
end
def custom_input(name, options = {}, &block)
default_options = { :css => '', :with_label => true, :label => nil }
options = default_options.merge(options)
html = options[:with_label] ? self.label(options[:label] || name, { :required => options[:required] }) : ''
html += template.capture(&block) || ''
html += inline_hints_for(name, options) || ''
html += self.errors_on(name) || ''
template.content_tag(:li, template.find_and_preserve(html), :style => "#{options[:style]}", :class => "#{options[:css]} #{'error' unless @object.errors[name].empty?}")
end
def inline_errors_on(method, options = nil)
if render_inline_errors?
errors = @object.errors[method.to_sym]
template.content_tag(:span, [*errors].to_sentence.untaint, :class => 'inline-errors') if errors.present?
else
nil
end
end
def error_sentence(errors, options = {}) #:nodoc:
error_class = options[:error_class] || default_inline_error_class
error_msg = template.content_tag(:p, Formtastic::Util.html_safe(errors.to_sentence.untaint))
template.content_tag(:div, error_msg, :class => error_class)
end
# FIXME (Did): allows to pass attributes to the I18n translation key
def inline_hints_for(method, options) #:nodoc:
options[:hint] = localized_string(method, options[:hint], :hint, options[:hint_options] || {})
return if options[:hint].blank? or options[:hint].kind_of? Hash
hint_class = options[:hint_class] || default_hint_class
template.content_tag(:p, Formtastic::Util.html_safe(options[:hint]), :class => hint_class)
end
def model_name
@object.present? ? (@object.class.model_name || @object.class.name) : @object_name.to_s.classify
end
def normalize_model_name(name)
if name =~ /(.+)\[(.+)\]/
[$1, $2]
else
[name.split('/')].flatten
end
end
# FIXME (Did): why the hell should all the strings be escaped ?
def localized_string(key, value, type, options = {}) #:nodoc:
key = value if value.is_a?(::Symbol)
escaping = options.delete(:escaping) || false
if value.is_a?(::String)
escaping ? escape_html_entities(value) : value
else
use_i18n = value.nil? ? i18n_lookups_by_default : (value != false)
if use_i18n
model_name, nested_model_name = normalize_model_name(self.model_name.underscore)
action_name = template.params[:action].to_s rescue ''
attribute_name = key.to_s
defaults = ::Formtastic::I18n::SCOPES.reject do |i18n_scope|
nested_model_name.nil? && i18n_scope.match(/nested_model/)
end.collect do |i18n_scope|
i18n_path = i18n_scope.dup
i18n_path.gsub!('%{action}', action_name)
i18n_path.gsub!('%{model}', model_name)
i18n_path.gsub!('%{nested_model}', nested_model_name) unless nested_model_name.nil?
i18n_path.gsub!('%{attribute}', attribute_name)
i18n_path.gsub!('..', '.')
i18n_path.to_sym
end
defaults << ''
defaults.uniq!
default_key = defaults.shift
i18n_value = ::Formtastic::I18n.t(default_key,
options.merge(:default => defaults, :scope => type.to_s.pluralize.to_sym))
if i18n_value.blank? && type == :label
# This is effectively what Rails label helper does for i18n lookup
options[:scope] = [:helpers, type]
options[:default] = defaults
i18n_value = ::I18n.t(default_key, options)
end
if i18n_value.is_a?(::String)
i18n_value = escaping ? escape_html_entities(i18n_value) : i18n_value
end
i18n_value.blank? ? nil : i18n_value
end
end
end
end
end

View File

@ -1,7 +1,5 @@
require 'responders'
module Locomotive
class AdminResponder < ::ActionController::Responder
class Responder < ::ActionController::Responder
include ::Responders::FlashResponder
@ -25,4 +23,4 @@ module Locomotive
end
end
end
end

View File

@ -1,5 +1,5 @@
require 'formtastic'
require 'locomotive/misc_form_builder'
Formtastic::SemanticFormHelper.builder = Locomotive::MiscFormBuilder
Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
# require 'formtastic'
# require 'locomotive/misc_form_builder'
# Formtastic::SemanticFormHelper.builder = Locomotive::MiscFormBuilder
# Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
#