diff --git a/Gemfile b/Gemfile index 6917ceca..8444eea9 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem 'liquid' gem 'bson_ext', '>= 1.0.1' gem 'mongo_ext' gem 'mongoid', '2.0.0.beta6' -gem 'mongoid_acts_as_tree', '>= 0.1.2' +gem 'mongoid_acts_as_tree', '0.1.5' gem 'mongo_session_store', '2.0.0.pre' gem 'warden' gem 'devise', '1.1.rc1' @@ -22,6 +22,7 @@ gem 'carrierwave-rails3', :require => 'carrierwave' gem 'actionmailer-with-request', :require => 'actionmailer_with_request' gem 'heroku' gem 'httparty', '0.6.0' +gem 'RedCloth' # Development environment group :development do diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..94e7d78c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +== MIT License + +Copyright (c) 2010, Didier Lafforgue. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.textile b/README.textile index aebb18b6..6bd8e391 100644 --- a/README.textile +++ b/README.textile @@ -1,20 +1,40 @@ h1. Locomotive CMS -Locomotive is a simple but powerful CMS based on liquid templates and mongodb database. If we have to give only 4 main features to describe our application, there will be: +Locomotive is a simple but powerful CMS based on liquid templates and mongodb database. At my company ("NoCoffee":http://www.nocoffee.fr), we use it for our clients when they request a simple website. + +If we have to give only 5 main features to describe our application, there will be: * managing as many websites as you want with one application instance * nice looking UI (see http://www.locomotiveapp.org for some screenshots) * flexible content types -* inline editing +* playing smoothly with Heroku and MongoHQ +* inline editing (coming soon) h2. Strategy / Development status We already developed a fully functional prototype in Rails 2.3.2 with both active record / mongomapper and it worked quite well. We are even using it for some client websites. Now, our goal is to port our prototype to Rails 3 and migrate from mongomapper to mongoid. Besides, we put a lot of efforts to make it as robust as we can by writing better specs than we wrote for the prototype at first. +h2. Gems + +Here is a short list of main gems used in the application. + +* Rails 3 (beta 3) +* Mongoid +* Liquid +* Devise +* Carrierwave +* Haml + h2. Installation -TODO +See the "official website":http://www.locomotiveapp.org + +h2. Credits + +Many thanks to "Sacha Greif":http://www.sachagreif.com for his great work on the user interface and the LocomotiveApp website front page. + +"Rodrigo Alvarez":http://blog.codecaster.es/ for his plugin named Congo which gave us a good starting point and for his availability for (very late) tech discussions. h2. Contact diff --git a/app/helpers/admin/base_helper.rb b/app/helpers/admin/base_helper.rb index 54fa7579..52a7435c 100644 --- a/app/helpers/admin/base_helper.rb +++ b/app/helpers/admin/base_helper.rb @@ -48,7 +48,7 @@ module Admin::BaseHelper end def nocoffee_tag - link_to content_tag(:em, 'no') + 'Coffee', 'http://www.nocoffee.fr', :id => 'nocoffee' + link_to 'noCoffee', 'http://www.nocoffee.fr', :id => 'nocoffee' end end \ No newline at end of file diff --git a/app/models/extensions/page/tree.rb b/app/models/extensions/page/tree.rb index 883cf011..5aade096 100644 --- a/app/models/extensions/page/tree.rb +++ b/app/models/extensions/page/tree.rb @@ -16,7 +16,7 @@ module Models ## callbacks ## before_validate :reset_parent - before_save { |p| p.parent_id = nil if p.parent_id.blank? } + before_save { |p| p.send(:write_attribute, :parent_id, nil) if p.parent_id.blank? } before_save :change_parent before_create { |p| p.send(:fix_position, false) } before_create :add_to_list_bottom @@ -60,11 +60,11 @@ module Models def hacked_fix_position(perform_save = true) if parent.nil? - self[parent_id_field] = nil + self.write_attribute parent_id_field, nil self[path_field] = [] self[depth_field] = 0 else - self[parent_id_field] = parent._id + self.write_attribute parent_id_field, parent._id self[path_field] = parent[path_field] + [parent._id] self[depth_field] = parent[depth_field] + 1 self.save if perform_save diff --git a/app/models/layout.rb b/app/models/layout.rb index 5c5d492e..9a68d7e8 100644 --- a/app/models/layout.rb +++ b/app/models/layout.rb @@ -21,9 +21,8 @@ class Layout < LiquidTemplate self.value.scan(Locomotive::Regexps::CONTENT_FOR).each do |attributes| slug = attributes[0].strip.downcase - name = attributes[1].strip.gsub("\"", '') - name = nil if name.empty? - name ||= I18n.t('attributes.defaults.page_parts.name') if slug == 'layout' + name = slug.humanize + name = I18n.t('attributes.defaults.page_parts.name') if slug == 'layout' if part = self.parts.detect { |p| p.slug == slug } part.name = name if name.present? diff --git a/app/views/admin/shared/_footer.html.haml b/app/views/admin/shared/_footer.html.haml index 8cd482d3..859c6d13 100644 --- a/app/views/admin/shared/_footer.html.haml +++ b/app/views/admin/shared/_footer.html.haml @@ -1,5 +1,2 @@ -%p.tright - = t('.developed_by') - = nocoffee_tag - = t('.powered_by') - = link_to 'Ruby on Rails', 'http://www.rubyonrails.com', :id => 'powered-by' \ No newline at end of file +%p.tcenter + = t('.who_is_behind', :development => nocoffee_tag) diff --git a/config/locales/admin_ui_fr.yml b/config/locales/admin_ui_fr.yml index 5bb16f0c..f411312c 100644 --- a/config/locales/admin_ui_fr.yml +++ b/config/locales/admin_ui_fr.yml @@ -47,8 +47,7 @@ fr: site: Site theme_assets: Fichiers Thème footer: - developed_by: Service développé par - powered_by: et propulsé par + who_is_behind: "Service développé par {{development}} et désigné par Sacha Greif" form_actions: back: Retour sans sauvegarder create: Créer @@ -301,7 +300,7 @@ fr: contents: index: - title: 'Liste "{{type}}"' + title: 'Liste des "{{type}}"' edit: éditer modèle destroy: supprimer modèle download: télécharger éléments diff --git a/doc/TODO b/doc/TODO index b50a686c..eba2d891 100644 --- a/doc/TODO +++ b/doc/TODO @@ -3,7 +3,6 @@ BOARD: - refactoring admin crud (pages + layouts + snippets) - refactor slugify method (use parameterize + create a module) -- change credits in the admin footer - change action icons according to the right action [Sacha] BACKLOG: @@ -51,4 +50,7 @@ x localize application in French x devise x carrierwave x localize devise emails - x admin \ No newline at end of file + x admin +x change credits in the admin footer +x license +x textile filter \ No newline at end of file diff --git a/lib/locomotive/liquid/filters/text.rb b/lib/locomotive/liquid/filters/text.rb new file mode 100644 index 00000000..235509c9 --- /dev/null +++ b/lib/locomotive/liquid/filters/text.rb @@ -0,0 +1,16 @@ +module Locomotive + module Liquid + module Filters + module Text + + def textile(input) + RedCloth.new(input).to_html + end + + end + + ::Liquid::Template.register_filter(Text) + + end + end +end \ No newline at end of file diff --git a/lib/locomotive/regexps.rb b/lib/locomotive/regexps.rb index 0dd3ebfe..80caff65 100644 --- a/lib/locomotive/regexps.rb +++ b/lib/locomotive/regexps.rb @@ -7,7 +7,7 @@ module Locomotive CONTENT_FOR = /\{\{\s*content_for_([a-zA-Z]{1}[a-zA-Z_0-9]*)(\s+.*)?\s*\}\}/ - CONTENT_FOR_LAYOUT = /\{\{\s*content_for_layout\s*\}\}/ + CONTENT_FOR_LAYOUT = /\{\{\s*content_for_layout\s*/ end end \ No newline at end of file diff --git a/public/images/admin/nocoffee.png b/public/images/admin/nocoffee.png new file mode 100644 index 00000000..5612223f Binary files /dev/null and b/public/images/admin/nocoffee.png differ diff --git a/public/stylesheets/admin/layout.css b/public/stylesheets/admin/layout.css index da6b5a4c..9b19dd09 100644 --- a/public/stylesheets/admin/layout.css +++ b/public/stylesheets/admin/layout.css @@ -134,13 +134,23 @@ body { /* ___ footer ___ */ #footer { + padding-top: 10px; background: transparent url(/images/admin/background/footer.png) no-repeat 0 0; } #footer p { padding: 15px 8px 0 0; - font-size: 0.6em; - color: #444; + font-size: 0.8em; + color: #E6E6E6; +} + +#footer p a { + color: #1F82BC; + text-decoration: none; +} + +#footer p a:hover { + text-decoration: underline; } /* ___ Alignements ___ */ @@ -166,10 +176,4 @@ body { /* ___ NoCoffee / Rails Tags ___ */ -a#nocoffee { text-decoration: none; font-size: 1.1em; line-height: 20px; color: #505b64; padding-right: 20px; margin: 0 4px; background: transparent url(../../images/admin/nocoffee.gif) no-repeat right 0px; } -a#nocoffee em { color: #ef3f44; font-weight: normal; font-style: normal; } - -a#powered-by { text-decoration: none; font-size: 1.1em; color: #666; } -a#powered-by:hover{ text-decoration: underline; color: #aaa; } - - +a#nocoffee { color: #b0b4c0 !important; text-decoration: none; line-height: 20px; padding-right: 20px; margin: 0 4px; background: transparent url(../../images/admin/nocoffee.png) no-repeat right 0px; } diff --git a/spec/factories.rb b/spec/factories.rb index 06484160..961335a9 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -44,7 +44,7 @@ Factory.define :layout do |l| My website - +
\{\{ content_for_layout \}\}
} diff --git a/spec/lib/locomotive/liquid/filters/text_spec.rb b/spec/lib/locomotive/liquid/filters/text_spec.rb new file mode 100644 index 00000000..059d6fcd --- /dev/null +++ b/spec/lib/locomotive/liquid/filters/text_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' + +describe Locomotive::Liquid::Filters::Text do + + include Locomotive::Liquid::Filters::Text + + it 'transforms a textile input into HTML' do + textile('This is *my* text.').should == "

This is my text.

" + end + +end \ No newline at end of file diff --git a/spec/models/layout_spec.rb b/spec/models/layout_spec.rb index 9f25ec21..379e21e5 100644 --- a/spec/models/layout_spec.rb +++ b/spec/models/layout_spec.rb @@ -27,8 +27,8 @@ describe Layout do @layout.parts.first.name.should == 'Body' @layout.parts.first.slug.should == 'layout' - @layout.parts.last.name.should == 'Left Sidebar' - @layout.parts.last.slug.should == 'sidebar' + @layout.parts.last.name.should == 'Left sidebar' + @layout.parts.last.slug.should == 'left_sidebar' end it 'should not add parts to pages if layout does not change' do diff --git a/spec/models/page_spec.rb b/spec/models/page_spec.rb index c2c88005..6b426a10 100644 --- a/spec/models/page_spec.rb +++ b/spec/models/page_spec.rb @@ -293,7 +293,7 @@ describe Page do before(:each) do @page = Factory.build(:page, :site => nil) @page.parts.build :slug => 'layout', :value => 'Hello world !' - @page.parts.build :slug => 'sidebar', :value => 'A sidebar...' + @page.parts.build :slug => 'left_sidebar', :value => 'A sidebar...' @page.send(:store_template) @layout = Factory.build(:layout, :site => nil) @layout.send(:store_template)