From 133eb470bbc3cd3bc9255976914995332fa56bee Mon Sep 17 00:00:00 2001 From: Ali-Salman29 Date: Tue, 11 Jun 2024 22:54:50 +0200 Subject: [PATCH] update: add arabic fields for certificates --- .../contentstore/views/certificates.py | 3 +- .../js/certificates/models/certificate.js | 8 ++ .../certificates/views/certificate_editor.js | 13 +++ .../js/certificate-details.underscore | 15 +-- .../js/certificate-editor.underscore | 14 +-- lms/djangoapps/certificates/views/webview.py | 20 +++- .../certificates/sass/_sdaia-template.scss | 103 ++++++++++++------ .../_accomplishment-rendering.html | 62 ++++------- xmodule/course_block.py | 7 ++ 9 files changed, 145 insertions(+), 100 deletions(-) diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py index 6535e0a85718..0b3e1a8f85ed 100644 --- a/cms/djangoapps/contentstore/views/certificates.py +++ b/cms/djangoapps/contentstore/views/certificates.py @@ -225,7 +225,8 @@ def serialize_certificate(certificate): "description": certificate_data['description'], "is_active": certificate_data['is_active'], "version": CERTIFICATE_SCHEMA_VERSION, - "signatories": certificate_data['signatories'] + "signatories": certificate_data['signatories'], + "arabic_course_title": certificate_data['arabic_course_title'] } # Some keys are not required, such as the title override... diff --git a/cms/static/js/certificates/models/certificate.js b/cms/static/js/certificates/models/certificate.js index 97a2735d7159..b8b754c257d3 100644 --- a/cms/static/js/certificates/models/certificate.js +++ b/cms/static/js/certificates/models/certificate.js @@ -19,6 +19,8 @@ function(_, Backbone, BackboneRelational, BackboneAssociations, gettext, CoffeeS // Metadata fields currently displayed in web forms course_title: '', + arabic_course_title: '', + // Metadata fields not currently displayed in web forms name: 'Name of the certificate', description: 'Description of the certificate', @@ -78,6 +80,12 @@ function(_, Backbone, BackboneRelational, BackboneAssociations, gettext, CoffeeS attributes: {name: true} }; } + if (!attrs.arabic_course_title.trim()) { + return { + message: gettext('Arabic name is require for generating Certificate'), + attributes: {name: true} + }; + } var allSignatoriesValid = _.every(attrs.signatories.models, function(signatory) { return signatory.isValid(); }); diff --git a/cms/static/js/certificates/views/certificate_editor.js b/cms/static/js/certificates/views/certificate_editor.js index 6b0365ffbf65..ca7fef650e4c 100644 --- a/cms/static/js/certificates/views/certificate_editor.js +++ b/cms/static/js/certificates/views/certificate_editor.js @@ -24,6 +24,7 @@ function($, _, Backbone, gettext, 'change .collection-name-input': 'setName', 'change .certificate-description-input': 'setDescription', 'change .certificate-course-title-input': 'setCourseTitle', + 'change .certificate-arabic-course-title-input': 'setArabicCourseTitle', 'focus .input-text': 'onFocus', 'blur .input-text': 'onBlur', submit: 'setAndClose', @@ -103,6 +104,7 @@ function($, _, Backbone, gettext, name: this.model.get('name'), description: this.model.get('description'), course_title: this.model.get('course_title'), + arabic_course_title: this.model.get('arabic_course_title'), org_logo_path: this.model.get('org_logo_path'), is_active: this.model.get('is_active'), isNew: this.model.isNew() @@ -143,11 +145,22 @@ function($, _, Backbone, gettext, ); }, + setArabicCourseTitle: function(event) { + // Updates the indicated model field (still requires persistence on server) + if (event && event.preventDefault) { event.preventDefault(); } + this.model.set( + 'arabic_course_title', + this.$('.certificate-arabic-course-title-input').val(), + {silent: true} + ); + }, + setValues: function() { // Update the specified values in the local model instance this.setName(); this.setDescription(); this.setCourseTitle(); + this.setArabicCourseTitle(); return this; } }); diff --git a/cms/templates/js/certificate-details.underscore b/cms/templates/js/certificate-details.underscore index a09a3baf897c..8c4f02235352 100644 --- a/cms/templates/js/certificate-details.underscore +++ b/cms/templates/js/certificate-details.underscore @@ -29,6 +29,12 @@ <%- course_title %>

<% } %> + <% if (arabic_course_title) { %> +

+ <%- gettext('Arabic Course Title') %>: + <%- arabic_course_title %> +

+ <% } %>
@@ -46,15 +52,6 @@
- - -
-
-

<%- gettext("Certificate Signatories") %>

-
-

<%- gettext("It is strongly recommended that you include four or fewer signatories. If you include additional signatories, preview the certificate in Print View to ensure the certificate will print correctly on one page.") %>

-
-
<% } %> diff --git a/cms/templates/js/certificate-editor.underscore b/cms/templates/js/certificate-editor.underscore index 513113b80500..ea89595bad35 100644 --- a/cms/templates/js/certificate-editor.underscore +++ b/cms/templates/js/certificate-editor.underscore @@ -31,16 +31,12 @@ " value="<%- course_title %>" aria-describedby="certificate-course-title-<%-uniqueId %>-tip" /> <%- gettext("Specify an alternative to the official course title to display on certificates. Leave blank to use the official course title.") %> +
+ + " value="<%- arabic_course_title %>" aria-describedby="certificate-arabic-course-title-<%-uniqueId %>-tip" /> + <%- gettext("Specify the title in the Arabic for the certificate") %> +
-
-

<%- gettext("Certificate Signatories") %>

-
-

<%- gettext("It is strongly recommended that you include four or fewer signatories. If you include additional signatories, preview the certificate in Print View to ensure the certificate will print correctly on one page.") %>

-
- - - <%- gettext("(Add signatories for a certificate)") %> -
diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py index e4585b98d5f4..69c8e7534de9 100644 --- a/lms/djangoapps/certificates/views/webview.py +++ b/lms/djangoapps/certificates/views/webview.py @@ -114,7 +114,6 @@ def _update_certificate_context(context, course, course_overview, user_certifica uuid=user_certificate.verify_uuid, suffix=context.get('certificate_verify_url_suffix') ) - # We prefer a CourseOverview for this function because it validates and corrects certificate_available_date # and certificates_display_behavior values. However, not all certificates are guaranteed to have a CourseOverview # associated with them, so we fall back on the course in that case. This shouldn't cause a problem because courses @@ -125,7 +124,9 @@ def _update_certificate_context(context, course, course_overview, user_certifica date = display_date_for_certificate(course, user_certificate) # Translators: The format of the date includes the full name of the month date = strftime_localized(date, "%B %-d, %Y") - context['certificate_date_issued'] = convert_date_to_arabic(date) + context['certificate_date_issued'] = date + # SDAIA: Adding Date in Arabic + context['arabic_certificate_date_issued'] = convert_date_to_arabic(date) # Translators: This text represents the verification of the certificate context['document_meta_description'] = _('This is a valid {platform_name} certificate for {user_name}, ' @@ -249,11 +250,18 @@ def _update_course_context(request, context, course, platform_name, course_overv Updates context dictionary with course info. """ effort = course_overview and course_overview.effort or '8' - context['course_duration'] = convert_date_to_arabic(effort) + context['course_duration'] = effort context['full_course_image_url'] = request.build_absolute_uri(course_image_url(course)) course_title_from_cert = context['certificate_data'].get('course_title', '') accomplishment_copy_course_name = course_title_from_cert if course_title_from_cert else course.display_name context['accomplishment_copy_course_name'] = accomplishment_copy_course_name + + # SDAIA: Adding Arabic name in the certificate context + context['arabic_course_duration'] = convert_date_to_arabic(effort) + arabic_course_title_from_cert = context['certificate_data'].get('arabic_course_title', '') + accomplishment_copy_arabic_course_name = arabic_course_title_from_cert if arabic_course_title_from_cert else course.display_name + context['accomplishment_copy_arabic_course_name'] = accomplishment_copy_arabic_course_name + course_number = course.display_coursenumber if course.display_coursenumber else course.number context['course_number'] = course_number context['idv_enabled_for_certificates'] = settings.FEATURES.get('ENABLE_CERTIFICATES_IDV_REQUIREMENT') @@ -326,6 +334,7 @@ def _update_context_with_user_info(context, user, user_certificate): context['accomplishment_user_id'] = user.id context['accomplishment_copy_name'] = user_fullname context['accomplishment_copy_username'] = user.username + context['accomplishment_copy_name_arabic'] = user.profile.arabic_name if user.profile.arabic_name else user_fullname context['accomplishment_more_title'] = _("More Information About {user_name}'s Certificate:").format( user_name=user_fullname @@ -603,7 +612,8 @@ def render_html_view(request, course_id, certificate=None): # pylint: disable=t certificate_language, course_key ) - + # import pdb; pdb.set_trace(); + # Generate the certificate context in the correct language, then render the template. with translation.override(certificate_language): context = {'user_language': user_language} @@ -643,6 +653,8 @@ def render_html_view(request, course_id, certificate=None): # pylint: disable=t # Append/Override the existing view context values with any course-specific static values from Advanced Settings context.update(course.cert_html_view_overrides) + # import pdb; pdb.set_trace(); + # Track certificate view events _track_certificate_events(request, course, user, user_certificate) diff --git a/lms/static/certificates/sass/_sdaia-template.scss b/lms/static/certificates/sass/_sdaia-template.scss index 595339f7a5ca..b32fd6a7e454 100644 --- a/lms/static/certificates/sass/_sdaia-template.scss +++ b/lms/static/certificates/sass/_sdaia-template.scss @@ -3,27 +3,63 @@ html { } @font-face { - font-family: DiodrumArabicFont; - src: url(../fonts/Diodrum/DiodrumArabic-Bold.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Extralight.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Light.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Medium.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Medium.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Regular.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Semibold.ttf); - src: url(../fonts/Diodrum/DiodrumArabic-Thin.ttf); + font-family: 'Diodrum'; + font-weight: 200; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Extralight.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Extralight.ttf') format('truetype'); } + +@font-face { + font-family: 'Diodrum'; + font-weight: 300; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Light.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Light.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 400; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Regular.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Regular.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 500; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Medium.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Medium.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 600; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Semibold.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Semibold.ttf') format('truetype'); +} + +@font-face { + font-family: 'Diodrum'; + font-weight: 700; + src: url('#{$font-path}/Diodrum/DiodrumArabic-Bold.ttf'); + src: + url('#{$font-path}/Diodrum/DiodrumArabic-Bold.ttf') format('truetype'); +} + :root { --primary-color: #32b994; --secondary-color: #1c355e; - --orange-color: #ea6851; } * { margin: 0; padding: 0; } -.orange-color { - color: var(--orange-color); +.primary-color { + color: var(--primary-color); } .black-color { color: var(--secondary-color); @@ -31,13 +67,17 @@ html { .flex-small { display: flex; flex-shrink: 0; - gap: 3px; + gap: 4px; } .text-align{ text-align: right; } .diodrumFontFamily{ - font-family: DiodrumArabicFont; + font-family: Diodrum; + font-weight: 500; +} +.stronger{ + font-weight: 700; } .certificateWrapper { background: url(../images/certificate-bg.png) no-repeat; @@ -60,7 +100,7 @@ html { margin: 0 auto; display: flex; flex-direction: column; - gap: 50px; + gap: 30px; } &__header { display: flex; @@ -73,7 +113,6 @@ html { color: var(--primary-color); display: flex; flex-direction: column; - gap: 5px; font-size: 45px; } &__titleAr { @@ -91,6 +130,9 @@ html { font-weight: bold; flex-direction: column; } + &__personName { + font-size: 22px; + } &__subTitleBody, &__personWrap, &__innerDetailWrap { @@ -98,11 +140,6 @@ html { justify-content: space-between; gap: 10px; } - &__personWrap, - &__innerDetailWrap { - color: var(--orange-color); - font-weight: 700; - } &__innerDetailWrap { font-size: 18px; } @@ -121,13 +158,11 @@ html { &__listWraper { display: flex; flex-direction: column; - gap: 25px; } &__valueListWrap { display: flex; flex-direction: column; - gap: 10px; } @media only screen and (max-width: 1200px) { gap: 20px; @@ -143,15 +178,17 @@ html { } &__mainTitleWrap { - gap: 15px; font-size: 25px; } &__bodywraper { - gap: 50px; + gap: 25px; } &__subTitleWrap { font-size: 18px; } + &__personName { + font-size: 20px; + } } @media only screen and (max-width: 992px) { @@ -187,11 +224,10 @@ html { } &__mainTitleWrap { - gap: 10px; font-size: 20px; } &__bodywraper { - gap: 30px; + gap: 20px; } &__subTitleWrap, &__innerDetailWrap { @@ -215,20 +251,19 @@ html { } &__mainTitleWrap { - gap: 5px; font-size: 18px; } - &__listWraper { - gap: 15px; - } &__subTitleWrap, &__list, &__innerDetailWrap { font-size: 12px; } - } - &__list{ - gap: 5px; + &__list{ + gap: 5px; + } + &__personName { + font-size: 18px; + } } } diff --git a/lms/templates/certificates/_accomplishment-rendering.html b/lms/templates/certificates/_accomplishment-rendering.html index aa6e6b2b3585..2231c61fa462 100644 --- a/lms/templates/certificates/_accomplishment-rendering.html +++ b/lms/templates/certificates/_accomplishment-rendering.html @@ -4,39 +4,15 @@ - SDAIA Academy - Certificate of completion + - - -
+
-
+
Saudi Data and AI Authority (SDAIA) Certifies that
-
+
:الهيئة السعودية للبيانات والذكاء الاصطناعي ( سدايا ) تمنح
- -
@@ -78,33 +54,33 @@

+ ${accomplishment_copy_arabic_course_name} +
Consisting of - (${course_duration}) + (${course_duration}) hours ساعة تدريبية(${course_duration})ساعة تدريبية(${arabic_course_duration})بمعدل
diff --git a/xmodule/course_block.py b/xmodule/course_block.py index 3cf3a1af3563..1fbda9047feb 100644 --- a/xmodule/course_block.py +++ b/xmodule/course_block.py @@ -681,6 +681,13 @@ class CourseFields: # lint-amnesty, pylint: disable=missing-class-docstring scope=Scope.settings, ) + cert_english_name = Dict( + # Translators: This field is the container for course-specific certificate configuration values + display_name=_("Certificate Web/HTML View Overrides"), + # Translators: These overrides allow for an alternative configuration of the certificate web view + help=_("Enter course-specific overrides for the Web/HTML template parameters here (JSON format)"), + scope=Scope.settings, + ) # An extra property is used rather than the wiki_slug/number because # there are courses that change the number for different runs. This allows # courses to share the same css_class across runs even if they have