rename translation files (convention) + email notification when adding contents (api)

This commit is contained in:
dinedine 2011-01-18 15:24:42 +01:00
parent 6eead019d4
commit 2fc99bf90a
24 changed files with 352 additions and 223 deletions

View File

@ -0,0 +1,15 @@
module Admin
class Notifications < ActionMailer::Base
default :from => Locomotive.config.mailer_sender
def new_content_instance(account, content)
@account, @content = account, content
subject = t('admin.notifications.new_content_instance.subject', :type => content.content_type.name, :locale => account.locale)
mail :subject => subject, :to => account.email
end
end
end

View File

@ -21,6 +21,7 @@ class ContentInstance
before_save :set_slug
before_save :set_visibility
before_create :add_to_list_bottom
after_create :send_notifications
## named scopes ##
scope :latest_updated, :order_by => [[:updated_at, :desc]], :limit => Locomotive.config.lastest_items_nb
@ -92,4 +93,18 @@ class ContentInstance
self.content_type.highlighted_field._alias.to_sym
end
def send_notifications
return unless self.content_type.api_enabled?
accounts = self.content_type.site.accounts.to_a
self.content_type.api_accounts.each do |account_id|
next if account_id.blank?
account = accounts.detect { |a| a.id.to_s == account_id.to_s }
Admin::Notifications.new_content_instance(account, self).deliver
end
end
end

View File

@ -10,6 +10,7 @@ class ContentType
field :highlighted_field_name
field :group_by_field_name
field :api_enabled, :type => Boolean, :default => false
field :api_accounts, :type => Array
## associations ##
referenced_in :site

View File

@ -1,5 +1,5 @@
- content_for :head do
= include_javascripts :custom_fields
= include_javascripts :content_types, :custom_fields
= include_stylesheets :fancybox
= f.inputs :name => :information do
@ -18,5 +18,9 @@
= f.input :order_by, :as => :select, :collection => options_for_order_by(f.object, 'contents'), :include_blank => false
= f.custom_input :api_enabled, :css => 'toggle' do
= f.check_box :api_enabled
= hidden_field_tag 'content_type[api_accounts][]', ''
= f.input :api_accounts, :as => :select, :collection => current_site.accounts.collect { |a| ["#{a.name} <#{a.email}>", a.id] }, :include_blank => false, :multiple => true, :wrapper_html => { :class => 'multiple', :style => (f.object.api_enabled? ? '' : 'display: none') }

View File

@ -1,8 +1,5 @@
- title t('.title')
- content_for :head do
= include_javascripts :content_types
- content_for :submenu do
= render 'admin/shared/menu/contents'

View File

@ -0,0 +1,17 @@
%p= t('.title', :name => @account.name, :date => I18n.l(Time.now), :locale => @account.locale)
%hr
%p
%b= t('.type', :type => @content.content_type.name, :locale => @account.locale)
%br
%i= @content.content_type.description
%hr
%ul
- @content.custom_fields.each do |field|
%li
%strong= field.label
&nbsp;-&nbsp;
%i= @content.send(field._name)

View File

@ -1,4 +1,4 @@
require 'devise'
require 'locomotive'
## patches ##
@ -31,7 +31,7 @@ end
# four configuration values can also be set straight in your models.
Devise.setup do |config|
# Configure the e-mail address which will be shown in DeviseMailer.
config.mailer_sender = "support@locomotiveapp.org"
config.mailer_sender = Locomotive.config.mailer_sender
# ==> Configuration for any authentication mechanism
# Configure which keys are used when authenticating an user. By default is

View File

@ -39,4 +39,7 @@ Locomotive.configure do |config|
# default locale (for now, only en and fr are supported)
config.default_locale = :en
# Configure the e-mail address which will be shown in the DeviseMailer, NotificationMailer, ...etc
config.mailer_sender = 'support@example.com'
end

View File

@ -42,6 +42,12 @@ en:
notice: "The page you requested does not exist."
link: "&rarr; Back to the application"
notifications:
new_content_instance:
subject: "[%{type}] new"
title: "Hi %{name}, just to let you know that a new instance has been created on %{date}"
type: "Model: %{type}"
custom_fields:
edit:
title: Editing custom field
@ -292,64 +298,3 @@ en:
title: "Step 3/3 &mdash; Create first site"
explanations: "This is the last step of the installation. You can upload a theme as a zip file. We have free available themes <a href=\"http://www.locomotivecms.com/support/themes\">here</a>."
next: Create site
formtastic:
titles:
information: General information
meta: SEO Metadata
code: Code
raw_template: Template
credentials: Credentials
language: Language
sites: Sites
access_points: Access points
memberships: Accounts
membership_email: Account email
file: File
preview: Preview
options: Advanced options
custom_fields: Custom fields
other_fields: Other information
presentation: Presentation
attributes: Attributes
upload: Upload
labels:
theme_asset:
new:
source: File
edit:
source: Replace file
custom_fields:
field:
_alias: Alias
import:
new:
source: File
samples: Copy samples
reset: Reset site
hints:
page:
published: "Only authenticated accounts can view unpublished pages."
cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise."
templatized: "Use the page as a template for a model you defined."
snippet:
slug: "You need to know it in order to insert the snippet inside a page"
site:
meta_keywords: "Meta keywords used within the head tag of the page. They are separeted by an empty space. Required for SEO."
meta_description: "Meta description used within the head tag of the page. Required for SEO."
domain_name: "ex: locomotiveapp.org"
theme_asset:
slug: "You do not need to add the extension file (.css or .js)"
edit:
source: "You can replace it by a file of the same extension"
custom_fields:
field:
_alias: "Property available in liquid templates"
hint: "Text displayed in the model form just below the field"
import:
source: "A zipfile containing a database.yml along with assets and templates"
samples: "If enabled, the import process will also copy contents and assets"
reset: "If enabled, all the data of your site will be destroyed before importing the new site"

View File

@ -42,6 +42,12 @@ fr:
update: Mettre à jour
send: Envoyer
notifications:
new_content_instance:
subject: "[%{type}] nouveau"
title: "Bonjour %{name}, nous voulions vous faire savoir qu'une nouvelle instance a été créée le %{date}"
type: "Modèle: %{type}"
custom_fields:
edit:
title: Editer champ personnalisé
@ -293,62 +299,3 @@ fr:
title: "Étape 3/3 &mdash; Créer premier site"
explanations: "C'est la dernière étape de l'installation. Vous pouvez uploader un theme sous forme d'un fichier zip. Nous avons quelques themes disponibles <a href=\"http://www.locomotivecms.com/support/themes\">ici</a>."
next: Créer site
formtastic:
titles:
information: Informations générales
meta: SEO Metadata
code: Code
raw_template: Gabarit
credentials: Informations de connexion
language: Langue
sites: Sites
access_points: Points d'accès
memberships: Comptes
membership_email: Email compte
file: Fichier
preview: Aperçu
options: Options avancées
custom_fields: Champs personnalisés
other_fields: Autres informations
presentation: Présentation
attributes: Propriétés
upload: Envoi au serveur
labels:
theme_asset:
new:
source: Fichier
edit:
source: Nouveau fichier
custom_fields:
field:
_alias: Alias
import:
new:
source: Fichier
samples: Copier contenu
reset: Remettre à zéro
hints:
page:
published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée."
cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis."
templatized: "Utilise la page comme un template pour un modèle défini."
snippet:
slug: "Utilisé pour insérer le snippet dans une page."
site:
meta_keywords: "Mots-clés utilisés à l'intérieur de la balise HEAD. Ils sont séparés par un espace. Requis pour un meilleur référencement."
meta_description: "Description utilisée à l'intérieur de la balise HEAD. Requis pour un meilleur référencement."
domain_name: "ex: locomotiveapp.org"
theme_asset:
slug: "Vous n'avez pas besoin de mettre l'extension du fichier (.css ou .js)"
edit:
source: "Vous pouvez le remplacer par un fichier avec la meme extension."
custom_fields:
field:
_alias: "Champ utilisable dans les templates liquid"
hint: "Texte affiché dans le formulaire de l'élément juste en dessous du champ."
import:
source: "Un fichier zip contenant database.yml, les fichiers du thème et les templates de page"
samples: "Si activé, les contenus et les média seront aussi copiés lors de l'import"
reset: "Si activé, toutes les données de votre site seront détruites avant l'import du nouveau site"

View File

@ -0,0 +1,65 @@
en:
formtastic:
titles:
information: General information
meta: SEO Metadata
code: Code
raw_template: Template
credentials: Credentials
language: Language
sites: Sites
access_points: Access points
memberships: Accounts
membership_email: Account email
file: File
preview: Preview
options: Advanced options
custom_fields: Custom fields
other_fields: Other information
presentation: Presentation
attributes: Attributes
upload: Upload
labels:
theme_asset:
new:
source: File
edit:
source: Replace file
custom_fields:
field:
_alias: Alias
import:
new:
source: File
samples: Copy samples
reset: Reset site
content_type:
api_accounts: Notified Accounts
hints:
page:
published: "Only authenticated accounts can view unpublished pages."
cache_strategy: "Cache the page for better performance. The 'Simple' choice is a good compromise."
templatized: "Use the page as a template for a model you defined."
snippet:
slug: "You need to know it in order to insert the snippet inside a page"
site:
meta_keywords: "Meta keywords used within the head tag of the page. They are separeted by an empty space. Required for SEO."
meta_description: "Meta description used within the head tag of the page. Required for SEO."
domain_name: "ex: locomotiveapp.org"
theme_asset:
slug: "You do not need to add the extension file (.css or .js)"
edit:
source: "You can replace it by a file of the same extension"
custom_fields:
field:
_alias: "Property available in liquid templates"
hint: "Text displayed in the model form just below the field"
import:
source: "A zipfile containing a database.yml along with assets and templates"
samples: "If enabled, the import process will also copy contents and assets"
reset: "If enabled, all the data of your site will be destroyed before importing the new site"
content_type:
api_enabled: "It is used to let people from outside to create new instances (example: messages in a contact form)"
api_accounts: "A notification email will be sent to each of the accounts listed above when a new instance is created"

View File

@ -0,0 +1,64 @@
fr:
formtastic:
titles:
information: Informations générales
meta: SEO Metadata
code: Code
raw_template: Gabarit
credentials: Informations de connexion
language: Langue
sites: Sites
access_points: Points d'accès
memberships: Comptes
membership_email: Email compte
file: Fichier
preview: Aperçu
options: Options avancées
custom_fields: Champs personnalisés
other_fields: Autres informations
presentation: Présentation
attributes: Propriétés
upload: Envoi au serveur
labels:
theme_asset:
new:
source: Fichier
edit:
source: Nouveau fichier
custom_fields:
field:
_alias: Alias
import:
new:
source: Fichier
samples: Copier contenu
reset: Remettre à zéro
content_type:
api_accounts: Comptes à notifier
hints:
page:
published: "Seuls les administrateurs authentifiés peuvent voir une page non publiée."
cache_strategy: "Cache la page pour de meilleure performance. L'option 'Simple' est le meilleur compromis."
templatized: "Utilise la page comme un template pour un modèle défini."
snippet:
slug: "Utilisé pour insérer le snippet dans une page."
site:
meta_keywords: "Mots-clés utilisés à l'intérieur de la balise HEAD. Ils sont séparés par un espace. Requis pour un meilleur référencement."
meta_description: "Description utilisée à l'intérieur de la balise HEAD. Requis pour un meilleur référencement."
domain_name: "ex: locomotiveapp.org"
theme_asset:
slug: "Vous n'avez pas besoin de mettre l'extension du fichier (.css ou .js)"
edit:
source: "Vous pouvez le remplacer par un fichier avec la meme extension."
custom_fields:
field:
_alias: "Champ utilisable dans les templates liquid"
hint: "Texte affiché dans le formulaire de l'élément juste en dessous du champ."
import:
source: "Un fichier zip contenant database.yml, les fichiers du thème et les templates de page"
samples: "Si activé, les contenus et les média seront aussi copiés lors de l'import"
reset: "Si activé, toutes les données de votre site seront détruites avant l'import du nouveau site"
content_type:
api_enabled: "Utilisé pour autoriser la création de nouvelles instances de l'extérieur (ex.: les messages dans un formulaire de contact)"
api_accounts: "Un email de notification sera envoyé à chaque compte listé ci-dessus lors de la création d'une nouvelle instance"

View File

@ -1,5 +1,10 @@
BOARD:
x notify accounts when new instance of models (opt): none, one or many accounts. Used for contact form.
x implementation
x emails
x tests
- fix bug issue about (custom fields)
BACKLOG:
@ -10,7 +15,6 @@ BACKLOG:
- refactor slugify method (use parameterize + create a module)
- validation for custom fields
- notify accounts when new instance of models (opt): none, one or many accounts. Used for contact form.
- global regions: keyword in editable element (http://www.mongodb.org/display/DOCS/Updating)
- write my first tutorial about locomotive

View File

@ -37,4 +37,7 @@ Locomotive.configure do |config|
# default locale (for now, only en and fr are supported)
config.default_locale = :en
# Configure the e-mail address which will be shown in the DeviseMailer, NotificationMailer, ...etc
config.mailer_sender = 'support@example.com'
end

View File

@ -12,7 +12,8 @@ module Locomotive
:enable_logs => false,
:heroku => false,
:delayed_job => true,
:default_locale => :en
:default_locale => :en,
:mailer_sender => 'support@example.com'
}
cattr_accessor :settings

View File

@ -64,3 +64,5 @@ class Hash
end
end

View File

@ -13,4 +13,20 @@ $(document).ready(function() {
});
$('#content_type_slug').keypress(function() { $(this).addClass('filled'); });
// api enabled ?
console.log('subscribing...');
$.subscribe('toggle.content_type_api_enabled.checked', function(event, data) {
console.log('checked');
$('#content_type_api_accounts_input').show();
}, []);
$.subscribe('toggle.content_type_api_enabled.unchecked', function(event, data) {
console.log('unchecked');
$('#content_type_api_accounts_input').hide();
}, []);
});

View File

@ -114,6 +114,8 @@ form.formtastic fieldset ol li code.nude textarea {
form.formtastic fieldset ol li select { font-size: 0.9em; position: relative; top: 2px; color: #787a89; }
form.formtastic fieldset ol li.multiple select { width: 45%; }
form.formtastic fieldset ol li.error input,
form.formtastic fieldset ol li.error textarea,
form.formtastic fieldset ol li.error code iframe { border: 2px solid #ec3f48 !important; }

View File

@ -60,6 +60,34 @@ describe ContentInstance do
end
describe '#api' do
before(:each) do
@account_1 = Factory.build('admin user', :id => '1')
@account_2 = Factory.build('frenchy user', :id => '2')
@content_type.api_enabled = true
@content_type.api_accounts = ['', @account_1.id, @account_2.id]
Site.any_instance.stubs(:accounts).returns([@account_1, @account_2])
@content = build_content
end
it 'does not send email notifications if the api is disabled' do
@content_type.api_enabled = false
Admin::Notifications.expects(:new_content_instance).never
@content.save
end
it 'sends email notifications when a new instance is created' do
Admin::Notifications.expects(:new_content_instance).with(@account_1, @content).returns(mock('mailer', :deliver => true))
Admin::Notifications.expects(:new_content_instance).with(@account_2, @content).returns(mock('mailer', :deliver => true))
@content.save
end
end
def build_content(options = {})
@content_type.contents.build({ :title => 'Locomotive', :description => 'Lorem ipsum....' }.merge(options))
end