Commit 3fd837c82fc36a1c9d67b643bc967fcc8172d5c5
Add support for menu order in default menu
- Now with default menu, can specify the order of pages.
- Fix custom menu not getting saved.
- Fix irrelevant types in content editor.
| | | | 17 | siteContent = db['content'] | 17 | siteContent = db['content'] |
---|
18 | siteMenu = db['menu'] | 18 | siteMenu = db['menu'] |
---|
19 | if siteMenu.find_one() == None: | 19 | if siteMenu.find_one() == None: |
---|
20 | siteMenu.insert({'customMenu': False}) | | siteMenu.insert({'customMenu': False}) |
---|
| | 20 | siteMenu.insert({'customMenu': False, 'menuOrder': []}) | 21 | | 21 | |
---|
| | 22 | |
---|
22 | # handy reference to otherwise long name | 23 | # handy reference to otherwise long name |
---|
23 | bson.ObjId = bson.objectid.ObjectId | 24 | bson.ObjId = bson.objectid.ObjectId |
---|
24 | | 25 | |
---|
… | | … | |
---|
50 | @app.route('/edit', methods=['GET']) | 50 | @app.route('/edit', methods=['GET']) |
---|
51 | def edit(): | 51 | def edit(): |
---|
52 | return flask.render_template('editor.html', content=getContent(), | 52 | return flask.render_template('editor.html', content=getContent(), |
---|
53 | title=conf) | | title=conf) |
---|
| | 53 | title=conf.SITE_TITLE) | 54 | | 54 | |
---|
55 | | 55 | |
---|
56 | @app.route('/page', methods=['POST']) | 56 | @app.route('/page', methods=['POST']) |
---|
… | | … | |
---|
115 | # print _id | 115 | # print _id |
---|
116 | # res = siteMenu.remove({'_id': bson.ObjId(_id)}) | 116 | # res = siteMenu.remove({'_id': bson.ObjId(_id)}) |
---|
117 | # return flask.jsonify(status='deleted') | 117 | # return flask.jsonify(status='deleted') |
---|
| | 118 | |
---|
118 | | 119 | |
---|
119 | | 120 | |
---|
120 | if __name__ == "__main__": | 121 | if __name__ == "__main__": |
---|
| | | | 9 | 'click .pagename .disp': 'showPage', | 9 | 'click .pagename .disp': 'showPage', |
---|
10 | 'click #addPage': 'addPage', | 10 | 'click #addPage': 'addPage', |
---|
11 | 'click .pagename .remove': 'removePage', | 11 | 'click .pagename .remove': 'removePage', |
---|
12 | 'click #menu-config': 'showMenu'//, | | 'click #menu-config': 'showMenu'//, |
---|
13 | //'click #footer-config': 'footerConfig' | | //'click #footer-config': 'footerConfig' |
---|
| | 12 | 'click #menu-config': 'showMenu', | 14 | }, | 13 | }, |
---|
15 | initialize: function() { | 14 | initialize: function() { |
---|
16 | _.bindAll(this); | 15 | _.bindAll(this); |
---|
… | | … | |
---|
24 | //console.log(menu); | 24 | //console.log(menu); |
---|
25 | this.menuconfig = new M.types.model.menu(menu); | 25 | this.menuconfig = new M.types.model.menu(menu); |
---|
26 | this.menuconfigview = new MenuConfigView({model: this.menuconfig}); | 26 | this.menuconfigview = new MenuConfigView({model: this.menuconfig}); |
---|
27 | //this.footerconfigview = new FooterConfigView(); | | //this.footerconfigview = new FooterConfigView(); |
---|
28 | }, | 27 | }, |
---|
29 | render: function() { | 28 | render: function() { |
---|
30 | // append the page list | 29 | // append the page list |
---|
… | | … | |
---|
67 | }, | 67 | }, |
---|
68 | showMenu: function(event) { | 68 | showMenu: function(event) { |
---|
69 | this.menuconfigview.render(); | 69 | this.menuconfigview.render(); |
---|
70 | }, | | }, |
---|
71 | footerConfig: function(event) { | | footerConfig: function(event) { |
---|
72 | //this.footerconfigview.render(); | | //this.footerconfigview.render(); |
---|
73 | } | 70 | } |
---|
74 | }); | 71 | }); |
---|
75 | | 72 | |
---|
… | | … | |
---|
238 | }, | 238 | }, |
---|
239 | render: function() { | 239 | render: function() { |
---|
240 | this.$el.html(''); | 240 | this.$el.html(''); |
---|
241 | console.log(this.model); | | console.log(this.model); |
---|
242 | var type = this.model.get('type'); | 241 | var type = this.model.get('type'); |
---|
243 | this.$el.append(this.template({ | 242 | this.$el.append(this.template({ |
---|
244 | type: this.model.get('type'), | 243 | type: this.model.get('type'), |
---|
… | | … | |
---|
246 | })); | 246 | })); |
---|
247 | | 247 | |
---|
248 | this.$select = $('.contentview select'); | 248 | this.$select = $('.contentview select'); |
---|
249 | //this.$select.bind('change', this.typeChanged); | | //this.$select.bind('change', this.typeChanged); |
---|
250 | this.$select.val(type); | 249 | this.$select.val(type); |
---|
251 | | 250 | |
---|
252 | if(type === 'text') { | 251 | if(type === 'text') { |
---|
… | | … | |
---|
258 | } | 258 | } |
---|
259 | else if(type === 'image' || type === 'video' || | 259 | else if(type === 'image' || type === 'video' || |
---|
260 | type === 'audio' || type === 'plugin') { | 260 | type === 'audio' || type === 'plugin') { |
---|
261 | var template = _.template($('#media-template').html()); | | var template = _.template($('#media-template').html()); |
---|
262 | | 261 | |
---|
| | 262 | var template = _.template($('#media-template').html()); |
---|
263 | $('#specific-content').html(template({ | 263 | $('#specific-content').html(template({ |
---|
264 | src: this.model.get('src') | 264 | src: this.model.get('src') |
---|
265 | })); | 265 | })); |
---|
266 | | 266 | |
---|
267 | //provide the users a preview | | //provide the users a preview |
---|
| | 267 | //TODO: provide the users a preview | 268 | /*var view = new M.types.view[type]({model: this.model}); | 268 | /*var view = new M.types.view[type]({model: this.model}); |
---|
269 | //$('#specific-content.preview').html(); | 269 | //$('#specific-content.preview').html(); |
---|
270 | view.render('.preview');*/ | 270 | view.render('.preview');*/ |
---|
… | | … | |
---|
309 | } | 309 | } |
---|
310 | }); | 310 | }); |
---|
311 | | 311 | |
---|
312 | /* view to configure footer */ | | /* view to configure footer */ |
---|
313 | var FooterConfigView = Backbone.View.extend({ | | var FooterConfigView = Backbone.View.extend({ |
---|
314 | tagName: 'div', | | tagName: 'div', |
---|
315 | id: 'page', | | id: 'page', |
---|
316 | events: { | | events: { |
---|
317 | 'click #saveFooter': 'saveFooter' | | 'click #saveFooter': 'saveFooter' |
---|
318 | }, | | }, |
---|
319 | initialize: function() { | | initialize: function() { |
---|
320 | _.bindAll(this); | | _.bindAll(this); |
---|
321 | this.template = _.template($('#footer-config-template').html()); | | this.template = _.template($('#footer-config-template').html()); |
---|
322 | }, | | }, |
---|
323 | render: function() { | | render: function() { |
---|
324 | $('#page').remove(); | | $('#page').remove(); |
---|
325 | $('#content-container').append(this.$el); | | $('#content-container').append(this.$el); |
---|
326 | this.$el.html(this.template()); | | this.$el.html(this.template()); |
---|
327 | M.editor.wysiwig('#footer-input'); | | M.editor.wysiwig('#footer-input'); |
---|
328 | }, | | }, |
---|
329 | saveFooter: function() { | | saveFooter: function() { |
---|
330 | tinymce.triggerSave(false, true); | | tinymce.triggerSave(false, true); |
---|
331 | var data = $('#footer-input').html(); | | var data = $('#footer-input').html(); |
---|
332 | console.log(data); | | console.log(data); |
---|
333 | } | | } |
---|
334 | }); | | }); |
---|
335 | | | |
---|
336 | /* view to configure custom navigation menu */ | 312 | /* view to configure custom navigation menu */ |
---|
337 | var MenuConfigView = Backbone.View.extend({ | 313 | var MenuConfigView = Backbone.View.extend({ |
---|
338 | tagName: 'div', | 314 | tagName: 'div', |
---|
… | | … | |
---|
326 | $('#content-container').append(this.$el); | 326 | $('#content-container').append(this.$el); |
---|
327 | console.log('rendering..', this.$el); | 327 | console.log('rendering..', this.$el); |
---|
328 | this.$el.html(this.template({ | 328 | this.$el.html(this.template({ |
---|
| | 329 | menu_order: this.model.get('menuOrder'), |
---|
329 | pos: this.model.get('pos'), | 330 | pos: this.model.get('pos'), |
---|
330 | menu: this.model.get('html') | 331 | menu: this.model.get('html') |
---|
331 | })); | 332 | })); |
---|
332 | this.$menuOptions = $('.menu-options'); | 333 | this.$menuOptions = $('.menu-options'); |
---|
| | 334 | this.$menuOrder = $('#menu-order-wrap'); |
---|
333 | | 335 | |
---|
334 | if(this.model.get('customMenu') === true) { | 336 | if(this.model.get('customMenu') === true) { |
---|
335 | $('#custom-menu').attr('checked', true); | 337 | $('#custom-menu').attr('checked', true); |
---|
336 | this.$menuOptions.show({complete: function() { | 338 | this.$menuOptions.show({complete: function() { |
---|
337 | M.editor.wysiwig('#menu'); | | M.editor.wysiwig('#menu'); |
---|
| | 339 | //M.editor.wysiwig('#menu'); | 338 | }}); | 340 | }}); |
---|
339 | } | 341 | } |
---|
340 | }, | 342 | }, |
---|
341 | showMenuOptions: function(bool) { | 343 | showMenuOptions: function(bool) { |
---|
342 | if(bool === true) { | 344 | if(bool === true) { |
---|
| | 345 | this.$menuOrder.hide(); |
---|
343 | this.$menuOptions.show({complete: function() { | 346 | this.$menuOptions.show({complete: function() { |
---|
344 | //M.editor.wysiwig('#menu'); | 347 | //M.editor.wysiwig('#menu'); |
---|
345 | }}); | 348 | }}); |
---|
346 | } | 349 | } |
---|
347 | else { | 350 | else { |
---|
| | 351 | this.$menuOrder.show(); |
---|
348 | this.$menuOptions.hide(); | 352 | this.$menuOptions.hide(); |
---|
349 | } | 353 | } |
---|
350 | }, | 354 | }, |
---|
… | | … | |
---|
364 | }, | 364 | }, |
---|
365 | saveMenu: function() { | 365 | saveMenu: function() { |
---|
366 | console.log('saving menu..'); | 366 | console.log('saving menu..'); |
---|
367 | // var menuHTML = $('#menu').val().trim(); | | // var menuHTML = $('#menu').val().trim(); |
---|
368 | //this.model.set({'html': menuHTML}); | | //this.model.set({'html': menuHTML}); |
---|
369 | //console.log(this.model.toJSON()); | | //console.log(this.model.toJSON()); |
---|
370 | //alert('saveMenu called'); | | //alert('saveMenu called'); |
---|
371 | var bool; | | var bool; |
---|
372 | if($("custom-menu").is(":checked")) { | | if($("custom-menu").is(":checked")) { |
---|
| | 367 | var bool, html = '', menuOrder = []; | | | 368 | if($('#custom-menu').is(":checked")) { |
---|
373 | bool = true; | 369 | bool = true; |
---|
| | 370 | html = $('#menu').val().trim(); |
---|
374 | } | 371 | } |
---|
375 | else { | 372 | else { |
---|
376 | bool = false; | 373 | bool = false; |
---|
| | 374 | menuOrder = $('#menu-order').val().split(','); |
---|
377 | } | 375 | } |
---|
378 | this.model.save({customMenu: bool}, { | | this.model.save({customMenu: bool}, { |
---|
| | 376 | this.model.set({'customMenu': bool, 'html': html, 'menuOrder': menuOrder}); | | | 377 | console.log(this.model.toJSON()); |
---|
| | 378 | this.model.save({}, { |
---|
379 | success: function(model, response) { | 379 | success: function(model, response) { |
---|
380 | console.log(model, response); | 380 | console.log(model, response); |
---|
381 | }, | 381 | }, |
---|
| | | | 137 | 'Pages': Pages | 137 | 'Pages': Pages |
---|
138 | }; | 138 | }; |
---|
139 | | 139 | |
---|
| | 140 | //content types to render in content menu |
---|
| | 141 | M.contentTypes = ['text', 'image', 'video', 'table', 'plugin']; |
---|
| | 142 | |
---|
140 | })(M); | 143 | })(M); |
---|
| | | | 64 | }, | 64 | }, |
---|
65 | populate: function() { | 65 | populate: function() { |
---|
66 | var item_template = _.template($('#nav-item-template').html()); | 66 | var item_template = _.template($('#nav-item-template').html()); |
---|
67 | _.each(M.pages.models, function(page) { | | _.each(M.pages.models, function(page) { |
---|
68 | //console.log('no children?', _.isEmpty(page.get('children'))); | | //console.log('no children?', _.isEmpty(page.get('children'))); |
---|
| | 67 | _.each(this.model.get('menuOrder'), function(page) { | 69 | this.$ul.append(item_template({ | 68 | this.$ul.append(item_template({ |
---|
| | 69 | cls: '', |
---|
| | 70 | page: page |
---|
| | 71 | })); |
---|
| | 72 | //console.log('no children?', _.isEmpty(page.get('children'))); |
---|
| | 73 | /*this.$ul.append(item_template({ |
---|
70 | cls: (_.isEmpty(page.get('children'))) ? '' : 'dropdown', | 74 | cls: (_.isEmpty(page.get('children'))) ? '' : 'dropdown', |
---|
71 | page: page.get('name') | 75 | page: page.get('name') |
---|
72 | })); | | })); |
---|
| | 76 | }));*/ | 73 | }, this); | 77 | }, this); |
---|
74 | }, | 78 | }, |
---|
75 | navClicked: function(event) { | 79 | navClicked: function(event) { |
---|
76 | this.$links.removeClass('active'); | 80 | this.$links.removeClass('active'); |
---|
77 | if(!event) { | 81 | if(!event) { |
---|
78 | var fragment = location.hash.split('/')[1]; | 82 | var fragment = location.hash.split('/')[1]; |
---|
79 | var pos = _.indexOf(M.pages.models, M.pages.where({'name': fragment})[0]); | | var pos = _.indexOf(M.pages.models, M.pages.where({'name': fragment})[0]); |
---|
| | 83 | //var pos = _.indexOf(M.pages.models, M.pages.where({'name': fragment})[0]); | | | 84 | var pos = _.indexOf(this.model.get('menuOrder'), fragment); |
---|
80 | if(!fragment) { | 85 | if(!fragment) { |
---|
81 | pos = 0; | 86 | pos = 0; |
---|
82 | } | 87 | } |
---|
| | | | 54 | <div class="page"> | 54 | <div class="page"> |
---|
55 | <div class="menu-config"> | 55 | <div class="menu-config"> |
---|
56 | <h4> Menu Config </h4> | 56 | <h4> Menu Config </h4> |
---|
57 | <!-- <form class="form-horizontal"> --> | | <!-- <form class="form-horizontal"> --> |
---|
| | 57 | <div class="control-group"> | | | 58 | <input id="custom-menu" type="checkbox"> |
---|
| | 59 | <span class=""><strong> Custom Menu </strong></span> |
---|
| | 60 | </div> |
---|
| | 61 | <div class="control-group" id="menu-order-wrap"> |
---|
| | 62 | <% if(!$('#custom-menu').is(':checked')) { %> |
---|
| | 63 | <div class="input-prepend"> |
---|
| | 64 | <span class="add-on"> <strong> Menu Order</strong></span> |
---|
| | 65 | <input id="menu-order" type="text" |
---|
| | 66 | placeholder="list,page,names,for,menu,order" value="<%= menu_order %>"> |
---|
| | 67 | </div> |
---|
| | 68 | <% } %> |
---|
| | 69 | </div> |
---|
| | 70 | <div class="menu-options" style="display: none;"> |
---|
58 | <div class="control-group"> | 71 | <div class="control-group"> |
---|
59 | <input id="custom-menu" type="checkbox"> | | <input id="custom-menu" type="checkbox"> |
---|
60 | <span class=""><strong> Custom Menu </strong></span> | | <span class=""><strong> Custom Menu </strong></span> |
---|
61 | </div> | | </div> |
---|
62 | <button id="updateMenu" class="btn btn-primary pull-right"> Update </button> | | <button id="updateMenu" class="btn btn-primary pull-right"> Update </button> |
---|
63 | <div class="clearfix"></div> | | <div class="clearfix"></div> |
---|
64 | <div class="menu-options" style="display: none;"> | | <div class="menu-options" style="display: none;"> |
---|
65 | <div class="control-group"> | | <div class="control-group"> |
---|
66 | <div class="input-prepend"> | | <div class="input-prepend"> |
---|
67 | <span class="add-on"> <strong> Position </strong></span> | | <span class="add-on"> <strong> Position </strong></span> |
---|
68 | <input id="pos" type="text" placeholder="[left, top]" | | <input id="pos" type="text" placeholder="[left, top]" |
---|
69 | value="<%= pos %>"> | | value="<%= pos %>"> |
---|
70 | </div> | | </div> |
---|
| | 72 | <div class="input-prepend"> | | | 73 | <span class="add-on"> <strong> Position </strong></span> |
---|
| | 74 | <input id="pos" type="text" placeholder="[left, top]" |
---|
| | 75 | value="<%= pos %>"> |
---|
71 | </div> | 76 | </div> |
---|
72 | <label><strong> HTML </strong></label> | | <label><strong> HTML </strong></label> |
---|
73 | <div id="menu"> | | <div id="menu"> |
---|
74 | <%= menu %> | | <%= menu %> |
---|
75 | </div> | | </div> |
---|
76 | </div> | 77 | </div> |
---|
77 | <!-- </form> --> | | <!-- </form> --> |
---|
| | 78 | <label><strong> HTML for menu: </strong></label> | | | 79 | <textarea cols="25" rows="8" id="menu"><%= menu %></textarea> |
---|
| | 80 | </div> |
---|
78 | </div> | 81 | </div> |
---|
| | 82 | <button id="updateMenu" class="btn btn-primary pull-right"> Update </button> |
---|
| | 83 | <div class="clearfix"></div> |
---|
79 | </div> | 84 | </div> |
---|
80 | </script> | 85 | </script> |
---|
81 | | 86 | |
---|
… | | … | |
---|
169 | <div class=""> | 169 | <div class=""> |
---|
170 | <label><b>Type</b></label> | 170 | <label><b>Type</b></label> |
---|
171 | <select> | 171 | <select> |
---|
172 | <% _.each(_.keys(M.types.model), function(type) { %> | | <% _.each(_.keys(M.types.model), function(type) { %> |
---|
| | 172 | <% _.each(M.contentTypes, function(type) { %> | 173 | <option><%= type %></option> | 173 | <option><%= type %></option> |
---|
174 | <% }); %> | 174 | <% }); %> |
---|
175 | </select> | 175 | </select> |
---|