Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add search engine result preview on product page #9444

Merged
merged 9 commits into from Sep 7, 2018
Merged
86 changes: 86 additions & 0 deletions admin-dev/themes/new-theme/js/app/utils/serp/index.js
@@ -0,0 +1,86 @@
/**
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
import Vue from 'vue';
import serp from './serp';
const $ = window.$;

/**
* Vue component displaying a search page result, Google style.
* Requires a tag with the id "#serp-app" to be present in the DOM to run it.
* The component is automatically updated by watching several inputs.
* Set the proper class to link a input to a part of the panel.
*/
class SerpApp {
constructor() {
// If the selector cannot be found, we do not load the Vue app
if (0 === $('#serp-app').length) {
return;
}

this.defaultTitle = $('.serp-default-title:input');
this.watchedTitle = $('.serp-watched-title:input');
this.defaultDescription = $('.serp-default-description');
this.watchedDescription = $('.serp-watched-description');
this.defaultUrl = $('.serp-default-url:input');

this.vm = new Vue({
el: '#serp-app',
template: '<serp ref="serp" />',
components: { serp },
});

this.attachEvents(this.vm.$refs.serp);
}

attachEvents(app) {
// Specific rules for updating the search result preview
const updateSerpTitle = () => {
const title1 = this.watchedTitle.length ? this.watchedTitle.val() : '';
const title2 = this.defaultTitle.length ? this.defaultTitle.val() : '';
app.setTitle(title1 || title2);
};
const updateSerpUrl = () => {
if (this.defaultUrl.length) {
app.setUrl(this.defaultUrl.val());
}
};
const updateSerpDescription = () => {
const desc1 = this.watchedDescription.length ? $(this.watchedDescription.val()).text() || this.watchedDescription.val() : '';
const desc2 = this.defaultDescription.length ? $(this.defaultDescription.val()).text() || this.defaultDescription.val() : '';
app.setDescription(desc1 || desc2);
};
this.watchedTitle.on('keyup change', updateSerpTitle);
this.defaultTitle.on('keyup change', updateSerpTitle);

this.watchedDescription.on('keyup change', updateSerpDescription);
this.defaultDescription.on('keyup change', updateSerpDescription);

updateSerpTitle();
updateSerpUrl();
updateSerpDescription();
}
}

export default SerpApp;
148 changes: 148 additions & 0 deletions admin-dev/themes/new-theme/js/app/utils/serp/serp.vue
@@ -0,0 +1,148 @@

<!--**
* 2007-2018 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/OSL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2018 PrestaShop SA
* @license https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*-->
<template>
<div id="serp"">
<div class="serp-preview">
<div class="serp-title">{{title}}</div>
<div class="serp-url">{{url}}<span class="serp-arrow"></span></div>
<div class="serp-description">{{description}}</div>
</div>
</div>
</template>

<script>
export default {
name: 'serp',
props: {
title: {
type: String,
default: '',
},
url: {
type: String,
default: 'http://example.com/',
},
description: {
type: String,
default: '',
},
},
methods: {
setTitle(title) {
if(title.length > 70) {
title = title.substring(0, 70) + ' ...';
}
this.title = title;
},
setUrl(url) {
this.url = url;
},
setDescription(description) {
if(description.length > 150) {
description = description.substring(0, 150) + ' ...';
}
this.description = description;
}
}
};
</script>

<style lang="sass" type="text/scss" scoped>
.serp-preview {
margin-top: 15px;
margin-bottom: 15px;
border-radius: 2px;
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.12);
background-color: #ffffff;
border: solid 1px #e7e7e7;
padding: 30px;
max-width: 700px;

.serp-arrow {
border-bottom-color: rgb(0, 102, 33);
border-bottom-style: solid;
border-bottom-width: 0px;
border-left-color: rgba(0, 0, 0, 0);
border-left-style: solid;
border-left-width: 4px;
border-right-color: rgba(0, 0, 0, 0);
border-right-style: solid;
border-right-width: 4px;
border-top-color: rgb(0, 102, 33);
border-top-style: solid;
border-top-width: 5px;
color: rgb(128, 128, 128);
cursor: default;
font-family: arial, sans-serif;
font-size: 11px;
font-weight: bold;
height: 0px;
position: absolute;
line-height: 27px;
margin-left: 3px;
margin-top: 6px;
text-align: center;
user-select: none;
visibility: visible;
white-space: nowrap;
width: 0px;
}

.serp-title {
color: #1A0DAB;
cursor: pointer;
font-family: arial, regular;
font-size: 18px;
font-weight: normal;
text-align: left;
text-decoration: none;
visibility: visible;
white-space: nowrap;
}

.serp-url {
color: #006621;
font-family: arial, regular;
font-size: 14px;
font-style: normal;
font-weight: normal;
line-height: 24px;
text-align: left;
visibility: visible;
white-space: nowrap;
}

.serp-description {
color: #545454;
font-family: arial, regular;
font-size: 13px;
font-weight: normal;
text-align: left;
visibility: visible;
word-wrap: break-word;
}
}
</style>
4 changes: 4 additions & 0 deletions admin-dev/themes/new-theme/js/product-page/index.js
Expand Up @@ -29,6 +29,7 @@ import attributes from './attributes';
import bulkCombination from './product-bulk-combinations';
import nestedCategory from './nested-categories';
import combination from './combination';
import Serp from '../app/utils/serp/index';

$(() => {
productHeader();
Expand All @@ -39,6 +40,9 @@ $(() => {
bulkCombination().init();
nestedCategory().init();

const serpComp = new Serp();
serpComp.vm.$refs.serp.setUrl($('#product_form_preview_btn').data('redirect'));

// This is the only script for the module page so there is no specific file for it.
$('.modules-list-select').on("change", (e) => {
$('.module-render-container').hide();
Expand Down
2 changes: 1 addition & 1 deletion admin-dev/themes/new-theme/public/backup.bundle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.