Merge pull request #1454 from pateljannat/issues-93
feat: meta image and keywords from settings
This commit is contained in:
@@ -19,12 +19,23 @@ describe("Course Creation", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
cy.fixture("profile.png", "base64").then((fileContent) => {
|
cy.fixture("profile.png", "base64").then((fileContent) => {
|
||||||
cy.get('input[type="file"]').attachFile({
|
/* cy.get('input[type="file"]').should("be.hidden").attachFile({
|
||||||
fileContent,
|
fileContent,
|
||||||
fileName: "profile.png",
|
fileName: "profile.png",
|
||||||
mimeType: "image/png",
|
mimeType: "image/png",
|
||||||
encoding: "base64",
|
encoding: "base64",
|
||||||
});
|
}); */
|
||||||
|
|
||||||
|
cy.get("div")
|
||||||
|
.contains("Course Image")
|
||||||
|
.siblings("div")
|
||||||
|
.children('input[type="file"]')
|
||||||
|
.attachFile({
|
||||||
|
fileContent,
|
||||||
|
fileName: "profile.png",
|
||||||
|
mimeType: "image/png",
|
||||||
|
encoding: "base64",
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get("label")
|
cy.get("label")
|
||||||
|
|||||||
@@ -24,7 +24,10 @@
|
|||||||
>
|
>
|
||||||
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center mb-3 text-ink-gray-7">
|
<div
|
||||||
|
v-if="batch.data.courses.length"
|
||||||
|
class="flex items-center mb-3 text-ink-gray-7"
|
||||||
|
>
|
||||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2" />
|
<BookOpen class="h-4 w-4 stroke-1.5 mr-2" />
|
||||||
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -352,10 +352,23 @@ const tabsStructure = computed(() => {
|
|||||||
label: 'Meta Description',
|
label: 'Meta Description',
|
||||||
name: 'meta_description',
|
name: 'meta_description',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
rows: 5,
|
rows: 4,
|
||||||
description:
|
description:
|
||||||
"This description will be shown on lists and pages that don't have meta description",
|
"This description will be shown on lists and pages that don't have meta description",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Meta Keywords',
|
||||||
|
name: 'meta_keywords',
|
||||||
|
type: 'textarea',
|
||||||
|
rows: 4,
|
||||||
|
description:
|
||||||
|
'Keywords for search engines to find your website. Separated by commas.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Meta Image',
|
||||||
|
name: 'meta_image',
|
||||||
|
type: 'Upload',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -51,7 +51,9 @@ const props = defineProps({
|
|||||||
|
|
||||||
const update = () => {
|
const update = () => {
|
||||||
props.fields.forEach((f) => {
|
props.fields.forEach((f) => {
|
||||||
if (f.type != 'Column Break') {
|
if (f.type == 'Upload') {
|
||||||
|
props.data.doc[f.name] = f.value ? f.value.file_url : null
|
||||||
|
} else if (f.type != 'Column Break') {
|
||||||
props.data.doc[f.name] = f.value
|
props.data.doc[f.name] = f.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -54,15 +54,24 @@
|
|||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="flex items-center text-sm space-x-2">
|
<div class="flex items-center text-sm space-x-2">
|
||||||
<div
|
<div
|
||||||
class="flex items-center justify-center rounded border border-outline-gray-modals bg-white w-[10rem] py-5"
|
class="flex items-center justify-center rounded border border-outline-gray-modals bg-white w-[10rem] py-2"
|
||||||
>
|
>
|
||||||
<img :src="data[field.name]?.file_url" class="h-6 rounded" />
|
<img
|
||||||
|
:src="data[field.name]?.file_url || data[field.name]"
|
||||||
|
class="w-[80%] rounded"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col flex-wrap">
|
<div class="flex flex-col flex-wrap">
|
||||||
<span class="break-all text-ink-gray-9">
|
<span class="break-all text-ink-gray-9">
|
||||||
{{ data[field.name]?.file_name }}
|
{{
|
||||||
|
data[field.name]?.file_name ||
|
||||||
|
data[field.name].split('/').pop()
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-sm text-ink-gray-5 mt-1">
|
<span
|
||||||
|
v-if="data[field.name]?.file_size"
|
||||||
|
class="text-sm text-ink-gray-5 mt-1"
|
||||||
|
>
|
||||||
{{ getFileSize(data[field.name]?.file_size) }}
|
{{ getFileSize(data[field.name]?.file_size) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,13 +14,16 @@
|
|||||||
{{ batch.data.description }}
|
{{ batch.data.description }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col gap-2 lg:gap-0 lg:flex-row lg:items-center justify-between lg:w-1/2"
|
class="flex flex-col gap-2 lg:gap-0 lg:flex-row lg:items-center space-x-5 lg:w-1/2"
|
||||||
>
|
>
|
||||||
<div class="flex items-center text-ink-gray-7">
|
<div
|
||||||
|
v-if="batch.data?.courses?.length"
|
||||||
|
class="flex items-center text-ink-gray-7"
|
||||||
|
>
|
||||||
<BookOpen class="h-4 w-4 mr-2" />
|
<BookOpen class="h-4 w-4 mr-2" />
|
||||||
<span> {{ batch.data?.courses?.length }} {{ __('Courses') }} </span>
|
<span> {{ batch.data?.courses?.length }} {{ __('Courses') }} </span>
|
||||||
</div>
|
</div>
|
||||||
<span class="hidden lg:block" v-if="batch.data.courses"
|
<span v-if="batch.data?.courses?.length" class="hidden lg:block"
|
||||||
>·</span
|
>·</span
|
||||||
>
|
>
|
||||||
<DateRange
|
<DateRange
|
||||||
|
|||||||
@@ -60,7 +60,10 @@
|
|||||||
"column_break_uwsp",
|
"column_break_uwsp",
|
||||||
"payment_reminder_template",
|
"payment_reminder_template",
|
||||||
"seo_tab",
|
"seo_tab",
|
||||||
"meta_description"
|
"meta_description",
|
||||||
|
"meta_image",
|
||||||
|
"column_break_xijv",
|
||||||
|
"meta_keywords"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@@ -370,13 +373,29 @@
|
|||||||
"fieldname": "meta_description",
|
"fieldname": "meta_description",
|
||||||
"fieldtype": "Small Text",
|
"fieldtype": "Small Text",
|
||||||
"label": "Meta Description"
|
"label": "Meta Description"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "This image will be shown on lists and pages that don't have an image by default",
|
||||||
|
"fieldname": "meta_image",
|
||||||
|
"fieldtype": "Attach Image",
|
||||||
|
"label": "Meta Image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Common keywords that will be used for all pages",
|
||||||
|
"fieldname": "meta_keywords",
|
||||||
|
"fieldtype": "Small Text",
|
||||||
|
"label": "Meta Keywords"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_xijv",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"grid_page_length": 50,
|
"grid_page_length": 50,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"issingle": 1,
|
"issingle": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2025-04-17 21:58:30.365876",
|
"modified": "2025-04-19 12:19:24.037931",
|
||||||
"modified_by": "sayali@frappe.io",
|
"modified_by": "sayali@frappe.io",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Settings",
|
"name": "LMS Settings",
|
||||||
|
|||||||
@@ -14,25 +14,28 @@ def get_context():
|
|||||||
or "/assets/lms/frontend/favicon.png"
|
or "/assets/lms/frontend/favicon.png"
|
||||||
)
|
)
|
||||||
title = frappe.db.get_single_value("Website Settings", "app_name") or "Frappe Learning"
|
title = frappe.db.get_single_value("Website Settings", "app_name") or "Frappe Learning"
|
||||||
description = frappe.db.get_single_value("LMS Settings", "meta_description")
|
|
||||||
csrf_token = frappe.sessions.get_csrf_token()
|
csrf_token = frappe.sessions.get_csrf_token()
|
||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
|
|
||||||
context = frappe._dict()
|
context = frappe._dict()
|
||||||
context.csrf_token = csrf_token
|
context.csrf_token = csrf_token
|
||||||
context.meta = get_meta(app_path, title, favicon, description)
|
context.meta = get_meta(app_path, title, favicon)
|
||||||
capture("active_site", "lms")
|
capture("active_site", "lms")
|
||||||
context.title = title
|
context.title = title
|
||||||
context.favicon = favicon
|
context.favicon = favicon
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
def get_meta(app_path, title, favicon, description):
|
def get_meta(app_path, title, favicon):
|
||||||
meta = frappe._dict()
|
meta = frappe._dict()
|
||||||
if app_path:
|
if app_path:
|
||||||
meta = get_meta_from_document(app_path)
|
meta = get_meta_from_document(app_path)
|
||||||
|
|
||||||
route_meta = frappe.get_all("Website Meta Tag", {"parent": app_path}, ["key", "value"])
|
route_meta = frappe.get_all("Website Meta Tag", {"parent": app_path}, ["key", "value"])
|
||||||
|
description = frappe.db.get_single_value("LMS Settings", "meta_description")
|
||||||
|
image = frappe.db.get_single_value("LMS Settings", "meta_image")
|
||||||
|
keywords = frappe.db.get_single_value("LMS Settings", "meta_keywords")
|
||||||
|
|
||||||
if len(route_meta) > 0:
|
if len(route_meta) > 0:
|
||||||
for row in route_meta:
|
for row in route_meta:
|
||||||
@@ -54,10 +57,9 @@ def get_meta(app_path, title, favicon, description):
|
|||||||
meta["description"] = description
|
meta["description"] = description
|
||||||
|
|
||||||
if not meta.get("image"):
|
if not meta.get("image"):
|
||||||
meta["image"] = favicon
|
meta["image"] = image or favicon
|
||||||
|
|
||||||
if not meta.get("keywords"):
|
meta["keywords"] = f"{meta.get('keywords')}, {keywords}"
|
||||||
meta["keywords"] = ""
|
|
||||||
|
|
||||||
if not meta:
|
if not meta:
|
||||||
meta = {
|
meta = {
|
||||||
|
|||||||
Reference in New Issue
Block a user