rename translation files (convention) + email notification when adding contents (api)
This commit is contained in:
parent
6eead019d4
commit
2fc99bf90a
15
app/mailers/admin/notifications.rb
Normal file
15
app/mailers/admin/notifications.rb
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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') }
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
- title t('.title')
|
||||
|
||||
- content_for :head do
|
||||
= include_javascripts :content_types
|
||||
|
||||
- content_for :submenu do
|
||||
= render 'admin/shared/menu/contents'
|
||||
|
||||
|
17
app/views/admin/notifications/new_content_instance.html.haml
Normal file
17
app/views/admin/notifications/new_content_instance.html.haml
Normal 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
|
||||
-
|
||||
%i= @content.send(field._name)
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -42,6 +42,12 @@ en:
|
||||
notice: "The page you requested does not exist."
|
||||
link: "→ 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 — 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"
|
||||
|
@ -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 — 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"
|
65
config/locales/formtastic.en.yml
Normal file
65
config/locales/formtastic.en.yml
Normal 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"
|
||||
|
64
config/locales/formtastic.fr.yml
Normal file
64
config/locales/formtastic.fr.yml
Normal 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"
|
6
doc/TODO
6
doc/TODO
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -64,3 +64,5 @@ class Hash
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}, []);
|
||||
|
||||
|
||||
});
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user