diff --git a/Gemfile b/Gemfile
index b3f593a9..89a67bb0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -64,7 +64,7 @@ group :test do
gem 'rspec-rails', '2.3.1'
gem 'factory_girl_rails'
gem 'pickle'
- gem 'xpath', '0.1.3' # :git => 'https://github.com/wunderbread/xpath.git'
+ gem 'xpath', '0.1.3'
gem 'capybara'
gem 'database_cleaner'
diff --git a/app/controllers/admin/assets_controller.rb b/app/controllers/admin/assets_controller.rb
index 9f6bda3f..a5e45c91 100644
--- a/app/controllers/admin/assets_controller.rb
+++ b/app/controllers/admin/assets_controller.rb
@@ -1,19 +1,59 @@
-module Admin # TODO
+module Admin
class AssetsController < BaseController
- sections 'assets'
+ include ActionView::Helpers::SanitizeHelper
+ include ActionView::Helpers::TextHelper
- respond_to :json, :only => :update
+ # defaults :collection_name => 'assets', :instance_name => 'asset'
- def create
- create! { admin_assets_url }
+ respond_to :json, :only => [:index, :create, :destroy]
+
+ def index
+ index! do |response|
+ response.json do
+ render :json => { :assets => @assets.collect { |asset| asset_to_json(asset) } }
+ end
+ end
end
- def update
- update! { admin_assets_url }
+ def create
+ params[:asset] = { :name => params[:name], :source => params[:file] } if params[:file]
+
+ create! do |success, failure|
+ success.json do
+ render :json => asset_to_json(@asset)
+ end
+ failure.json do
+ render :json => { :status => 'error' }
+ end
+ end
+ rescue Exception => e
+ render :json => { :status => 'error', :message => e.message }
end
protected
+ def collection
+ if params[:image]
+ @assets ||= begin_of_association_chain.assets.only_image
+ else
+ @assets ||= begin_of_association_chain.assets
+ end
+ end
+
+ def asset_to_json(asset)
+ {
+ :status => 'success',
+ :filename => asset.source_filename,
+ :short_name => truncate(asset.name, :length => 15),
+ :extname => truncate(asset.extname, :length => 3),
+ :content_type => asset.content_type,
+ :url => asset.source.url,
+ :vignette_url => asset.vignette_url,
+ :destroy_url => admin_asset_url(asset, :json),
+
+ }
+ end
+
end
end
diff --git a/config/routes.rb b/config/routes.rb
index 1ce539b1..da58ede1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -35,7 +35,7 @@ Rails.application.routes.draw do
resources :assets # TODO
- resources :images
+ resources :images, :controller => 'assets', :defaults => { :image => true }
resources :content_types
diff --git a/doc/TODO b/doc/TODO
index e2a5b980..efc7e4a9 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -5,14 +5,17 @@ x bushido version
~ editable_elements: inheritable: false (Mattias) => seems to be fixed by Dirk's last pull request (#44) => content tag
- remove asset_collections
x site templates
+ x tinyMCE plugin
+ x vignette.rb
+ x code
- helpers
- - tinyMCE plugin
- - vignette.rb
- - code
- ui
- - rake task
- - internal collection
- - assign same _id
+ x rake task
+ x internal collection
+ x assign same _id
+- pull request locomedia
+- SEO: support and support/ should be 2 different pages. Remove trailing slash
+- BUG: has_many. Delete an author
BACKLOG:
diff --git a/public/javascripts/admin/application.js b/public/javascripts/admin/application.js
index 5c789ccd..dc36d7f0 100644
--- a/public/javascripts/admin/application.js
+++ b/public/javascripts/admin/application.js
@@ -48,9 +48,9 @@ var TinyMceDefaultSettings = {
script_url : '/javascripts/admin/plugins/tiny_mce/tiny_mce.js',
theme : 'advanced',
skin : 'locomotive',
- plugins: 'safari,inlinepopups,locoimage',
+ plugins: 'safari,inlinepopups,locomedia',
theme_advanced_buttons1 : 'code,|,bold,italic,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,bullist,numlist,|,outdent,indent,blockquote,|,link,unlink',
- theme_advanced_buttons2 : 'formatselect,fontselect,fontsizeselect,|,image',
+ theme_advanced_buttons2 : 'formatselect,fontselect,fontsizeselect,|,locomedia',
theme_advanced_buttons3 : '',
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locoimage/css/locoimage.css b/public/javascripts/admin/plugins/tiny_mce/plugins/locoimage/css/locoimage.css
index 71f3bf07..18816d21 100644
--- a/public/javascripts/admin/plugins/tiny_mce/plugins/locoimage/css/locoimage.css
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locoimage/css/locoimage.css
@@ -1,18 +1,3 @@
-/*#src_list, #over_list, #out_list {width:280px;}
-.mceActionPanel {margin-top:7px;}
-.alignPreview {border:1px solid #000; width:140px; height:140px; overflow:hidden; padding:5px;}
-.checkbox {border:0;}
-.panel_wrapper div.current {height:305px;}
-#prev {margin:0; border:1px solid #000; width:428px; height:150px; overflow:auto;}
-#align, #classlist {width:150px;}
-#width, #height {vertical-align:middle; width:50px; text-align:center;}
-#vspace, #hspace, #border {vertical-align:middle; width:30px; text-align:center;}
-#class_list {width:180px;}
-input {width: 280px;}
-#constrain, #onmousemovecheck {width:auto;}
-#id, #dir, #lang, #usemap, #longdesc {width:200px;}
-*/
-
body {
font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
font-size: 1em;
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/css/style.css b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/css/style.css
new file mode 100644
index 00000000..d6ab462a
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/css/style.css
@@ -0,0 +1,95 @@
+body {
+ font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;
+ font-size: 1em;
+ overflow: hidden;
+}
+
+p.no-items {
+ padding: 18px 0px;
+ background: transparent url(/images/admin/list/none-small.png) no-repeat center 0;
+ text-align: center;
+ color: #9d8963 !important;
+ font-size: 1.1em !important;
+}
+
+.actions {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+}
+
+ul.assets {
+ overflow: auto;
+ height: 571px;
+}
+
+ul.assets li.asset h4 a {
+ top: 9px;
+ font-size: 0.7em;
+}
+
+ul.assets li.asset .inside {
+ cursor: pointer;
+}
+
+ul.assets li.asset div.actions {
+ top: 7px;
+}
+
+ul.assets li.new-asset {
+ display: none;
+}
+
+#upload-link {
+ float: left;
+ display: block;
+ background: transparent url("/images/admin/buttons/dark-gray-bg.png") repeat-x 0 0;
+ outline: none;
+ -moz-border-radius : 4px;
+ -webkit-border-radius: 4px;
+ height: 20px;
+ font-size: 0.8em;
+ font-family: 'Lucida Grande';
+ padding: 5px 12px 5px 12px;
+ margin: 5px 0 0 14px;
+ color: #fff !important;
+ text-decoration: none;
+ text-shadow: 1px 1px 1px #000;
+}
+
+#spinner {
+ position: fixed;
+ top: 40%;
+ left: 30%;
+ height: 60px;
+ width: 250px;
+ background: transparent;
+ z-index: 999;
+}
+
+#spinner .overlay, #spinner .text {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ -moz-border-radius : 10px;
+ -webkit-border-radius: 10px;
+}
+
+#spinner .overlay {
+ background: #000;
+ opacity: 0.8;
+}
+
+#spinner .text {
+ padding: 20px 0;
+ text-align: center;
+ font-size: 1.1em;
+ color: #fff;
+ text-shadow: 1px 1px 1px #000;
+}
+
+.mceActionPanel input {
+ font-size: 0.8em;
+}
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/dialog.htm b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/dialog.htm
new file mode 100644
index 00000000..1261f296
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/dialog.htm
@@ -0,0 +1,61 @@
+
+
+
+ {#locomedia_dlg.dialog_title}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{#locomedia_dlg.loading}
+
{#locomedia_dlg.uploading}
+
{#locomedia_dlg.destroying}
+
+
+ {#locomedia_dlg.no_items}
+
+
+
+
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin.js
new file mode 100644
index 00000000..7f89b731
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin.js
@@ -0,0 +1,48 @@
+// (function(){tinymce.create('tinymce.plugins.LocoMediafilePlugin',{init:function(ed,url){ed.addCommand('locoMediafile',function(){ed.windowManager.open({file:url+'/mediafile.htm',width:645,height:650,inline:1},{plugin_url:url})});ed.addButton('mediafile',{title:'locomediafile.image_desc',cmd:'locoMediaFile'})},getInfo:function(){return{longname:'Locomotive Media File',author:'Locomotive Engine',authorurl:'http://www.locomotivecms.com',infourl:'http://www.locomotiveapp.com',version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add('locomedia',tinymce.plugins.LocoMediafilePlugin)})();
+
+/**
+ * editor_plugin_src.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under LGPL License.
+ *
+ * License: http://tinymce.moxiecode.com/license
+ * Contributing: http://tinymce.moxiecode.com/contributing
+ */
+
+(function() {
+ tinymce.create('tinymce.plugins.LocoMediaPlugin', {
+ init : function(ed, url) {
+ // Register commands
+ ed.addCommand('locoMedia', function() {
+ ed.windowManager.open({
+ file : url + '/dialog.htm',
+ width : 645,
+ height : 650,
+ inline : 1
+ }, {
+ plugin_url : url
+ });
+ });
+
+ // Register buttons
+ ed.addButton('locomedia', {
+ title : 'locomedia.image_desc',
+ cmd : 'locoMedia'
+ });
+ },
+
+ getInfo : function() {
+ return {
+ longname : 'Locomotive Media File',
+ author : 'Didier Lafforgue',
+ authorurl : 'http://www.locomotivecms.com',
+ infourl : 'http://www.locomotivecms.com',
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
+ };
+ }
+ });
+
+ // Register plugin
+ tinymce.PluginManager.add('locomedia', tinymce.plugins.LocoMediaPlugin);
+})();
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin_src.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin_src.js
new file mode 100644
index 00000000..d86a87b7
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/editor_plugin_src.js
@@ -0,0 +1,46 @@
+/**
+ * editor_plugin_src.js
+ *
+ * Copyright 2009, Moxiecode Systems AB
+ * Released under LGPL License.
+ *
+ * License: http://tinymce.moxiecode.com/license
+ * Contributing: http://tinymce.moxiecode.com/contributing
+ */
+
+(function() {
+ tinymce.create('tinymce.plugins.LocoMediafilePlugin', {
+ init : function(ed, url) {
+ // Register commands
+ ed.addCommand('locoMediafile', function() {
+ ed.windowManager.open({
+ file : url + '/dialog.htm',
+ width : 645,
+ height : 650,
+ inline : 1
+ }, {
+ plugin_url : url
+ });
+ });
+
+ // Register buttons
+ ed.addButton('mediafile', {
+ title : 'locomediafile.image_desc',
+ cmd : 'locoMediaFile'
+ });
+ },
+
+ getInfo : function() {
+ return {
+ longname : 'Locomotive Media File',
+ author : 'Locomotive Engine',
+ authorurl : 'http://www.locomotivecms.com',
+ infourl : 'http://www.locomotivecms.com',
+ version : tinymce.majorVersion + "." + tinymce.minorVersion
+ };
+ }
+ });
+
+ // Register plugin
+ tinymce.PluginManager.add('locomedia', tinymce.plugins.LocoMediafilePlugin);
+})();
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/img/sample.gif b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/img/sample.gif
new file mode 100644
index 00000000..53bf6890
Binary files /dev/null and b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/img/sample.gif differ
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/js/dialog.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/js/dialog.js
new file mode 100644
index 00000000..6b03acf6
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/js/dialog.js
@@ -0,0 +1,197 @@
+var MediafileDialog = {
+ formElement: null,
+
+ listElement: null,
+
+ preInit : function() {
+ var url;
+
+ tinyMCEPopup.requireLangPack();
+
+ if (url = tinyMCEPopup.getParam("external_image_list_url"))
+ document.write('');
+ },
+
+ init : function(ed) {
+ var self = this;
+
+ formElement = $(document.forms[0]);
+
+ listElement = formElement.find('ul');
+
+ $.getJSON('/admin/assets.json', function(data) {
+ $(data.assets).each(function() {
+ self._addAsset(this);
+ });
+
+ self.setupUploader();
+
+ self.hideSpinner();
+
+ if ($('ul li.asset').length == 0) $('p.no-items').show();
+ });
+ },
+
+ hideSpinner: function() {
+ $('#spinner').hide();
+ },
+
+ showSpinner: function(msg) {
+ $('#spinner .text').hide();
+ $('#spinner .' + msg).show();
+ $('#spinner').show();
+ },
+
+ insertFile: function(asset) {
+ var ed = tinyMCEPopup.editor, f = document.forms[0], nl = f.elements, v, args = {}, el;
+
+ tinyMCEPopup.restoreSelection();
+
+ // Fixes crash in Safari
+ if (tinymce.isWebKit) ed.getWin().focus();
+
+ if (asset.content_type == 'image')
+ tinymce.extend(args, { src : asset.url });
+ else
+ tinymce.extend(args, { href : asset.url });
+
+ el = ed.selection.getNode();
+
+ if (el && (el.nodeName == 'IMG' || el.nodeName == 'A')) {
+ ed.dom.setAttribs(el, args);
+ } else {
+ if (asset.content_type == 'image') {
+ ed.execCommand('mceInsertContent', false, '', { skip_undo: 1 });
+ } else {
+ var html = ed.selection.getContent();
+ if (html == '') html = asset.filename;
+ ed.execCommand('mceInsertContent', false, '' + html + '', { skip_undo: 1 });
+ }
+
+
+ ed.dom.setAttribs('__mce_tmp', args);
+ ed.dom.setAttrib('__mce_tmp', 'id', '');
+ ed.undoManager.add();
+ }
+
+ tinyMCEPopup.close();
+ },
+
+ setupUploader: function() {
+ var self = this;
+ var multipartParams = {};
+
+ with(window.parent) {
+ multipartParams[$('meta[name=csrf-param]').attr('content')] = $('meta[name=csrf-token]').attr('content');
+ }
+
+ var uploader = new plupload.Uploader({
+ runtimes : (jQuery.browser.webkit == true ? 'flash' : 'html5,flash'),
+ browse_button : 'upload-link',
+ max_file_size : '10mb',
+ url : $('a#upload-link').attr('href'),
+ flash_swf_url : '/javascripts/admin/plugins/plupload/plupload.flash.swf',
+ multipart: true,
+ multipart_params: multipartParams,
+ filters : [
+ { title : 'Media files', extensions : 'png,gif,jpg,jpeg,pdf,doc,docx,xls,xlsx,txt' },
+ ]
+ });
+
+ uploader.bind('QueueChanged', function() {
+ self.showSpinner('uploading');
+ uploader.start();
+ });
+
+ uploader.bind('FileUploaded', function(up, file, response) {
+ var json = JSON.parse(response.response);
+
+ if (json.status == 'success')
+ self._addAsset(json);
+
+ self.hideSpinner();
+ });
+
+ uploader.init();
+ },
+
+ _addAsset: function(data) {
+ var self = this;
+
+ var asset = $('ul li.new-asset')
+ .clone()
+ .insertBefore($('ul li.clear'))
+ .addClass('asset');
+
+ asset.find('h4 a').attr('href', data.url)
+ .html(data.short_name)
+ .bind('click', function(e) {
+ self.insertFile(data);
+ e.stopPropagation(); e.preventDefault();
+ });
+
+ html = '';
+
+ if (data.content_type == 'image') {
+ asset.find('.icon').removeClass('icon').addClass('image');
+ html = $('')
+ .attr('src', data.vignette_url)
+ .bind('click', function(e) {
+ self.insertFile(data);
+ });
+ } else {
+ asset.find('.icon').addClass(data.content_type);
+ html = data.content_type == 'other' ? data.extname : data.content_type;
+ if (html == '') html = '?'
+ html = $('').html(html)
+ .bind('click', function(e) {
+ self.insertFile(data);
+ });
+ }
+
+ asset.find('.inside').append(html);
+
+ asset.find('.actions a')
+ .attr('href', data.destroy_url)
+ .bind('click', function(e) {
+ if (confirm($(this).attr('data-confirm'))) {
+ self.showSpinner('destroying');
+ $(this).callRemote();
+ }
+ e.preventDefault(); e.stopPropagation();
+ })
+ .bind('ajax:success', function(event, data) {
+ self._destroyAsset(asset);
+ });
+
+ if ($('ul li.asset').length % 4 == 0)
+ asset.addClass('last');
+
+ asset.removeClass('new-asset');
+
+ $('p.no-items').hide();
+
+ $('ul').scrollTo($('li.asset:last'), 400);
+ },
+
+ _destroyAsset: function(asset) {
+ asset.remove();
+
+ if ($('ul li.asset').length == 0) {
+ $('p.no-items').show();
+ } else {
+ $('ul li.asset').each(function(index) {
+ if ((index + 1) % 4 == 0)
+ $(this).addClass('last');
+ else
+ $(this).removeClass('last');
+ });
+ }
+
+ this.hideSpinner();
+ }
+
+};
+
+MediafileDialog.preInit();
+tinyMCEPopup.onInit.add(MediafileDialog.init, MediafileDialog);
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/de_dlg.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/de_dlg.js
new file mode 100644
index 00000000..0c0fc6a1
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/de_dlg.js
@@ -0,0 +1,9 @@
+tinyMCE.addI18n('de.locomedia_dlg',{
+ dialog_title: 'Mediendatei einfügen',
+ upload: 'Mediendatei hochladen',
+ loading: 'Laden...',
+ uploading: 'Hochladen...',
+ destroying: 'Löschen...',
+ confirm: 'Bist du sicher ?',
+ no_items: 'Momentan gibt es hier keine Mediendateien.'
+});
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/en_dlg.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/en_dlg.js
new file mode 100644
index 00000000..47b6b504
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/en_dlg.js
@@ -0,0 +1,9 @@
+tinyMCE.addI18n('en.locomedia_dlg',{
+ dialog_title: 'Insert media',
+ upload: 'Upload media',
+ loading: 'Loading...',
+ uploading: 'Uploading...',
+ destroying: 'Destroying...',
+ confirm: 'Are you sure ?',
+ no_items: 'There are no media for now.'
+});
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/fr_dlg.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/fr_dlg.js
new file mode 100644
index 00000000..fd481ece
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/fr_dlg.js
@@ -0,0 +1,9 @@
+tinyMCE.addI18n('fr.locomedia_dlg',{
+ dialog_title: 'Insérer un média',
+ upload: 'Uploader média',
+ loading: 'Chargement...',
+ uploading: 'Uploading...',
+ destroying: 'Suppression...',
+ confirm: 'Êtes-vous sûr(e) ?',
+ no_items: 'Il n\'y a aucun média pour l\'instant'
+});
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/it_dlg.js b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/it_dlg.js
new file mode 100644
index 00000000..e1d651ef
--- /dev/null
+++ b/public/javascripts/admin/plugins/tiny_mce/plugins/locomedia/langs/it_dlg.js
@@ -0,0 +1,9 @@
+tinyMCE.addI18n('it.locomedia_dlg',{
+ dialog_title: 'Inserisci immagine',
+ upload: 'Carica immagine',
+ loading: 'Caricamento...',
+ uploading: 'Caricamento file...',
+ destroying: 'Eliminazione...',
+ confirm: 'Sicuro?',
+ no_items: 'Per ora non ci sono immagini.'
+});
\ No newline at end of file
diff --git a/public/javascripts/admin/plugins/tiny_mce/themes/advanced/skins/locomotive/ui.css b/public/javascripts/admin/plugins/tiny_mce/themes/advanced/skins/locomotive/ui.css
index 0a54f0a2..48190d08 100755
--- a/public/javascripts/admin/plugins/tiny_mce/themes/advanced/skins/locomotive/ui.css
+++ b/public/javascripts/admin/plugins/tiny_mce/themes/advanced/skins/locomotive/ui.css
@@ -728,6 +728,10 @@
background-position: -380px 0
}
+.locomotiveSkin span.mce_locomedia {
+ background-position: -380px 0
+}
+
.locomotiveSkin span.mce_help {
background-position: -340px 0
}
diff --git a/spec/lib/locomotive/render_spec.rb b/spec/lib/locomotive/render_spec.rb
index d65cd106..358cee92 100644
--- a/spec/lib/locomotive/render_spec.rb
+++ b/spec/lib/locomotive/render_spec.rb
@@ -51,7 +51,6 @@ describe 'Locomotive rendering system' do
end
it 'sets the status to 404 not found when no page is found' do
- # @controller.expects(:not_found_page).returns(@page)
@page.stubs(:not_found?).returns(true)
@controller.send(:prepare_and_set_response, 'Hello world !')
@controller.status.should == :not_found