diff options
| author | Frédéric van der Essen <fva@openerp.com> | 2013-08-19 16:11:08 +0200 |
|---|---|---|
| committer | Frédéric van der Essen <fva@openerp.com> | 2013-08-19 16:11:08 +0200 |
| commit | 63dd1b0bb73d2a71b3a643ea1a613ca3759ceacf (patch) | |
| tree | 94366fbe12a54730d467fa365dcde31a22140a0e /addons/website | |
| parent | 660e8798abdd73eb56f1b571654edb39707c24c2 (diff) | |
| parent | c94c7c42260bb878b0c0dfa921a0558f7dc005be (diff) | |
[MERGE] from trunk
bzr revid: fva@openerp.com-20130819141108-s2vsjqdzzzlib4oi
Diffstat (limited to 'addons/website')
| -rw-r--r-- | addons/website/__openerp__.py | 8 | ||||
| -rw-r--r-- | addons/website/controllers/main.py | 3 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.js | 760 | ||||
| -rw-r--r-- | addons/website/static/src/js/website_bootstrap.js | 19 | ||||
| -rw-r--r-- | addons/website/views/views.xml | 45 | ||||
| -rw-r--r-- | addons/website/website.py | 35 |
6 files changed, 423 insertions, 447 deletions
diff --git a/addons/website/__openerp__.py b/addons/website/__openerp__.py index 14e8aaa3564..aa0f5dbf64f 100644 --- a/addons/website/__openerp__.py +++ b/addons/website/__openerp__.py @@ -15,13 +15,5 @@ OpenERP Website CMS 'views/views.xml', 'views/res_config.xml', 'website_data.xml', - ], - 'js': [ - 'static/lib/bootstrap/js/bootstrap.js', - 'static/src/js/website.js', ], - 'css': [ - 'static/src/css/editor.css', - ], - 'qweb': ['static/src/xml/*.xml'], } diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index f6c7726df23..bd3f7285126 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -164,9 +164,6 @@ class Website(openerp.addons.web.controllers.main.Home): etag = request.httprequest.headers.get('If-None-Match') hashed_session = hashlib.md5(request.session_id).hexdigest() retag = hashed_session - - print Model.search(request.cr, request.uid, [(1,'=',1)]) - try: if etag: date = Model.read(request.cr, request.uid, [id], [last_update], request.context)[0].get(last_update) diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 8eaf0c42e0c..eb224c7905c 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -1,434 +1,384 @@ -openerp.website = function(instance) { - -instance.web.ActionManager.include({ - // Temporary fix until un-webclientization of the editorbar - ir_actions_client: function (action) { - if (instance.web.client_actions.get_object(action.tag)) { - return this._super.apply(this, arguments); - } else { - console.warn("Action '%s' not found in registry", action.tag); - return $.when(); - } +$(function(){ + + // Ugly. I'll clean this monday + if ($('html').attr('data-editable') !== '1'){ + return; } -}); -var _lt = instance.web._lt; -var QWeb = instance.web.qweb; -instance.website.EditorBar = instance.web.Widget.extend({ - template: 'Website.EditorBar', - events: { - 'click button[data-action=edit]': 'edit', - 'click button[data-action=save]': 'save', - 'click button[data-action=cancel]': 'cancel', - 'click button[data-action=snippet]': 'snippet', - }, - container: 'body', - init: function () { - this._super.apply(this, arguments); - this.saving_mutex = new $.Mutex(); - }, - customize_setup: function() { - var self = this; - var view_name = $('html').data('view-xmlid'); - var menu = $('#customize-menu'); - this.$('#customize-menu-button').click(function(event) { - menu.empty(); - self.rpc('/website/customize_template_get', { 'xml_id': view_name }).then( - function(result) { - _.each(result, function (item) { - if (item.header) { - menu.append('<li class="nav-header">' + item.name + '</li>'); - } else { - menu.append(_.str.sprintf('<li><a href="#" data-view-id="%s"><strong class="icon-check%s"></strong> %s</a></li>', - item.id, item.active ? '' : '-empty', item.name)); - } - }); + // TODO fme: put everything in openerp.website scope and load templates on + // next tick or document ready + // Also check with xmo if jquery.keypress.js is still needed. + + /* ----- TEMPLATE LOADING ---- */ + + function loadTemplates(templates) { + var def = $.Deferred(); + var count = templates.length; + templates.forEach(function(t) { + openerp.qweb.add_template(t, function(err) { + if (err) { + def.reject(); + } else { + count--; + if (count < 1) { + def.resolve(); + } } - ); - }); - menu.on('click', 'a', function (event) { - var view_id = $(event.target).data('view-id'); - self.rpc('/website/customize_template_toggle', { - 'view_id': view_id - }).then( function(result) { - window.location.reload(); - }); - }); - }, - start: function() { - var self = this; - - this.$('#website-top-edit').hide(); - this.$('#website-top-view').show(); - - $('.dropdown-toggle').dropdown(); - this.customize_setup(); - - this.$buttons = { - edit: this.$('button[data-action=edit]'), - save: this.$('button[data-action=save]'), - cancel: this.$('button[data-action=cancel]'), - snippet: this.$('button[data-action=snippet]'), - }; - - this.rte = new instance.website.RTE(this); - this.rte.on('change', this, this.proxy('rte_changed')); - - this.snippets = new instance.website.Snippets(); - this.snippets.appendTo($("body")); - - return $.when( - this._super.apply(this, arguments), - this.rte.insertBefore(this.$buttons.snippet.parent()) - ); - }, - edit: function () { - this.$buttons.edit.prop('disabled', true); - this.$('#website-top-view').hide(); - this.$('#website-top-edit').show(); - - // this.$buttons.cancel.add(this.$buttons.snippet).prop('disabled', false) - // .add(this.$buttons.save) - // .parent().show(); - // - // TODO: span edition changing edition state (save button) - var $editables = $('[data-oe-model]') - .not('link, script') - // FIXME: propagation should make "meta" blocks non-editable in the first place... - .not('.oe_snippet_editor') - .prop('contentEditable', true) - .addClass('oe_editable'); - var $rte_ables = $editables.not('[data-oe-type]'); - var $raw_editables = $editables.not($rte_ables); - - // temporary fix until we fix ckeditor - $raw_editables.each(function () { - $(this).parents().add($(this).find('*')).on('click', function(ev) { - ev.preventDefault(); - ev.stopPropagation(); }); }); + return def; + } - this.rte.start_edition($rte_ables); - $raw_editables.on('keydown keypress cut paste', function (e) { - var $target = $(e.target); - if ($target.hasClass('oe_dirty')) { - return; - } + var templates = [ + '/website/static/src/xml/website.xml' + ]; - $target.addClass('oe_dirty'); - this.$buttons.save.prop('disabled', false); - }.bind(this)); - }, - rte_changed: function () { - this.$buttons.save.prop('disabled', false); - }, - save: function () { - var self = this; - var defs = []; - $('.oe_dirty').each(function (i, v) { - var $el = $(this); - // TODO: Add a queue with concurrency limit in webclient - // https://github.com/medikoo/deferred/blob/master/lib/ext/function/gate.js - var def = self.saving_mutex.exec(function () { - return self.saveElement($el).then(function () { - $el.removeClass('oe_dirty'); - }).fail(function () { - var data = $el.data(); - console.error(_.str.sprintf('Could not save %s#%d#%s', data.oeModel, data.oeId, data.oeField)); - }); - }); - defs.push(def); - }); - return $.when.apply(null, defs).then(function () { - window.location.reload(); + loadTemplates(templates).then(function(){ + var editor = new EditorBar(); + editor.prependTo($('body')); + $('body').css('padding-top', '50px'); // Not working properly: editor.$el.outerHeight()); + // TODO: Create an openerp.Widget out of this + }); + + /* ----- PUBLISHING STUFF ---- */ + + $(document).on('click', '.js_publish, .js_unpublish', function (e) { + e.preventDefault(); + var $link = $(this).parent(); + $link.find('.js_publish, .js_unpublish').addClass("hidden"); + var $unp = $link.find(".js_unpublish"); + var $p = $link.find(".js_publish"); + $.post('/website/publish', {'id': $link.data('id'), 'object': $link.data('object')}, function (result) { + if (+result) { + $p.addClass("hidden"); + $unp.removeClass("hidden"); + } else { + $p.removeClass("hidden"); + $unp.addClass("hidden"); + } }); - }, - saveElement: function ($el) { - var data = $el.data(); - var html = $el.html(); - var xpath = data.oeXpath; - if (xpath) { - var $w = $el.clone(); - $w.removeClass('oe_dirty'); - _.each(['model', 'id', 'field', 'xpath'], function(d) {$w.removeAttr('data-oe-' + d);}); - $w - .removeClass('oe_editable') - .prop('contentEditable', false); - html = $w.wrap('<div>').parent().html(); - } - return (new instance.web.DataSet(this, 'ir.ui.view')).call('save', [data.oeModel, data.oeId, data.oeField, html, xpath]); - }, - cancel: function () { - window.location.reload(); - }, - snippet: function (ev) { - this.snippets.toggle(); - }, -}); + }); -instance.website.RTE = instance.web.Widget.extend({ - tagName: 'li', - id: 'oe_rte_toolbar', - className: 'oe_right oe_rte_toolbar', - // editor.ui.items -> possible commands &al - // editor.applyStyle(new CKEDITOR.style({element: "span",styles: {color: "#(color)"},overrides: [{element: "font",attributes: {color: null}}]}, {color: '#ff0000'})); - - start_edition: function ($elements) { - var self = this; - this.snippet_carousel(); - $elements - .not('span, [data-oe-type]') - .each(function () { - var $this = $(this); - CKEDITOR.inline(this, self._config()).on('change', function () { - $this.addClass('oe_dirty'); - self.trigger('change', this, null); + /* ----- TOP EDITOR BAR FOR ADMIN ---- */ + + var EditorBar = openerp.Widget.extend({ + template: 'Website.EditorBar', + events: { + 'click button[data-action=edit]': 'edit', + 'click button[data-action=save]': 'save', + 'click button[data-action=cancel]': 'cancel', + 'click button[data-action=snippet]': 'snippet', + }, + container: 'body', + customize_setup: function() { + var self = this; + var view_name = $('html').data('view-xmlid'); + var menu = $('#customize-menu'); + this.$('#customize-menu-button').click(function(event) { + menu.empty(); + openerp.jsonRpc('/website/customize_template_get', 'call', { 'xml_id': view_name }).then( + function(result) { + _.each(result, function (item) { + if (item.header) { + menu.append('<li class="nav-header">' + item.name + '</li>'); + } else { + menu.append(_.str.sprintf('<li><a href="#" data-view-id="%s"><strong class="icon-check%s"></strong> %s</a></li>', + item.id, item.active ? '' : '-empty', item.name)); + } + }); + } + ); + }); + menu.on('click', 'a', function (event) { + var view_id = $(event.target).data('view-id'); + openerp.jsonRpc('/website/customize_template_toggle', 'call', { + 'view_id': view_id + }).then( function(result) { + window.location.reload(); }); }); - }, - - _current_editor: function () { - return CKEDITOR.currentInstance; - }, - _config: function () { - var removed_plugins = [ - // remove custom context menu - 'contextmenu,tabletools,liststyle', - // magicline captures mousein/mouseout => draggable does not work - 'magicline' - ]; - return { - // Disable auto-generated titles - // FIXME: accessibility, need to generate user-sensible title, used for @title and @aria-label - title: false, - removePlugins: removed_plugins.join(','), - uiColor: '', - // Ensure no config file is loaded - customConfig: '', - // Disable ACF - allowedContent: true, - // Don't insert paragraphs around content in e.g. <li> - autoParagraph: false, - filebrowserImageUploadUrl: "/website/attach", - // Support for sharedSpaces in 4.x - extraPlugins: 'sharedspace', - // Place toolbar in controlled location - sharedSpaces: { top: 'oe_rte_toolbar' }, - toolbar: [ - {name: 'basicstyles', items: [ - "Bold", "Italic", "Underline", "Strike", "Subscript", - "Superscript", "TextColor", "BGColor", "RemoveFormat" - ]},{ - name: 'span', items: [ - "Link", "Unlink", "Blockquote", "BulletedList", - "NumberedList", "Indent", "Outdent", - ]},{ - name: 'justify', items: [ - "JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock" - ]},{ - name: 'special', items: [ - "Image", "Table" - ]},{ - name: 'styles', items: [ - "Format", "Styles" - ]} - ], - // styles dropdown in toolbar - stylesSet: [ - // emphasis - {name: "Muted", element: 'span', attributes: {'class': 'text-muted'}}, - {name: "Primary", element: 'span', attributes: {'class': 'text-primary'}}, - {name: "Warning", element: 'span', attributes: {'class': 'text-warning'}}, - {name: "Danger", element: 'span', attributes: {'class': 'text-danger'}}, - {name: "Success", element: 'span', attributes: {'class': 'text-success'}}, - {name: "Info", element: 'span', attributes: {'class': 'text-info'}} - ], - }; - }, - // TODO clean - snippet_carousel: function () { - var self = this; - $('.carousel .js_carousel_options .label').on('click', function (e) { - e.preventDefault(); - var $button = $(e.currentTarget); - var $c = $button.parents(".carousel:first"); - - if($button.hasClass("js_add")) { - var cycle = $c.find(".carousel-inner .item").size(); - $c.find(".carousel-inner").append(QWeb.render("Website.Snipped.carousel")); - $c.carousel(cycle); - } - else { - var cycle = $c.find(".carousel-inner .item.active").remove(); - $c.find(".carousel-inner .item:first").addClass("active"); - $c.carousel(0); - self.trigger('change', self, null); - } - }); - $('.carousel .js_carousel_options').show(); - } -}); + }, + start: function() { + var self = this; -instance.website.Snippets = instance.web.Widget.extend({ - template: 'website.snippets', - init: function () { - this._super.apply(this, arguments); - }, - start: function() { - var self = this; - - $.ajax({ - type: "GET", - url: "/page/website.snippets", - dataType: "text", - success: function(text){ - self.$el.html(text); - }, - }); + this.saving_mutex = new openerp.Mutex(); - // load snippets - // /page/website.snippets - }, - setup_droppable: function () { - var self = this; - $('.oe_snippet_drop').remove(); - var droppable = '<div class="oe_snippet_drop"></div>'; - var $zone = $(':not(.oe_snippet) > .container'); - $zone.after(droppable);//.after(droppable); - - $(".oe_snippet_drop").droppable({ - hoverClass: 'oe_accepting', - drop: function( event, ui ) { - console.log(event, ui, "DROP"); - - $(event.target).replaceWith($(ui.draggable).html()); - $('.oe_selected').remove(); - $('.oe_snippet_drop').remove(); - } - }); - }, - toggle: function(){ - if(this.$el.hasClass('oe_hidden')){ - this.$el.removeClass('oe_hidden'); - }else{ - this.$el.addClass('oe_hidden'); - } - }, - snippet_start: function () { - var self = this; - $('.oe_snippet').draggable().click(function(ev) { - self.setup_droppable(); - $(".oe_snippet_drop").show(); - $('.oe_selected').removeClass('oe_selected'); - $(ev.currentTarget).addClass('oe_selected'); - }); + this.$('#website-top-edit').hide(); + this.$('#website-top-view').show(); - }, -}); + $('.dropdown-toggle').dropdown(); + this.customize_setup(); -$(function(){ + this.$buttons = { + edit: this.$('button[data-action=edit]'), + save: this.$('button[data-action=save]'), + cancel: this.$('button[data-action=cancel]'), + snippet: this.$('button[data-action=snippet]'), + }; - function make_static(){ - $('.oe_snippet_demo').removeClass('oe_new'); - $('.oe_page *').off('mouseover mouseleave'); - $('.oe_page .oe_selected').removeClass('oe_selected'); - } + this.rte = new RTE(this); + this.rte.on('change', this, this.proxy('rte_changed')); - var selected_snippet = null; - function snippet_click(event){ - if(selected_snippet){ - selected_snippet.removeClass('oe_selected'); - if(selected_snippet[0] === $(this)[0]){ - selected_snippet = null; - event.preventDefault(); - make_static(); - return; - } - } - $(this).addClass('oe_selected'); - selected_snippet = $(this); - make_editable(); - event.preventDefault(); - } - //$('.oe_snippet').click(snippet_click); + this.snippets = new Snippets(); + this.snippets.appendTo($("body")); - var hover_element = null; + return $.when( + this._super.apply(this, arguments), + this.rte.insertBefore(this.$buttons.snippet.parent()) + ); + }, + edit: function () { + this.$buttons.edit.prop('disabled', true); + this.$('#website-top-view').hide(); + this.$('#website-top-edit').show(); + + // this.$buttons.cancel.add(this.$buttons.snippet).prop('disabled', false) + // .add(this.$buttons.save) + // .parent().show(); + // + // TODO: span edition changing edition state (save button) + var $editables = $('[data-oe-model]') + .not('link, script') + // FIXME: propagation should make "meta" blocks non-editable in the first place... + .not('.oe_snippet_editor') + .prop('contentEditable', true) + .addClass('oe_editable'); + var $rte_ables = $editables.not('[data-oe-type]'); + var $raw_editables = $editables.not($rte_ables); + + // temporary fix until we fix ckeditor + $raw_editables.each(function () { + $(this).parents().add($(this).find('*')).on('click', function(ev) { + ev.preventDefault(); + ev.stopPropagation(); + }); + }); - function make_editable( constraint_after, constraint_inside ){ - if(selected_snippet && selected_snippet.hasClass('oe_new')){ - $('.oe_snippet_demo').addClass('oe_new'); - }else{ - $('.oe_snippet_demo').removeClass('oe_new'); - } - - $('.oe_page *').off('mouseover'); - $('.oe_page *').off('mouseleave'); - $('.oe_page *').mouseover(function(event){ - console.log('hover:',this); - if(hover_element){ - hover_element.removeClass('oe_selected'); - hover_element.off('click'); - } - $(this).addClass('oe_selected'); - $(this).click(append_snippet); - hover_element = $(this); - event.stopPropagation(); - }); - $('.oe_page *').mouseleave(function(){ - if(hover_element && $(this) === hover_element){ - hover_element = null; - $(this).removeClass('oe_selected'); - } - }); - } + this.rte.start_edition($rte_ables); + $raw_editables.on('keydown keypress cut paste', function (e) { + var $target = $(e.target); + if ($target.hasClass('oe_dirty')) { + return; + } - function customier_option_get(event){ + $target.addClass('oe_dirty'); + this.$buttons.save.prop('disabled', false); + }.bind(this)); + }, + rte_changed: function () { + this.$buttons.save.prop('disabled', false); + }, + save: function () { + var self = this; + var defs = []; + $('.oe_dirty').each(function (i, v) { + var $el = $(this); + // TODO: Add a queue with concurrency limit in webclient + // https://github.com/medikoo/deferred/blob/master/lib/ext/function/gate.js + var def = self.saving_mutex.exec(function () { + return self.saveElement($el).then(function () { + $el.removeClass('oe_dirty'); + }).fail(function () { + var data = $el.data(); + console.error(_.str.sprintf('Could not save %s#%d#%s', data.oeModel, data.oeId, data.oeField)); + }); + }); + defs.push(def); + }); + return $.when.apply(null, defs).then(function () { + window.location.reload(); + }); + }, + saveElement: function ($el) { + var data = $el.data(); + var html = $el.html(); + var xpath = data.oeXpath; + if (xpath) { + var $w = $el.clone(); + $w.removeClass('oe_dirty'); + _.each(['model', 'id', 'field', 'xpath'], function(d) {$w.removeAttr('data-oe-' + d);}); + $w + .removeClass('oe_editable') + .prop('contentEditable', false); + html = $w.wrap('<div>').parent().html(); + } + return openerp.jsonRpc('/web/dataset/call', 'call', { + model: 'ir.ui.view', + method: 'save', + args: [data.oeModel, data.oeId, data.oeField, html, xpath] + }); + }, + cancel: function () { + window.location.reload(); + }, + snippet: function (ev) { + this.snippets.toggle(); + }, + }); + /* ----- RICH TEXT EDITOR ---- */ + + var RTE = openerp.Widget.extend({ + tagName: 'li', + id: 'oe_rte_toolbar', + className: 'oe_right oe_rte_toolbar', + // editor.ui.items -> possible commands &al + // editor.applyStyle(new CKEDITOR.style({element: "span",styles: {color: "#(color)"},overrides: [{element: "font",attributes: {color: null}}]}, {color: '#ff0000'})); + + start_edition: function ($elements) { + var self = this; + this.snippet_carousel(); + $elements + .not('span, [data-oe-type]') + .each(function () { + var $this = $(this); + CKEDITOR.inline(this, self._config()).on('change', function () { + $this.addClass('oe_dirty'); + self.trigger('change', this, null); + }); + }); + }, + + _current_editor: function () { + return CKEDITOR.currentInstance; + }, + _config: function () { + var removed_plugins = [ + // remove custom context menu + 'contextmenu,tabletools,liststyle', + // magicline captures mousein/mouseout => draggable does not work + 'magicline' + ]; + return { + // Disable auto-generated titles + // FIXME: accessibility, need to generate user-sensible title, used for @title and @aria-label + title: false, + removePlugins: removed_plugins.join(','), + uiColor: '', + // Ensure no config file is loaded + customConfig: '', + // Disable ACF + allowedContent: true, + // Don't insert paragraphs around content in e.g. <li> + autoParagraph: false, + filebrowserImageUploadUrl: "/website/attach", + // Support for sharedSpaces in 4.x + extraPlugins: 'sharedspace', + // Place toolbar in controlled location + sharedSpaces: { top: 'oe_rte_toolbar' }, + toolbar: [ + {name: 'basicstyles', items: [ + "Bold", "Italic", "Underline", "Strike", "Subscript", + "Superscript", "TextColor", "BGColor", "RemoveFormat" + ]},{ + name: 'span', items: [ + "Link", "Unlink", "Blockquote", "BulletedList", + "NumberedList", "Indent", "Outdent", + ]},{ + name: 'justify', items: [ + "JustifyLeft", "JustifyCenter", "JustifyRight", "JustifyBlock" + ]},{ + name: 'special', items: [ + "Image", "Table" + ]},{ + name: 'styles', items: [ + "Format", "Styles" + ]} + ], + // styles dropdown in toolbar + stylesSet: [ + // emphasis + {name: "Muted", element: 'span', attributes: {'class': 'text-muted'}}, + {name: "Primary", element: 'span', attributes: {'class': 'text-primary'}}, + {name: "Warning", element: 'span', attributes: {'class': 'text-warning'}}, + {name: "Danger", element: 'span', attributes: {'class': 'text-danger'}}, + {name: "Success", element: 'span', attributes: {'class': 'text-success'}}, + {name: "Info", element: 'span', attributes: {'class': 'text-info'}} + ], + }; + }, + // TODO clean + snippet_carousel: function () { + var self = this; + $('.carousel .js_carousel_options .label').on('click', function (e) { + e.preventDefault(); + var $button = $(e.currentTarget); + var $c = $button.parents(".carousel:first"); + + if($button.hasClass("js_add")) { + var cycle = $c.find(".carousel-inner .item").size(); + $c.find(".carousel-inner").append(QWeb.render("Website.Snipped.carousel")); + $c.carousel(cycle); + } + else { + var cycle = $c.find(".carousel-inner .item.active").remove(); + $c.find(".carousel-inner .item:first").addClass("active"); + $c.carousel(0); + self.trigger('change', self, null); + } + }); + $('.carousel .js_carousel_options').show(); + } + }); - event.preventDefault(); - } + /* ----- SNIPPET SELECTOR ---- */ + + var Snippets = openerp.Widget.extend({ + template: 'website.snippets', + init: function () { + this._super.apply(this, arguments); + }, + start: function() { + var self = this; + + $.ajax({ + type: "GET", + url: "/page/website.snippets", + dataType: "text", + success: function(text){ + self.$el.html(text); + }, + }); - function append_snippet(event){ - console.log('click',this,event.button); - if(event.button === 0){ - if(selected_snippet){ - if(selected_snippet.hasClass('oe_new')){ - var new_snippet = $("<div class='oe_snippet'></div>"); - new_snippet.append($(this).clone()); - new_snippet.click(snippet_click); - $('.oe_snippet.oe_selected').before(new_snippet); - }else{ - $(this).after($('.oe_snippet.oe_selected').contents().clone()); + // load snippets + // /page/website.snippets + }, + setup_droppable: function () { + var self = this; + $('.oe_snippet_drop').remove(); + var droppable = '<div class="oe_snippet_drop"></div>'; + var $zone = $(':not(.oe_snippet) > .container'); + $zone.after(droppable);//.after(droppable); + + $(".oe_snippet_drop").droppable({ + hoverClass: 'oe_accepting', + drop: function( event, ui ) { + console.log(event, ui, "DROP"); + + $(event.target).replaceWith($(ui.draggable).html()); + $('.oe_selected').remove(); + $('.oe_snippet_drop').remove(); } - selected_snippet.removeClass('oe_selected'); - selected_snippet = null; - make_static(); + }); + }, + toggle: function(){ + if(this.$el.hasClass('oe_hidden')){ + this.$el.removeClass('oe_hidden'); + }else{ + this.$el.addClass('oe_hidden'); } - }else if(event.button === 1){ - $(this).remove(); - } - event.preventDefault(); - } -}); + }, + snippet_start: function () { + var self = this; + $('.oe_snippet').draggable().click(function(ev) { + self.setup_droppable(); + $(".oe_snippet_drop").show(); + $('.oe_selected').removeClass('oe_selected'); + $(ev.currentTarget).addClass('oe_selected'); + }); -$(function () { - $(document).on('click', '.js_publish, .js_unpublish', function (e) { - e.preventDefault(); - var $link = $(this).parent(); - $link.find('.js_publish, .js_unpublish').addClass("hidden"); - var $unp = $link.find(".js_unpublish"); - var $p = $link.find(".js_publish"); - $.post('/website/publish', {'id': $link.data('id'), 'object': $link.data('object')}, function (result) { - if (+result) { - $p.addClass("hidden"); - $unp.removeClass("hidden"); - } else { - $p.removeClass("hidden"); - $unp.addClass("hidden"); - } - }); + }, }); + }); -}; diff --git a/addons/website/static/src/js/website_bootstrap.js b/addons/website/static/src/js/website_bootstrap.js deleted file mode 100644 index d08f6270fc9..00000000000 --- a/addons/website/static/src/js/website_bootstrap.js +++ /dev/null @@ -1,19 +0,0 @@ -$(function() { - // Init headless webclient - // TODO: Webclient research : use iframe embedding mode - // Meanwhile, let's HACK !!! - var s = new openerp.init(['web', 'website']); - s.web.WebClient.bind_hashchange = s.web.WebClient.show_common = s.web.blockUI = s.web.unblockUI = function() {}; - s.web.WebClient.include({ do_push_state: function() {} }); - var wc = new s.web.WebClient(); - wc.start(); - var instance = openerp.instances[wc.session.name]; - // Another hack since we have no callback when webclient has loaded modules. - instance.web.qweb.add_template('/website/static/src/xml/website.xml'); - - $(function() { - var editor = new instance.website.EditorBar(instance.webclient); - editor.prependTo($('body')); - $('body').css('padding-top', '50px'); // Not working properly: editor.$el.outerHeight()); - }); -}); diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index db0cd25eec6..7d75ecde6ba 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -20,10 +20,13 @@ <template id="layout"> <!DOCTYPE html> - <html t-att-data-view-xmlid="__stack__[0]"> + <html t-att-data-view-xmlid="__stack__[0]" t-att-data-editable="'1' if editable else '0'"> <head> <title><t t-esc="title or res_company.name"/></title> + <script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script> + <script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script> <script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script> + <script type="text/javascript" src="/website/static/lib/bootstrap/js/bootstrap.js"></script> <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.2/ckeditor.js"></script> <script type="text/javascript" src="/website/static/lib/ckeditor.sharedspace/plugin.js"></script> <script type="text/javascript"> @@ -33,11 +36,15 @@ </script> <t t-if="editable"> - <t t-raw="css"/> - <t t-raw="script"/> <link rel='stylesheet' href='/website/static/src/css/snippets.css'/> - <script type="text/javascript" src="/website/static/src/js/website_bootstrap.js"></script> + <link rel='stylesheet' href='/website/static/src/css/editor.css'/> + + <script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script> + <script type="text/javascript" src="/web/static/lib/qweb/qweb2.js"></script> + <script type="text/javascript" src="/web/static/src/js/openerpframework.js"></script> </t> + + <script type="text/javascript" src="/website/static/src/js/website.js"></script> <t t-raw="head or ''"/> <t t-call="website.theme"/> @@ -280,6 +287,36 @@ </t> </template> + <template id="500"> + <t t-call="website.layout"> + <div class="container"> + <h1 class="mt32">500: Internal Server Error!</h1> + <pre t-esc="traceback"/> + </div> + </t> + </template> + + <template id="401"> + <t t-call="website.layout"> + <div class="container"> + <h1 class="mt32">401: Unauthorized Access!</h1> + <p> + The page you were looking for could not be + authorized. + </p><p> + Maybe you were looking for one of these + popular pages ? + </p> + <pre class="hidden" t-esc="error"/> + <ul> + <li><a href="/">Homepage</a></li> + <li><a href="/">Contact Us</a></li> + </ul> + </div> + </t> + </template> + + <template id="contactus" name="Contact us"> <t t-call="website.layout"> <t t-set="title">Contact us - <t t-raw="res_company.name"/></t> diff --git a/addons/website/website.py b/addons/website/website.py index a3208f96470..461ad67f86a 100644 --- a/addons/website/website.py +++ b/addons/website/website.py @@ -2,12 +2,16 @@ import simplejson import openerp -from openerp.osv import osv +from openerp.osv import osv, orm from openerp.addons.web import http from openerp.addons.web.controllers import main from openerp.addons.web.http import request import urllib import math +import traceback + +import logging +logger = logging.getLogger(__name__) def auth_method_public(): @@ -42,11 +46,16 @@ class website(osv.osv): def get_rendering_context(self, additional_values=None): debug = 'debug' in request.params + is_logged = True + try: + request.session.check_security() + except: # TODO fme: check correct exception + is_logged = False is_public_user = request.uid == self.get_public_user().id values = { 'debug': debug, 'is_public_user': is_public_user, - 'editable': not is_public_user, + 'editable': is_logged and not is_public_user, 'request': request, 'registry': request.registry, 'cr': request.cr, @@ -55,11 +64,6 @@ class website(osv.osv): 'res_company': request.registry['res.company'].browse(request.cr, openerp.SUPERUSER_ID, 1), 'json': simplejson, } - if values['editable']: - values.update({ - 'script': "\n".join(['<script type="text/javascript" src="%s"></script>' % i for i in main.manifest_list('js', db=request.db, debug=debug)]), - 'css': "\n".join('<link rel="stylesheet" href="%s">' % i for i in main.manifest_list('css', db=request.db, debug=debug)) - }) if additional_values: values.update(additional_values) return values @@ -68,7 +72,22 @@ class website(osv.osv): context = { 'inherit_branding': values.get('editable', False), } - return request.registry.get("ir.ui.view").render(request.cr, request.uid, template, values, context=context) + try: + return request.registry.get("ir.ui.view").render(request.cr, request.uid, template, values, context=context) + except (osv.except_osv, orm.except_orm), err: + logger.error(err) + values['error'] = err[1] + return self.render('website.401', values) + except ValueError: + logger.error("Website Rendering Error.\n\n%s" % (traceback.format_exc())) + return self.render('website.404', values) + except Exception: + logger.error("Website Rendering Error.\n\n%s" % (traceback.format_exc())) + if values['editable']: + values['traceback'] = traceback.format_exc() + return self.render('website.500', values) + else: + return self.render('website.404', values) def pager(self, url, total, page=1, step=30, scope=5, url_args=None): # Compute Pager |
