Merge pull request #10092 from kennethsequeira/blog-seo
feat: add suggestive Google Search Preview option in blog
This commit is contained in:
commit
1032becf3d
5 changed files with 80 additions and 9 deletions
|
|
@ -201,7 +201,7 @@ class TestPermissions(unittest.TestCase):
|
|||
doc = frappe.get_doc("DocType", "Blog Post")
|
||||
|
||||
# change one property from the child table
|
||||
doc.fields[-1].fieldtype = 'HTML'
|
||||
doc.fields[-1].fieldtype = 'Check'
|
||||
self.assertRaises(frappe.CannotChangeConstantError, doc.save)
|
||||
frappe.clear_cache(doctype='DocType')
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,40 @@
|
|||
|
||||
frappe.ui.form.on('Blog Post', {
|
||||
refresh: function(frm) {
|
||||
|
||||
generate_google_search_preview(frm);
|
||||
},
|
||||
title: function(frm) {
|
||||
generate_google_search_preview(frm);
|
||||
},
|
||||
meta_description: function(frm) {
|
||||
generate_google_search_preview(frm);
|
||||
},
|
||||
blog_intro: function(frm) {
|
||||
generate_google_search_preview(frm);
|
||||
}
|
||||
});
|
||||
|
||||
function generate_google_search_preview(frm) {
|
||||
let google_preview = frm.get_field("google_preview");
|
||||
let seo_title = (frm.doc.title).slice(0, 60);
|
||||
let seo_description = (frm.doc.meta_description || frm.doc.blog_intro || "").slice(0, 160);
|
||||
let date = frm.doc.published_on ? new frappe.datetime.datetime(frm.doc.published_on).moment.format('ll') + ' - ' : '';
|
||||
let route_array = frm.doc.route.split('/');
|
||||
route_array.pop();
|
||||
|
||||
google_preview.html(`
|
||||
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400&display=swap" rel="stylesheet">
|
||||
<div style="font-family: Open Sans; padding: 15px; border: 1px solid #d1d8dd !important; border-radius: 6px;">
|
||||
<cite style="font-size: 14px; padding-top: 1px; line-height: 1.3; color: #202124; font-style: normal;">
|
||||
${frappe.boot.sitename}
|
||||
<span style="color: #5f6368;"> › ${route_array.join(' › ')}</span>
|
||||
</cite>
|
||||
<div style="font-size: 20px; line-height: 1.3; color: #1a0dab; padding-top: 4px; margin-bottom: 3px;">
|
||||
${ seo_title }
|
||||
</div>
|
||||
<p style="color: #545454; max-width: 48em; line-height: 1.58; font-size:14px;">
|
||||
<span style="color: #70757a;">${ date }</span> ${ seo_description }
|
||||
</p>
|
||||
</div>
|
||||
`);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,13 @@
|
|||
"content",
|
||||
"content_md",
|
||||
"content_html",
|
||||
"email_sent"
|
||||
"email_sent",
|
||||
"meta_tags",
|
||||
"meta_description",
|
||||
"column_break_18",
|
||||
"meta_image",
|
||||
"section_break_20",
|
||||
"google_preview"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
|
|
@ -123,6 +129,36 @@
|
|||
"fieldname": "disable_comments",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable Comments"
|
||||
},
|
||||
{
|
||||
"fieldname": "meta_description",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Meta Description"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_18",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "meta_image",
|
||||
"fieldtype": "Attach Image",
|
||||
"label": "Meta Image"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_20",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"description": "This is an example Google SERP Preview.",
|
||||
"fieldname": "google_preview",
|
||||
"fieldtype": "HTML",
|
||||
"label": "Google Snippet Preview",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "meta_tags",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Meta Tags"
|
||||
}
|
||||
],
|
||||
"has_web_view": 1,
|
||||
|
|
@ -131,7 +167,7 @@
|
|||
"is_published_field": "published",
|
||||
"links": [],
|
||||
"max_attachments": 5,
|
||||
"modified": "2020-04-08 19:58:13.672332",
|
||||
"modified": "2020-04-29 17:32:41.055883",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Website",
|
||||
"name": "Blog Post",
|
||||
|
|
|
|||
|
|
@ -65,16 +65,18 @@ class BlogPost(WebsiteGenerator):
|
|||
|
||||
|
||||
context.content = get_html_content_based_on_type(self, 'content', self.content_type)
|
||||
context.description = self.blog_intro or strip_html_tags(context.content[:140])
|
||||
|
||||
#if meta description is not present, then blog intro or first 140 characters of the blog will be set as description
|
||||
context.description = self.meta_description or self.blog_intro or strip_html_tags(context.content[:140])
|
||||
|
||||
context.metatags = {
|
||||
"name": self.title,
|
||||
"description": context.description,
|
||||
}
|
||||
|
||||
#if meta image is not present, then first image inside the blog will be set as the meta image
|
||||
image = find_first_image(context.content)
|
||||
if image:
|
||||
context.metatags["image"] = image
|
||||
context.metatags["image"] = self.meta_image or image or None
|
||||
|
||||
self.load_comments(context)
|
||||
|
||||
|
|
@ -95,7 +97,6 @@ class BlogPost(WebsiteGenerator):
|
|||
else:
|
||||
context.comment_text = _('{0} comments').format(len(context.comment_list))
|
||||
|
||||
|
||||
def get_list_context(context=None):
|
||||
list_context = frappe._dict(
|
||||
template = "templates/includes/blog/blog.html",
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<p class="lead">
|
||||
{{ description }}
|
||||
{{ blog_intro }}
|
||||
</p>
|
||||
<div itemprop="articleBody" class="longform blog-text mt-5">
|
||||
{{ content }}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue