SEO: keyword suggest mockup

bzr revid: ddm@openerp.com-20130828135558-w4ysgixr6l7n45b5
This commit is contained in:
ddm 2013-08-28 15:55:58 +02:00
parent d5ec571b8d
commit 3c9f07d244
4 changed files with 82 additions and 18 deletions

View File

@ -289,6 +289,13 @@
} }
/* ---- SEO TOOLS ---- */ /* ---- SEO TOOLS ---- */
.oe_seo_configuration {
min-width: 42em;
}
.oe_seo_configuration .modal-body {
max-height: inherit;
min-height: 27em;
}
.oe_seo_configuration input { .oe_seo_configuration input {
width: 90%; width: 90%;
} }
@ -303,9 +310,10 @@
} }
.oe_seo_keywords_list { .oe_seo_keywords_list {
width: 80%; width: 100%;
margin: 0.1em;
} }
.oe_seo_keywords_list li { .oe_seo_keywords_list li {
float: left; float: left;
width: 15em; width: 19em;
} }

View File

@ -259,6 +259,10 @@ $icon_close: #E00101
$remove_color: $icon_close $remove_color: $icon_close
.oe_seo_configuration .oe_seo_configuration
min-width: 42em
.modal-body
max-height: inherit
min-height: 27em
input input
width: 90% width: 90%
textarea textarea
@ -269,7 +273,8 @@ $remove_color: $icon_close
color: $remove_color color: $remove_color
.oe_seo_keywords_list .oe_seo_keywords_list
width: 80% width: 100%
margin: 0.1em
li li
float: left float: left
width: 15em width: 19em

View File

@ -239,17 +239,54 @@
this.onDelete = options.onDelete; this.onDelete = options.onDelete;
}, },
destroy: function () { destroy: function () {
this.onDelete(this.keyword); if (_.isFunction(this.onDelete)) {
this.onDelete(this.keyword);
}
this._super(); this._super();
}, },
}); });
website.seo.cleanupKeyword = function (word) {
return word ? word.replace(/[,;.:]+/g, " ").replace(/ +/g, " ").trim() : "";
};
website.seo.PageParser = function () {
function currentURL () {
var url = window.location.href;
var hashIndex = url.indexOf('#');
return hashIndex >= 0 ? url.substring(0, hashIndex) : url;
}
var parsedPage = {
url: currentURL(),
title: $('title').text(),
headers: {},
content: {}
};
_.each([ 'h1', 'h2', 'h3'], function (header) {
parsedPage.headers[header] = [];
$(header).each(function () {
var text = $(this).text();
parsedPage.headers[header].push(text);
});
});
this.url = function () {
return parsedPage.url;
};
this.title = function () {
return parsedPage.title;
};
this.headers = function () {
return parsedPage.headers;
};
this.keywordSuggestions = function () {
return _.map(_.uniq(parsedPage.headers.h1.concat(parsedPage.headers.h2)), website.seo.cleanupKeyword);
};
};
website.seo.Configurator = openerp.Widget.extend({ website.seo.Configurator = openerp.Widget.extend({
template: 'website.seo_configuration', template: 'website.seo_configuration',
events: { events: {
'keypress input[name=seo_page_keywords]': 'confirmKeyword', 'keypress input[name=seo_page_keywords]': 'confirmKeyword',
'click button[data-action=add]': 'addKeyword', 'click button[data-action=add]': 'addKeyword',
'click a[data-action=update]': 'update', 'click a[data-action=update]': 'update',
'hidden': 'close' 'hidden': 'destroy'
}, },
maxTitleSize: 65, maxTitleSize: 65,
@ -258,9 +295,20 @@
maxWordsPerKeyword: 4, maxWordsPerKeyword: 4,
start: function () { start: function () {
var pageParser = new website.seo.PageParser();
var currentKeywords = this.keywords;
this.$el.find('.js_seo_page_url').text(pageParser.url());
this.$el.find('input[name=seo_page_title]').val(pageParser.title());
this.$el.find('input[name=seo_page_keywords]').typeahead({
source: function () {
var suggestions = pageParser.keywordSuggestions();
var alreadyChosen = currentKeywords();
return _.difference(suggestions, alreadyChosen);
},
items: 4
});
$('body').addClass('oe_stop_scrolling'); $('body').addClass('oe_stop_scrolling');
this.$el.find('.js_seo_page_url').text(this.currentPage());
this.$el.find('input[name=seo_page_title]').val($('title').text());
this.$el.modal(); this.$el.modal();
}, },
currentPage: function () { currentPage: function () {
@ -270,7 +318,7 @@
}, },
keywords: function () { keywords: function () {
return _.uniq(this.$el.find('.js_seo_keyword').map(function () { return _.uniq(this.$el.find('.js_seo_keyword').map(function () {
return $(this).text(); x return $(this).text();
}).get()); }).get());
}, },
isExistingKeyword: function (word) { isExistingKeyword: function (word) {
@ -300,28 +348,31 @@
$modal.find('button[data-action=add]') $modal.find('button[data-action=add]')
.prop('disabled', true).addClass('disabled'); .prop('disabled', true).addClass('disabled');
} }
var word = this.$el.find('input[name=seo_page_keywords]').val() var candidate = this.$el.find('input[name=seo_page_keywords]').val();
.replace(/[,;.:]+/gm, " ").replace(/ +/g, " ").trim(); var word = website.seo.cleanupKeyword(candidate);
if (word && !this.isKeywordListFull() && !this.isExistingKeyword(word)) { if (word && !this.isKeywordListFull() && !this.isExistingKeyword(word)) {
new website.seo.Keyword(this, { new website.seo.Keyword(this, {
keyword: word, keyword: word,
onDelete: enableNewKeywords onDelete: enableNewKeywords
}).appendTo(this.$el.find('.js_seo_keywords_list')); }).appendTo(this.$el.find('.js_seo_keywords_list'));
var $body = this.$el.find('.modal-body'); this.scrollDown();
$body.animate({
scrollTop: $body[0].scrollHeight
}, 500);
} }
if (this.isKeywordListFull()) { if (this.isKeywordListFull()) {
disableNewKeywords(); disableNewKeywords();
} }
}, },
scrollDown: function () {
var $body = this.$el.find('.modal-body');
$body.animate({
scrollTop: $body[0].scrollHeight
}, 500);
},
update: function () { update: function () {
// TODO: Persist changes // TODO: Persist changes
}, },
close: function () { destroy: function () {
$('body').removeClass('oe_stop_scrolling'); $('body').removeClass('oe_stop_scrolling');
this.destroy(); this._super();
}, },
}); });

View File

@ -79,7 +79,7 @@
<label class="control-label" for="seo_page_keywords">Keywords</label> <label class="control-label" for="seo_page_keywords">Keywords</label>
<div class="controls"> <div class="controls">
<div class="input-append"> <div class="input-append">
<input type="text" name="seo_page_keywords" maxlength="20" size="24" placeholder="New keyword"/> <input type="text" name="seo_page_keywords" data-provide="typeahead" autocomplete="off" maxlength="20" size="24" placeholder="New keyword"/>
<button data-action="add" class="btn" type="button">Add</button> <button data-action="add" class="btn" type="button">Add</button>
</div> </div>
<ul class="oe_seo_keywords_list js_seo_keywords_list"> <ul class="oe_seo_keywords_list js_seo_keywords_list">