Supporting multiple theming folders for sites
214
LICENSE.txt
|
@ -1,202 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
1. Definitions.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2014 Stanford University
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
|
19
README.md
|
@ -1,23 +1,6 @@
|
|||
Overview
|
||||
========
|
||||
This directory stores a default theme for an Open edX instance.
|
||||
|
||||
We've organized the tree to mimic the directory structure of the edX
|
||||
codebase so that it's easy to tell where the files will end up upon
|
||||
deploy. We'll use a special settings file to set the template and
|
||||
staticfiles paths properly to point to these files.
|
||||
|
||||
![Alt text](/default_theme_screenshot.jpg?raw=true "Open edX Default Theme Screenshot")
|
||||
|
||||
Theme Authoring
|
||||
===============
|
||||
To customize your theme:
|
||||
- Fork this repository.
|
||||
- Clone it into the theme directory next to your edx-platform directory and rename the theme directory to your new theme's name.
|
||||
- Upload your own image assets.
|
||||
- Edit the .scss file in static/sass/ and rename the file with your theme's name.
|
||||
- Edit the lms.envs.json file in edx-platform and set 'USE_CUSTOM_THEME' to true, and 'THEME_NAME' to your theme's name.
|
||||
|
||||
These are comprehensive theming folders
|
||||
|
||||
License
|
||||
=======
|
||||
|
|
До Ширина: | Высота: | Размер: 13 KiB После Ширина: | Высота: | Размер: 13 KiB |
До Ширина: | Высота: | Размер: 18 KiB После Ширина: | Высота: | Размер: 18 KiB |
До Ширина: | Высота: | Размер: 740 KiB После Ширина: | Высота: | Размер: 740 KiB |
До Ширина: | Высота: | Размер: 22 KiB После Ширина: | Высота: | Размер: 22 KiB |
До Ширина: | Высота: | Размер: 17 KiB После Ширина: | Высота: | Размер: 17 KiB |
До Ширина: | Высота: | Размер: 977 B После Ширина: | Высота: | Размер: 977 B |
До Ширина: | Высота: | Размер: 1.3 KiB После Ширина: | Высота: | Размер: 1.3 KiB |
До Ширина: | Высота: | Размер: 1.3 KiB После Ширина: | Высота: | Размер: 1.3 KiB |
До Ширина: | Высота: | Размер: 344 B После Ширина: | Высота: | Размер: 344 B |
|
@ -210,7 +210,7 @@ course_mode_class = course_mode if course_mode else ''
|
|||
<p>${accomplishment_copy_course_description}</p>
|
||||
<div class="ar-body-content-signs">
|
||||
<div class="ar-signature">
|
||||
<img src="/static/comprehensive/images/satya-sign.png" height="50" width="150" alt="CEO Signature"/>
|
||||
<img src="/static/comprehensive/images/ceo-sign.png" height="50" width="150" alt="CEO Signature"/>
|
||||
<p>
|
||||
<strong>Satya Nadella</strong><br/>
|
||||
Chief Executive Officer<br/>
|
||||
|
@ -218,7 +218,7 @@ course_mode_class = course_mode if course_mode else ''
|
|||
</p>
|
||||
</div>
|
||||
<div class="ar-signature">
|
||||
<img src="/static/comprehensive/images/bjorn-sign.png" height="50" width="150" alt="Director Signature"/>
|
||||
<img src="/static/comprehensive/images/director-sign.png" height="50" width="150" alt="Director Signature"/>
|
||||
<p>
|
||||
<strong>Björn Rettig</strong><br/>
|
||||
Senior Director Technical Content<br/>
|
Двоичные данные
lms/static/images/bjorn-sign.png
До Ширина: | Высота: | Размер: 8.8 KiB |
Двоичные данные
lms/static/images/satya-sign.png
До Ширина: | Высота: | Размер: 10 KiB |
|
@ -0,0 +1,25 @@
|
|||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
%>
|
||||
<%inherit file="base.html" />
|
||||
<%block name="title">${_("Page Not Found")}</%block>
|
||||
<%block name="bodyclass">view-util util-404</%block>
|
||||
|
||||
|
||||
<%block name="content">
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<header>
|
||||
<h1 class="title title-1">${_("Page not found")}</h1>
|
||||
</header>
|
||||
<article class="content-primary" role="main">
|
||||
<p>
|
||||
${_('The page that you were looking for was not found.')}
|
||||
+ ${_('Go back to the {homepage} or let us know about any pages that may have been moved by contacting support.')}
|
||||
</p>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
|
@ -0,0 +1,37 @@
|
|||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
<%inherit file="base.html" />
|
||||
<%block name="title">
|
||||
${Text(_("{studio_name} Server Error")).format(
|
||||
studio_name=Text(settings.STUDIO_SHORT_NAME)
|
||||
)}
|
||||
</%block>
|
||||
<%block name="bodyclass">view-util util-500</%block>
|
||||
|
||||
<%block name="content">
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<header>
|
||||
<h1 class="title title-1">
|
||||
${Text(_(u"The {em_start}{studio_name}{em_end} servers encountered an error")).format(
|
||||
em_start=HTML('<em>'),
|
||||
em_end=HTML('</em>'),
|
||||
studio_name=Text(settings.STUDIO_SHORT_NAME),
|
||||
)}
|
||||
</h1>
|
||||
</header>
|
||||
<article class="content-primary" role="main">
|
||||
<p>
|
||||
${Text(_("An error occurred in {studio_name} and the page could not be loaded. Please try again in a few moments.")).format(
|
||||
studio_name=Text(settings.STUDIO_SHORT_NAME),
|
||||
)}
|
||||
${_("We've logged the error and our staff is currently working to resolve this error as soon as possible.")}
|
||||
${_('If the problem persists, please contact support.')}
|
||||
</p>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
|
@ -0,0 +1,28 @@
|
|||
<%page expression_filter="h"/>
|
||||
<%inherit file="base.html" />
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.conf import settings
|
||||
%>
|
||||
<%block name="bodyclass">error</%block>
|
||||
<%block name="title">
|
||||
% if error == '404':
|
||||
404 - ${_("Page Not Found")}
|
||||
% elif error == '500':
|
||||
500 - ${_("Internal Server Error")}
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
<%block name="content">
|
||||
<article class="error-prompt">
|
||||
% if error == '404':
|
||||
<h1>${_("The Page You Requested Page Cannot be Found")}</h1>
|
||||
<p class="description">${_("We're sorry. We couldn't find the {studio_name} page you're looking for. You may want to return to the {studio_name} Dashboard and try again. If you are still having problems accessing things, please feel free to contact support").format(studio_name=settings.STUDIO_SHORT_NAME )}</p>
|
||||
% elif error == '500':
|
||||
<h1>${_("The Server Encountered an Error")}</h1>
|
||||
<p class="description">${_("We're sorry. There was a problem with the server while trying to process your last request. You may want to return to the {studio_name} Dashboard or try this request again. If you are still having problems accessing things, please feel free to contact {studio_name} support for further help.").format(studio_name=settings.STUDIO_SHORT_NAME )}</p>
|
||||
% endif
|
||||
<a href="/" class="back-button">${_("Back to dashboard")}</a>
|
||||
</article>
|
||||
</%block>
|
|
@ -0,0 +1,57 @@
|
|||
<%page expression_filter="h"/>
|
||||
|
||||
<%inherit file="base.html" />
|
||||
<%def name="online_help_token()"><% return "login" %></%def>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
%>
|
||||
<%block name="title">${_("Sign In")}</%block>
|
||||
<%block name="bodyclass">not-signedin view-signin</%block>
|
||||
|
||||
<%block name="content">
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<header>
|
||||
<h1 class="title title-1">${_("Sign In to {studio_name}").format(studio_name=settings.STUDIO_NAME)}</h1>
|
||||
<a href="${reverse('signup')}" class="action action-signin">${_("Don't have a {studio_name} Account? Sign up!").format(studio_name=settings.STUDIO_SHORT_NAME)}</a>
|
||||
</header>
|
||||
<!-- Login Page override for red-theme. -->
|
||||
<article class="content-primary" role="main">
|
||||
<form id="login_form" method="post" action="login_post" onsubmit="return false;">
|
||||
|
||||
<fieldset>
|
||||
<legend class="sr">${_("Required Information to Sign In to {studio_name}").format(studio_name=settings.STUDIO_NAME)}</legend>
|
||||
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf }" />
|
||||
|
||||
<ol class="list-input">
|
||||
<li class="field text required" id="field-email">
|
||||
<label for="email">${_("E-mail")}</label>
|
||||
<input id="email" type="email" name="email" placeholder="${_('example: username@domain.com')}"/>
|
||||
</li>
|
||||
|
||||
<li class="field text required" id="field-password">
|
||||
<label for="password">${_("Password")}</label>
|
||||
<input id="password" type="password" name="password" />
|
||||
<a href="${forgot_password_link}" class="action action-forgotpassword">${_("Forgot password?")}</a>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" id="submit" name="submit" class="action action-primary">${_("Sign In to {studio_name}").format(studio_name=settings.STUDIO_NAME)}</button>
|
||||
</div>
|
||||
|
||||
<!-- no honor code for CMS, but need it because we're using the lms student object -->
|
||||
<input name="honor_code" type="checkbox" value="true" checked="true" hidden="true">
|
||||
</form>
|
||||
</article>
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
||||
|
||||
<%block name="requirejs">
|
||||
require(["js/factories/login"], function(LoginFactory) {
|
||||
LoginFactory("${reverse('homepage')}");
|
||||
});
|
||||
</%block>
|
|
@ -0,0 +1,113 @@
|
|||
<%inherit file="base.html" />
|
||||
<%def name="online_help_token()"><% return "register" %></%def>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
%>
|
||||
|
||||
<%block name="title">${_("Sign Up")}</%block>
|
||||
<%block name="bodyclass">not-signedin view-signup</%block>
|
||||
|
||||
<%block name="content">
|
||||
|
||||
<div class="wrapper-content wrapper">
|
||||
<section class="content">
|
||||
<header>
|
||||
<h1 class="title title-1">${_("Sign Up for {studio_name}").format(studio_name=settings.STUDIO_NAME)}</h1>
|
||||
<a href="${reverse('login')}" class="action action-signin">${_("Already have a {studio_name} Account? Sign in").format(studio_name=settings.STUDIO_SHORT_NAME)}</a>
|
||||
</header>
|
||||
|
||||
<p class="introduction">${_("Ready to start creating online courses? Sign up below and start creating your first {platform_name} course today.").format(platform_name=settings.PLATFORM_NAME)}</p>
|
||||
|
||||
<article class="content-primary" role="main">
|
||||
<form id="register_form" method="post">
|
||||
<div id="register_error" name="register_error" class="message message-status message-status error">
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<legend class="sr">${_("Required Information to Sign Up for {studio_name}").format(studio_name=settings.STUDIO_NAME)}</legend>
|
||||
|
||||
<ol class="list-input">
|
||||
<li class="field text required" id="field-email">
|
||||
<label for="email">${_("E-mail")}</label>
|
||||
## Translators: This is the placeholder text for a field that requests an email address.
|
||||
<input id="email" type="email" name="email" placeholder="${_("example: username@domain.com")}" />
|
||||
</li>
|
||||
|
||||
<li class="field text required" id="field-name">
|
||||
<label for="name">${_("Full Name")}</label>
|
||||
## Translators: This is the placeholder text for a field that requests the user's full name.
|
||||
<input id="name" type="text" name="name" placeholder="${_("example: Jane Doe")}" />
|
||||
</li>
|
||||
|
||||
<li class="field text required" id="field-username">
|
||||
<label for="username">${_("Public Username")}</label>
|
||||
## Translators: This is the placeholder text for a field that asks the user to pick a username
|
||||
<input id="username" type="text" name="username" placeholder="${_("example: JaneDoe")}" />
|
||||
<span class="tip tip-stacked">${_("This will be used in public discussions with your courses and in our edX101 support forums")}</span>
|
||||
</li>
|
||||
|
||||
<li class="field text required" id="field-password">
|
||||
<label for="password">${_("Password")}</label>
|
||||
<input id="password" type="password" name="password" />
|
||||
</li>
|
||||
|
||||
<li class="field-group">
|
||||
<div class="field text" id="field-location">
|
||||
<label for="location">${_("Your Location")}</label>
|
||||
<input class="short" id="location" type="text" name="location" />
|
||||
</div>
|
||||
|
||||
<div class="field text" id="field-language">
|
||||
<label for="language">${_("Preferred Language")}</label>
|
||||
<input class="short" id="language" type="text" name="language" />
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="field checkbox required" id="field-tos">
|
||||
<input id="tos" name="terms_of_service" type="checkbox" value="true" />
|
||||
I agree to the <a href="http://openedx.microsoft.com/tos" target="_blank">Terms of Service </a>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" id="submit" name="submit" class="action action-primary">${_("Create My Account & Start Authoring Courses")}</button>
|
||||
</div>
|
||||
|
||||
<!-- no honor code for CMS, but need it because we're using the lms student object -->
|
||||
<input name="honor_code" type="checkbox" value="true" checked="true" hidden="true">
|
||||
</form>
|
||||
</article>
|
||||
|
||||
<aside class="content-supplementary" role="complementary">
|
||||
<h2 class="sr">${_("Common {studio_name} Questions").format(studio_name=settings.STUDIO_SHORT_NAME)}</h2>
|
||||
|
||||
<div class="bit">
|
||||
<h3 class="title-3">${_("Who is {studio_name} for?").format(studio_name=settings.STUDIO_SHORT_NAME)}</h3>
|
||||
<p>${_("{studio_name} is for anyone that wants to create online courses that leverage the global {platform_name} platform. Our users are often faculty members, teaching assistants and course staff, and members of instructional technology groups.").format(
|
||||
studio_name=settings.STUDIO_SHORT_NAME, platform_name=settings.PLATFORM_NAME,
|
||||
)}</p>
|
||||
</div>
|
||||
|
||||
<div class="bit">
|
||||
<h3 class="title-3">${_("How technically savvy do I need to be to create courses in {studio_name}?").format(studio_name=settings.STUDIO_SHORT_NAME)}</h3>
|
||||
<p>${_("{studio_name} is designed to be easy to use by almost anyone familiar with common web-based authoring environments (Wordpress, Moodle, etc.). No programming knowledge is required, but for some of the more advanced features, a technical background would be helpful. As always, we are here to help, so don't hesitate to dive right in.").format(
|
||||
studio_name=settings.STUDIO_SHORT_NAME,
|
||||
)}</p>
|
||||
</div>
|
||||
|
||||
<div class="bit">
|
||||
<h3 class="title-3">${_("I've never authored a course online before. Is there help?")}</h3>
|
||||
<p>${_("Absolutely. We have created an online course, edX101, that describes some best practices: from filming video, creating exercises, to the basics of running an online course. Additionally, we're always here to help, just drop us a note.")}</p>
|
||||
</div>
|
||||
</aside>
|
||||
</section>
|
||||
</div>
|
||||
</%block>
|
||||
|
||||
<%block name="requirejs">
|
||||
require(["js/factories/register"], function (RegisterFactory) {
|
||||
RegisterFactory();
|
||||
});
|
||||
</%block>
|
После Ширина: | Высота: | Размер: 13 KiB |
После Ширина: | Высота: | Размер: 18 KiB |
После Ширина: | Высота: | Размер: 740 KiB |
После Ширина: | Высота: | Размер: 22 KiB |
После Ширина: | Высота: | Размер: 17 KiB |
После Ширина: | Высота: | Размер: 977 B |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 1.3 KiB |
После Ширина: | Высота: | Размер: 344 B |
|
@ -0,0 +1,419 @@
|
|||
//-----------------
|
||||
// Override CSS
|
||||
//-----------------
|
||||
html {
|
||||
// The background color of the site
|
||||
background-color: $main-color !important;
|
||||
}
|
||||
|
||||
#{$a-tags}{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
//-----------------
|
||||
// Header Styling
|
||||
//-----------------
|
||||
.home > header {
|
||||
height: 375;
|
||||
background-position: center top;
|
||||
|
||||
.outer-wrapper {
|
||||
padding: 120px 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.home > header .title > .heading-group {
|
||||
display: block !important;
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
.home > header .title > .heading-group h2 {
|
||||
text-transform: none !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
|
||||
.home > header .title > .heading-group h1 {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
//--------------------------------
|
||||
// Registration/Signin link on the header
|
||||
//--------------------------------
|
||||
|
||||
// Register link in header
|
||||
.btn-register:hover{
|
||||
text-decoration: underline !important;
|
||||
color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
// Sign in link on the header
|
||||
.btn-primary:hover{
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
//------------------
|
||||
// Registration Page
|
||||
//------------------
|
||||
// The register button on the registration page
|
||||
.register-button{
|
||||
background-color: $ms-color !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.register-button:hover{
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
.register-button:focus{
|
||||
border: 1px dotted $ms-color !important;
|
||||
}
|
||||
|
||||
// The secondary button (sign in button) on the registration page
|
||||
.nav-btn{
|
||||
border: 1px solid $ms-secondary-button-border !important;
|
||||
color: $ms-primary-button-text !important;
|
||||
}
|
||||
|
||||
.nav-btn:focus{
|
||||
background-color: $ms-secondary-button-hover !important;
|
||||
box-shadow: none !important;
|
||||
border: 1px dotted $ms-secondary-button-border !important;
|
||||
}
|
||||
|
||||
.nav-btn:hover{
|
||||
background-color: $ms-secondary-button-hover !important;
|
||||
box-shadow: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
div.cta-login a.cta-login-action{
|
||||
color: $ms-primary-button-text !important;
|
||||
}
|
||||
|
||||
div.cta-login a.cta-login-action:hover{
|
||||
background-color: $ms-secondary-button-hover !important;
|
||||
color: $ms-primary-button-text !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.cta-register:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
div.main-cta > a.register {
|
||||
border: none !important;
|
||||
color: $main-color;
|
||||
background-color: $ms-color;
|
||||
background-image: none !important;
|
||||
text-shadow: none !important;
|
||||
}
|
||||
|
||||
div.main-cta > a.register:hover {
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
// In the registeration and sign in page we want text fields border to be visible with grey color
|
||||
form .field * {
|
||||
border-color: grey !important;
|
||||
}
|
||||
|
||||
// On the side-bar of registration page Already registered Sign in butons border is made visible with grey color
|
||||
div.cta-login-action {
|
||||
border-color: grey !important;
|
||||
}
|
||||
|
||||
|
||||
//------------------
|
||||
// Sign in Page
|
||||
//------------------
|
||||
.login-button{
|
||||
background-color: $ms-color !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.login-button:hover{
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
.login-button:focus{
|
||||
border: 1px dotted $ms-color !important;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
a:hover{
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
color: $ms-color !important;
|
||||
}
|
||||
|
||||
.forgot-password:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
.field-link:hover{
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
//------------------
|
||||
// View when the user logged in
|
||||
//------------------
|
||||
|
||||
// The user dropdown menu on the right hand side
|
||||
header.header-global .user a.user-link{
|
||||
padding: 5px 12px 10px 10px !important;
|
||||
position: relative;
|
||||
text-transform: none;
|
||||
font-size: 14px;
|
||||
font-weight: 500 !important;
|
||||
letter-spacing: 0;
|
||||
color: $main-color;
|
||||
}
|
||||
|
||||
header.header-global .user .dropdown-menu li>a:hover,header.global .user .dropdown-menu li>a:focus{
|
||||
color: $ms-color !important;
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
|
||||
.fa-sort-desc:before{
|
||||
content:"\f0dd";
|
||||
color:$main-color;
|
||||
}
|
||||
|
||||
.dashboard .my-courses .empty-dashboard-message a {
|
||||
background: $main-color;
|
||||
background-color: $ms-color;
|
||||
color: $main-color !important;
|
||||
font-family: "Segoe UI","Open Sans",Verdana,Geneva,sans-serif,sans-serif;
|
||||
text-shadow: none;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
|
||||
.dashboard .profile-sidebar {
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
header.header-global .user a.user-link .icon {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin: 2px 6px -3px 3px;
|
||||
font-size: 1.2em;
|
||||
color: $main-color !important;
|
||||
}
|
||||
|
||||
/*media all*/
|
||||
header.header-global .user > :last-child.primary > a {
|
||||
padding: 2px 10px 12px 10px !important;
|
||||
border: 1px solid $ms-color;
|
||||
border-left-color: $main-color !important;
|
||||
background: $ms-color !important;
|
||||
}
|
||||
|
||||
header.header-global .user > :last-child.primary > a:hover{
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
// Certificate top shadow and putting into grey area changes
|
||||
//-------------------------
|
||||
|
||||
.accomplishment-rendering {
|
||||
border-top: 0;
|
||||
top: inherit;
|
||||
}
|
||||
|
||||
|
||||
.wrapper-accomplishment-rendering {
|
||||
padding: 30px 2.85714%;
|
||||
}
|
||||
|
||||
.layout-accomplishment .accomplishment-rendering {
|
||||
top: inherit;
|
||||
}
|
||||
|
||||
.layout-accomplishment .wrapper-introduction {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// View on the course view page
|
||||
//------------------
|
||||
div.course-actions > a.enter-course {
|
||||
background-color: $ms-color;
|
||||
}
|
||||
|
||||
div.course-actions > a.enter-course:hover {
|
||||
background-color: $ms-primary-button-hover !important;
|
||||
}
|
||||
|
||||
// The logo height on the course view page when the user signs in
|
||||
header.global.slim h1.logo img {
|
||||
height: inherit !important;
|
||||
}
|
||||
|
||||
// Align find courses link when user signs in
|
||||
.nav-global-01 {
|
||||
margin-top: 0.2em !important;
|
||||
}
|
||||
|
||||
// Align the course name on header when user logs in and view a course
|
||||
header.global.slim h2.course-header {
|
||||
margin-top: 1.2em !important;
|
||||
}
|
||||
|
||||
// Hide the Limited Profile message in My Profile page since we do not let users to enter their age to promote to Full Profile
|
||||
div.wrapper-profile-field-account-privacy {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Hide the birth date on the registration page
|
||||
#field-yob {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Hide birth date from the Additional Information section of Account Settings page
|
||||
div.u-field-year_of_birth {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Hide the Preferred Language on the Account Settings page
|
||||
div.u-field-language_proficiencies {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Hide the mailing address on the registration page
|
||||
#field-address-mailing {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// On the Account Settings page make the textboxes for Full Name and E-Mail visible by showing the borders for UX
|
||||
#u-field-input-name {
|
||||
border-color: grey !important;
|
||||
}
|
||||
#u-field-input-email {
|
||||
border-color: grey !important;
|
||||
}
|
||||
|
||||
// hide the social media links on the course about page
|
||||
.social-sharing {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Update User View Profile/Account Settings to take the maincolor
|
||||
body.view-profile {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
body.ltr {
|
||||
background-color: $main-color;
|
||||
}
|
||||
|
||||
//-----------------
|
||||
// Hide the image on the password reset page
|
||||
//-----------------
|
||||
.view-passwordreset .introduction header {
|
||||
background-image: none !important;
|
||||
}
|
||||
|
||||
//-----------------
|
||||
// Footer Styling
|
||||
//-----------------
|
||||
.wrapper-footer {
|
||||
box-shadow: none !important;
|
||||
|
||||
footer {
|
||||
max-width: 1180px;
|
||||
margin: 0 auto;
|
||||
|
||||
.colophon {
|
||||
width: 80%;
|
||||
float: left;
|
||||
margin-top: 1.1em !important;
|
||||
.nav-colophon li {
|
||||
display: inline-block;
|
||||
height: 35px;
|
||||
float: left;
|
||||
margin: 0 20px 20px 0;
|
||||
}
|
||||
.nav-colophon a:hover{
|
||||
text-decoration:underline;
|
||||
color:$ms-color !important;
|
||||
}
|
||||
}
|
||||
|
||||
.references {
|
||||
width: 15%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
// test if below hover is needed?
|
||||
a:hover {
|
||||
text-decoration: underline !important;
|
||||
}
|
||||
}
|
||||
|
||||
.copyright {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------
|
||||
// TOS Styling
|
||||
//-----------------
|
||||
section.tos {
|
||||
box-sizing: border-box;
|
||||
padding: 0 50px;
|
||||
|
||||
.print {
|
||||
margin: 200px 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------
|
||||
// FAQ Page Table Styling
|
||||
//------------------
|
||||
|
||||
table.faq-table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
tr:nth-child(even){background-color: $gray-2}
|
||||
}
|
||||
|
||||
//------------------
|
||||
// COOKIE BANNER
|
||||
//------------------
|
||||
.cookie-banner-show {
|
||||
padding-top: 0px !important;
|
||||
}
|
||||
|
||||
.cookie-notice {
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 26px;
|
||||
background-color: #EEEEEE !important;
|
||||
vertical-align: central;
|
||||
}
|
||||
|
||||
.cookie-notice-title {
|
||||
margin-left: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
.cookie-color {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.cookie-close {
|
||||
float: right;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
// Import the original styles from edx-platform.
|
||||
@import 'lms/static/sass/lms-main-v1';
|
||||
|
||||
// Our overrides for settings we want to change.
|
||||
@import 'overrides';
|
||||
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
@import 'lms/static/sass/partials/base/variables';
|
||||
|
||||
//-----------------
|
||||
// Color variables (from Stanford palette unless noted)
|
||||
//-----------------
|
||||
|
||||
// MS Blue Color: CourseName, footer links, top left buttons and other buttons (the one on the course page), also the links on the page texts get that color.
|
||||
// This is the common MS Blue colour for all MS sites.
|
||||
$ms-color: #0072c6;
|
||||
|
||||
// Main Color variables
|
||||
// White Color
|
||||
$main-color: #FFFFFF;
|
||||
|
||||
// Main Page, Course tile border color
|
||||
$ms-border: #D2D2D2;
|
||||
|
||||
// MS Button Colors
|
||||
$ms-primary-button-hover: #00188F;
|
||||
$ms-secondary-button-hover: #D2D2D2;
|
||||
$ms-secondary-button-border: #737373;
|
||||
$ms-primary-button-text: #333333;
|
||||
|
||||
$dark-color: $ms-color; //Link Color
|
||||
$light-color: #f4e00c; //Selected Header BG Color, ie. calendar ***Custom, not from palette***
|
||||
$bg-color: #f7fe81; //Selected Content BG Color, ie. calendar ***Custom, not from palette***
|
||||
|
||||
//Main BG Color Variables
|
||||
$main-bg: $ms-color;
|
||||
|
||||
// Pop-up takes this color and the course pages lines take the colors here
|
||||
$main-bg-60: lighten($ms-border, 18.5%); //Main Border/HR Color
|
||||
$main-bg-25: lighten($ms-border, 25%);
|
||||
|
||||
//Secondary Color Variables
|
||||
$secondary: #b5a4b7;
|
||||
$secondary-50: lighten($secondary, 9%);
|
||||
$secondary-25: lighten($secondary, 20%); //Important Heading BG Color
|
||||
|
||||
//Gray Color Variables
|
||||
$gray: #3f3f3f; //Main Text Color
|
||||
$gray-75: lighten($gray, 18.25%); //Lighter Text Color
|
||||
|
||||
$gray-3: #e9e9e9; //Block/Course BG Color
|
||||
$gray-2: #f2f2f2;
|
||||
$gray-1: #fbfbfb; //Main BG Color
|
||||
|
||||
$black: #2e2e2e;
|
||||
$black-80: #585858;
|
||||
|
||||
//-----------------
|
||||
// Font Assignment
|
||||
//-----------------
|
||||
$theme-sans-font: 'Segoe UI';
|
||||
$sans-serif: $theme-sans-font, $sans-serif;
|
||||
$body-font-family: $sans-serif;
|
||||
|
||||
$theme-serif-font: 'Segoe UI';
|
||||
$serif: $theme-serif-font, $serif;
|
||||
|
||||
// newer variables/standards
|
||||
$f-serif: $theme-sans-font, $f-serif;
|
||||
$f-sans-serif: $theme-sans-font, $f-sans-serif;
|
||||
|
||||
//-----------------
|
||||
// Theme Element Assignments
|
||||
//-----------------
|
||||
|
||||
$body-bg: $gray-1;
|
||||
$container-bg: $gray-1;
|
||||
$login-register-bg: $gray-1;
|
||||
$content-wrapper-bg: $gray-1;
|
||||
$header-image: none;
|
||||
$header-bg: $main-color;
|
||||
$courseware-header-image: none;
|
||||
$courseware-header-bg: transparentize(lighten($secondary, 18.5%), .25);
|
||||
$footer-bg: $main-color;
|
||||
$courseware-footer-border: 1px solid $main-bg-60;
|
||||
$courseware-footer-shadow: box-shadow(2px 1px 0 rgba(0, 0, 0, .1));
|
||||
$courseware-footer-margin: 50px;
|
||||
|
||||
$faded-hr-image-1: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
$faded-hr-image-2: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
$faded-hr-image-3: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
$faded-hr-image-4: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
$faded-hr-image-5: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
$faded-hr-image-6: linear-gradient($main-bg-60 0%, $main-bg-60);
|
||||
|
||||
$base-font-color: $black;
|
||||
$lighter-base-font-color: $black-80;
|
||||
$very-light-text: $gray-1;
|
||||
|
||||
$link-color: $dark-color;
|
||||
$link-color-d1: $dark-color;
|
||||
$link-hover: $light-color;
|
||||
$site-status-color: $bg-color;
|
||||
|
||||
$header-graphic-super-color: $dark-color;
|
||||
$header-graphic-sub-color: $lighter-base-font-color;
|
||||
|
||||
$header-link-color: $dark-color;
|
||||
$header-link-hover: $light-color;
|
||||
|
||||
$button-color: $ms-color;
|
||||
$button-archive-color: $gray-3;
|
||||
$shadow-color: $gray;
|
||||
|
||||
// actions
|
||||
$button-bg-image: none;
|
||||
$button-bg-color: $ms-color;
|
||||
$button-bg-hover-color: $ms-primary-button-hover;
|
||||
|
||||
// actions - primary
|
||||
$action-primary-bg: $ms-color;
|
||||
$action-primary-fg: $gray-2;
|
||||
$action-primary-shadow: none;
|
||||
|
||||
// focused - hover/active pseudo states
|
||||
$action-primary-focused-bg: $dark-color;
|
||||
$action-primary-focused-fg: $gray-1;
|
||||
|
||||
// current or active navigation item
|
||||
$action-primary-active-bg: $dark-color;
|
||||
$action-primary-active-fg: $gray-1;
|
||||
$action-primary-active-shadow: none;
|
||||
$action-primary-active-focused-fg: $gray-2;
|
||||
$action-primary-active-focused-shadow: none;
|
||||
|
||||
// disabled
|
||||
$action-primary-disabled-bg: $gray-75;
|
||||
$action-prmary-disabled-fg: $gray-1;
|
||||
|
||||
// actions - secondary
|
||||
$action-secondary-bg: $secondary;
|
||||
$action-secondary-fg: $gray;
|
||||
$action-secondary-shadow: none;
|
||||
|
||||
// focused - hover/active pseudo states
|
||||
$action-secondary-focused-bg: $secondary-50;
|
||||
$action-secondary-focused-fg: $gray;
|
||||
|
||||
// current or active navigation item
|
||||
$action-secondary-active-bg: $secondary-50;
|
||||
$action-secondary-active-fg: $gray;
|
||||
$action-secondary-active-shadow: none;
|
||||
$action-secondary-active-focused-fg: $gray-75;
|
||||
$action-secondary-active-focused-shadow: none;
|
||||
|
||||
// disabled
|
||||
$action-secondary-disabled-bg: $gray-3;
|
||||
$action-secondary-disabled-fg: $gray;
|
||||
|
||||
$border-color-1: $main-bg-60;
|
||||
$border-color-2: $main-bg-60;
|
||||
$border-color-3: $main-bg-60;
|
||||
$outer-border-color: $main-bg-60;
|
||||
|
||||
$sidebar-color: $gray-1;
|
||||
|
||||
$homepage__header--gradient__color--alpha: $secondary-25;
|
||||
$homepage__header--gradient__color--bravo: $secondary-25;
|
||||
$homepage__header--background: $secondary-25;
|
||||
$dashboard-profile-header-image: none;
|
||||
$dashboard-profile-header-color: $secondary-25;
|
||||
$dashboard-profile-color: $gray-3;
|
||||
$dot-color: $main-bg-60;
|
||||
|
||||
$course-bg-color: $gray-3;
|
||||
$course-bg-image: none;
|
||||
$account-content-wrapper-bg: $gray-1;
|
||||
|
||||
$course-profile-bg: $gray-1;
|
||||
$course-header-bg: transparentize($gray-1, .1);
|
||||
|
||||
$sidebar-chapter-bg-top: transparentize($gray-1, .3);
|
||||
$sidebar-chapter-bg-bottom: transparentize($gray-1, .9);
|
||||
$sidebar-chapter-bg: $gray-2;
|
||||
$sidebar-active-image: $gray-3;
|
||||
|
||||
$form-bg-color: $gray-1;
|
||||
$modal-bg-color: $gray-1;
|
||||
|
||||
//TOP HEADER IMAGE MARGIN
|
||||
$header_image_margin: -77px;
|
||||
|
||||
//FOOTER MARGIN
|
||||
$footer_margin: ($baseline/4) 0;
|
||||
|
||||
$a-tags: 'a, a:active, a:hover, a:visited';
|
||||
|
||||
//-----------------
|
||||
// CSS BG Images
|
||||
//-----------------
|
||||
// Home Page Background Image
|
||||
$homepage-bg-image: url('/static/comprehensive/images/REX_BG_1.png');
|
|
@ -0,0 +1,7 @@
|
|||
<section class="about-item about-accomplishments">
|
||||
<h2 class="about-title hd-4">${accomplishment_copy_about}</h2>
|
||||
|
||||
<div class="about-copy copy copy-meta">
|
||||
<p>${platform_name} acknowledges achievements through certificates, which are awarded for various activities Microsoft Learning students complete under the <a href="https://openedx.microsoft.com/tos">Microsoft Learning Terms of Service</a>. Some certificates require completing additional steps.</p>
|
||||
</div>
|
||||
</section>
|
|
@ -0,0 +1,9 @@
|
|||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<section class="about-item about-edx">
|
||||
<h2 class="about-edx-title hd-4">${company_about_title}</h2>
|
||||
|
||||
<div class="about-edx-copy copy copy-meta">
|
||||
<p>Fulfill your potential and make the most of your investment in Microsoft technology with certification, Massive Open Online Courses (MOOC), classroom training, e-learning, and books from Microsoft and Microsoft Learning Partners.</p>
|
||||
<a class="action" href="${company_about_url}">${company_about_urltext}</a>
|
||||
</div>
|
||||
</section>
|
|
@ -0,0 +1,16 @@
|
|||
<div class="wrapper-footer">
|
||||
|
||||
<footer class="footer-app" role="contentinfo" id="company-info">
|
||||
<div class="footer-app-copyright">
|
||||
<p class="copy copy-micro">© <script>document.write(new Date().getFullYear())</script> Microsoft Corporation</p>
|
||||
</div>
|
||||
<nav class="footer-app-nav">
|
||||
<ul class="list list-legal">
|
||||
<li class="nav-item">
|
||||
<a class="action btn btn-small btn-link" href="https://openedx.microsoft.com/tos">Terms of Service</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</footer>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,240 @@
|
|||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%
|
||||
course_mode_class = course_mode if course_mode else ''
|
||||
%>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: MDL2;
|
||||
src: url(../app/assets/fonts/mdl2/MDL2.eot);
|
||||
src: url(../app/assets/fonts/mdl2/MDL2.eot#iefix) format("embedded-opentype"), url(../app/assets/fonts/mdl2/MDL2.ttf) format("truetype"), url(../app/assets/fonts/mdl2/MDL2.woff) format("woff"), url(../app/assets/fonts/mdl2/MDL2.svg#mdl2) format("svg");
|
||||
font-weight: 400;
|
||||
font-style: normal
|
||||
}
|
||||
@font-face {
|
||||
font-family: SegoeUI;
|
||||
src: local("Segoe UI"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff2) format("woff2"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.woff) format("woff"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.ttf) format("truetype"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/normal/latest.svg#web) format("svg");
|
||||
font-weight: 400;
|
||||
font-style: normal
|
||||
}
|
||||
@font-face {
|
||||
font-family: SegoeUI;
|
||||
src: local("Segoe UI Light"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.woff2) format("woff2"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.woff) format("woff"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.ttf) format("truetype"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/light/latest.svg#web) format("svg");
|
||||
font-weight: 100;
|
||||
font-style: normal
|
||||
}
|
||||
@font-face {
|
||||
font-family: SegoeUI;
|
||||
src: local("Segoe UI Bold"), local("Segoe UI"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.woff2) format("woff2"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.woff) format("woff"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.ttf) format("truetype"), url(//c.s-microsoft.com/static/fonts/segoe-ui/west-european/bold/latest.svg#web) format("svg");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
.accomplishment-main {
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
.layout-accomplishment .accomplishment-rendering {
|
||||
top: inherit;
|
||||
}
|
||||
.accomplishment-rendering {
|
||||
box-sizing: border-box;
|
||||
max-width: 756px;
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
border-top:none;
|
||||
}
|
||||
.accomplishment-rendering h1,
|
||||
.accomplishment-rendering h2,
|
||||
.accomplishment-rendering h3,
|
||||
.accomplishment-rendering p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: SegoeUI, Arial, sans-serif;
|
||||
}
|
||||
.ar-header {
|
||||
position: relative;
|
||||
padding: 40px 50px 20px 30px;
|
||||
min-height: 173px;
|
||||
background-color: #002050;
|
||||
}
|
||||
.ar-header h1 {
|
||||
color: #FFFFFF;
|
||||
font-size: 46px;
|
||||
font-weight: 100;
|
||||
line-height: 60px;
|
||||
}
|
||||
.ar-header-logo {
|
||||
position: absolute;
|
||||
top: 18px;
|
||||
right: 20px;
|
||||
}
|
||||
.ar-header-logo .print-logo {
|
||||
display: none;
|
||||
}
|
||||
.ar-ribbon {
|
||||
border-bottom: 7px solid #00B0E3;
|
||||
}
|
||||
.ar-body {
|
||||
position: relative;
|
||||
clear: both;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ar-body-content {
|
||||
padding: 30px 136px 30px 30px;
|
||||
}
|
||||
.ar-body-content h2 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 5px;
|
||||
font-size: 46px;
|
||||
line-height: 60px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
.ar-body-content h3 {
|
||||
font-size: 18px;
|
||||
line-height: 27px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.ar-body-content p {
|
||||
font-size: 15px;
|
||||
line-height: 18px;
|
||||
margin-bottom: 30px;
|
||||
max-width: 500px;
|
||||
}
|
||||
.ar-body-content-signs {
|
||||
position: relative;
|
||||
margin-top: 40px;
|
||||
clear: both;
|
||||
}
|
||||
.ar-body-ribbon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 75px;
|
||||
height: 68px;
|
||||
width: 61px;
|
||||
}
|
||||
.ar-footer {
|
||||
clear: left;
|
||||
padding: 10px 30px;
|
||||
background-color: #002050;
|
||||
border-top: 2px solid #00B0E3;
|
||||
}
|
||||
.ar-footer p {
|
||||
color: #FFFFFF;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
line-height: 14px;
|
||||
}
|
||||
.ar-signature {
|
||||
float: left;
|
||||
margin: 0 20px 0 0;
|
||||
width: 200px;
|
||||
}
|
||||
.ar-signature p {
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
}
|
||||
.layout-accomplishment .wrapper-accomplishment-rendering {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.layout-accomplishment .wrapper-about {
|
||||
padding-top: 1.5rem;
|
||||
padding-bottom: 1.5rem;
|
||||
}
|
||||
@media screen and (max-width: 767px) {
|
||||
.ar-header h1 {
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
}
|
||||
.ar-body-content h2 {
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
}
|
||||
.ar-body-ribbon {
|
||||
display: none;
|
||||
}
|
||||
.ar-body-content {
|
||||
padding: 30px 16px 30px 16px;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.accomplishment-main{
|
||||
padding: 0;
|
||||
}
|
||||
.accomplishment-rendering{
|
||||
border-top: 0.0625rem solid #d3d1d1;
|
||||
}
|
||||
.ar-header-logo .screen-logo {
|
||||
display: none;
|
||||
}
|
||||
.ar-header-logo .print-logo {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/* from http://browserstrangeness.bitbucket.org/css_hacks.html, Chrome and Safari (and Opera 14+), NOT Microsoft Edge */
|
||||
@media print and (-webkit-min-device-pixel-ratio:0) {
|
||||
@supports (not (-ms-ime-align: auto)) {
|
||||
.ar-header-logo .screen-logo {
|
||||
display: block;
|
||||
}
|
||||
.ar-header-logo .print-logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<main class="accomplishment accomplishment-main">
|
||||
<div class="wrapper-accomplishment-rendering">
|
||||
<div class="accomplishment-rendering">
|
||||
<div class="ar-header">
|
||||
<h1>${platform_name}<br/>Honor Certificate of Completion</h1>
|
||||
<div class="ar-header-logo">
|
||||
<img class="screen-logo" src="/static/comprehensive/images/ms-logo-white.png" alt="Microsoft" />
|
||||
<img class="print-logo" src="/static/comprehensive/images/ms-logo-grey.png" alt="Microsoft" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ar-ribbon">
|
||||
</div>
|
||||
<div class="ar-body">
|
||||
<div class="ar-body-content">
|
||||
<h2>${accomplishment_copy_name | h}</h2>
|
||||
<p>${accomplishment_copy_description_full}</p>
|
||||
<h3>
|
||||
<span class="accomplishment-course-org">${accomplishment_copy_course_org} </span>
|
||||
<span class="accomplishment-course-number">${course_number}</span>:
|
||||
<span class="accomplishment-course-name">${accomplishment_copy_course_name}</span>
|
||||
</h3>
|
||||
<p>${accomplishment_copy_course_description}</p>
|
||||
<div class="ar-body-content-signs">
|
||||
<div class="ar-signature">
|
||||
<img src="/static/comprehensive/images/ceo-sign.png" height="50" width="150" alt="CEO Signature"/>
|
||||
<p>
|
||||
<strong>Satya Nadella</strong><br/>
|
||||
Chief Executive Officer<br/>
|
||||
Microsoft
|
||||
</p>
|
||||
</div>
|
||||
<div class="ar-signature">
|
||||
<img src="/static/comprehensive/images/director-sign.png" height="50" width="150" alt="Director Signature"/>
|
||||
<p>
|
||||
<strong>Björn Rettig</strong><br/>
|
||||
Senior Director Technical Content<br/>
|
||||
Microsoft
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ar-body-ribbon">
|
||||
<img src="/static/comprehensive/images/ribbon.png" alt=""/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ar-footer">
|
||||
<p>Certification Number: ${certificate_id_number}</p>
|
||||
<p>Date of Achievement: ${certificate_date_issued}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
|
@ -0,0 +1,22 @@
|
|||
<%inherit file="accomplishment-base.html" />
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
% if user.is_authenticated() and user.id == int(accomplishment_user_id):
|
||||
<%include file="_accomplishment-banner.html" />
|
||||
% endif
|
||||
<%include file="_accomplishment-introduction.html" />
|
||||
|
||||
<%include file="_accomplishment-rendering.html" />
|
||||
<div class="wrapper-about">
|
||||
<aside role="complementary" class="about" aria-label="About edX Certificates">
|
||||
<%include file="_about-edx.html" />
|
||||
<%include file="_about-accomplishments.html" />
|
||||
</aside>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
(function(a,b,c,d){
|
||||
a='//tags.tiqcdn.com/utag/msft/lex-openedx/prod/utag.js';
|
||||
b=document;c='script';d=b.createElement(c);d.src=a;d.type='text/java'+c;d.async=true;
|
||||
a=b.getElementsByTagName(c)[0];a.parentNode.insertBefore(d,a);
|
||||
})();
|
||||
</script>
|
|
@ -0,0 +1,57 @@
|
|||
<%def name="online_help_token()"><% return "course" %></%def>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
%>
|
||||
<%page args="course" expression_filter="h"/>
|
||||
<article class="course" id="${course.id}" role="region" aria-label="${course.display_name_with_default}">
|
||||
<a href="${reverse('about_course', args=[course.id.to_deprecated_string()])}">
|
||||
<header class="course-image">
|
||||
<div class="cover-image">
|
||||
<img src="${course.course_image_url}" alt="${course.display_name_with_default} ${course.display_number_with_default}" />
|
||||
<div class="learn-more" aria-hidden="true">${_("LEARN MORE")}</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="course-info" aria-hidden="true">
|
||||
<h2 class="course-name">
|
||||
<span class="course-organization">${course.display_org_with_default}</span>
|
||||
<span class="course-code">${course.display_number_with_default}</span>
|
||||
<span class="course-title">${course.display_name_with_default}</span>
|
||||
</h2>
|
||||
<%
|
||||
if course.start is not None:
|
||||
course_date_string = course.start.strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||
else:
|
||||
course_date_string = ''
|
||||
%>
|
||||
% if course.self_paced:
|
||||
<div class="course-date" aria-hidden="true">Self-Paced</div>
|
||||
% else:
|
||||
% if course.advertised_start is not None:
|
||||
<div class="course-date" aria-hidden="true">${_("Starts")}: ${course.advertised_start}</div>
|
||||
% else:
|
||||
<div class="course-date localized_datetime" aria-hidden="true" data-format="shortDate" data-datetime="${course_date_string}" data-string="${_("Starts: {date}")}"></div>
|
||||
% endif
|
||||
% endif
|
||||
</div>
|
||||
<div class="sr">
|
||||
<ul>
|
||||
<li>${course.display_org_with_default}</li>
|
||||
<li>${course.display_number_with_default}</li>
|
||||
% if course.self_paced:
|
||||
<li>Self-Paced</li>
|
||||
% else:
|
||||
% if course.advertised_start is not None:
|
||||
<li>${_("Starts")}: <time itemprop="startDate">${course.advertised_start}</time></li>
|
||||
% else:
|
||||
<li>${_("Starts")}: <time class="localized_datetime" itemprop="startDate" data-format="shortDate" data-datetime="${course_date_string}"></time></li>
|
||||
% endif
|
||||
% endif
|
||||
</ul>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
||||
DateUtilFactory.transform(iterationKey=".localized_datetime");
|
||||
</%static:require_module_async>
|
|
@ -0,0 +1,354 @@
|
|||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from courseware.courses import get_course_about_section
|
||||
from django.conf import settings
|
||||
from edxmako.shortcuts import marketing_link
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
%>
|
||||
|
||||
<%inherit file="../main.html" />
|
||||
<%block name="headextra">
|
||||
## OG (Open Graph) title and description added below to give social media info to display
|
||||
## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
|
||||
<meta property="og:title" content="${course.display_name_with_default_escaped}" />
|
||||
<meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" />
|
||||
</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
## CourseTalk widget js script
|
||||
% if show_coursetalk_widget:
|
||||
<script src="//d3q6qq2zt8nhwv.cloudfront.net/s/js/widgets/coursetalk-read-reviews.js"></script>
|
||||
% endif
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
$(".register").click(function(event) {
|
||||
$("#class_enroll_form").submit();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
% if can_add_course_to_cart:
|
||||
add_course_complete_handler = function(jqXHR, textStatus) {
|
||||
if (jqXHR.status == 200) {
|
||||
location.href = "${cart_link}";
|
||||
}
|
||||
if (jqXHR.status == 400) {
|
||||
$("#register_error")
|
||||
.html(jqXHR.responseText ? jqXHR.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
.css("display", "block");
|
||||
}
|
||||
else if (jqXHR.status == 403) {
|
||||
location.href = "${reg_then_add_to_cart_link}";
|
||||
}
|
||||
};
|
||||
|
||||
$("#add_to_cart_post").click(function(event){
|
||||
$.ajax({
|
||||
url: "${reverse('add_course_to_cart', args=[course.id.to_deprecated_string()])}",
|
||||
type: "POST",
|
||||
/* Rant: HAD TO USE COMPLETE B/C PROMISE.DONE FOR SOME REASON DOES NOT WORK ON THIS PAGE. */
|
||||
complete: add_course_complete_handler
|
||||
})
|
||||
event.preventDefault();
|
||||
});
|
||||
% endif
|
||||
|
||||
## making the conditional around this entire JS block for sanity
|
||||
%if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
|
||||
<%
|
||||
perms_error = _('The currently logged-in user account does not have permission to enroll in this course. '
|
||||
'You may need to {start_logout_tag}log out{end_tag} then try the enroll button again. '
|
||||
'Please visit the {start_help_tag}help page{end_tag} for a possible solution.').format(
|
||||
start_help_tag="<a href='{url}'>".format(url=marketing_link('FAQ')), end_tag='</a>',
|
||||
start_logout_tag="<a href='{url}'>".format(url=reverse('logout'))
|
||||
)
|
||||
%>
|
||||
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
|
||||
if(xhr.status == 200) {
|
||||
location.href = "${reverse('dashboard')}";
|
||||
} else if (xhr.status == 403) {
|
||||
location.href = "${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}?course_id=${course.id | u}&enrollment_action=enroll";
|
||||
} else if (xhr.status == 400) { //This means the user did not have permission
|
||||
$('#register_error').html("${perms_error}").css("display", "block");
|
||||
} else {
|
||||
$('#register_error').html(
|
||||
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
).css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
%else:
|
||||
|
||||
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
|
||||
if(xhr.status == 200) {
|
||||
if (xhr.responseText == "") {
|
||||
location.href = "${reverse('dashboard')}";
|
||||
}
|
||||
else {
|
||||
location.href = xhr.responseText;
|
||||
}
|
||||
} else if (xhr.status == 403) {
|
||||
location.href = "${reverse('register_user')}?course_id=${course.id | u}&enrollment_action=enroll";
|
||||
} else {
|
||||
$('#register_error').html(
|
||||
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
).css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
%endif
|
||||
|
||||
})(this)
|
||||
</script>
|
||||
|
||||
<script src="${static.url('js/course_info.js')}"></script>
|
||||
</%block>
|
||||
|
||||
<%block name="pagetitle">${course.display_name_with_default_escaped}</%block>
|
||||
|
||||
<section class="course-info">
|
||||
<header class="course-profile">
|
||||
<div class="intro-inner-wrapper">
|
||||
<div class="table">
|
||||
<section class="intro">
|
||||
<div class="heading-group">
|
||||
<h1>
|
||||
${course.display_name_with_default_escaped}
|
||||
<button type="button">${course.display_org_with_default | h}</button>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="main-cta">
|
||||
%if user.is_authenticated() and registered:
|
||||
%if show_courseware_link:
|
||||
<a href="${course_target}">
|
||||
%endif
|
||||
|
||||
<span class="register disabled">${_("You are enrolled in this course")}</span>
|
||||
|
||||
%if show_courseware_link:
|
||||
<strong>${_("View Course")}</strong>
|
||||
</a>
|
||||
%endif
|
||||
|
||||
%elif in_cart:
|
||||
<span class="add-to-cart">
|
||||
${_('This course is in your <a href="{cart_link}">cart</a>.').format(cart_link=cart_link)}
|
||||
</span>
|
||||
% elif is_course_full:
|
||||
<span class="register disabled">
|
||||
${_("Course is full")}
|
||||
</span>
|
||||
% elif invitation_only and not can_enroll:
|
||||
<span class="register disabled">${_("Enrollment in this course is by invitation only")}</span>
|
||||
## Shib courses need the enrollment button to be displayed even when can_enroll is False,
|
||||
## because AnonymousUsers cause can_enroll for shib courses to be False, but we need them to be able to click
|
||||
## so that they can register and become a real user that can enroll.
|
||||
% elif not is_shib_course and not can_enroll:
|
||||
<span class="register disabled">${_("Enrollment is Closed")}</span>
|
||||
%elif can_add_course_to_cart:
|
||||
<%
|
||||
if user.is_authenticated():
|
||||
reg_href = "#"
|
||||
reg_element_id = "add_to_cart_post"
|
||||
else:
|
||||
reg_href = reg_then_add_to_cart_link
|
||||
reg_element_id = "reg_then_add_to_cart"
|
||||
%>
|
||||
<% if ecommerce_checkout:
|
||||
reg_href = ecommerce_checkout_link
|
||||
reg_element_id = ""
|
||||
%>
|
||||
<a href="${reg_href}" class="add-to-cart" id="${reg_element_id}">
|
||||
${_("Add {course_name} to Cart <span>({price} USD)</span>")\
|
||||
.format(course_name=course.display_number_with_default, price=course_price)}
|
||||
</a>
|
||||
<div id="register_error"></div>
|
||||
%else:
|
||||
<%
|
||||
if ecommerce_checkout:
|
||||
reg_href = ecommerce_checkout_link
|
||||
else:
|
||||
reg_href="#"
|
||||
if professional_mode:
|
||||
href_class = "add-to-cart"
|
||||
else:
|
||||
href_class = "register"
|
||||
%>
|
||||
<a href="${reg_href}" class="${href_class}">
|
||||
${_("Enroll in {course_name}").format(course_name=course.display_number_with_default) | h}
|
||||
</a>
|
||||
<div id="register_error"></div>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
</section>
|
||||
% if get_course_about_section(request, course, "video"):
|
||||
<a href="#video-modal" class="media" rel="leanModal">
|
||||
<div class="hero">
|
||||
<img src="${course_image_urls['large']}" alt="" />
|
||||
<div class="play-intro"></div>
|
||||
</div>
|
||||
</a>
|
||||
%else:
|
||||
<div class="media">
|
||||
<div class="hero">
|
||||
<img src="${course_image_urls['large']}" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<div class="details">
|
||||
% if staff_access and studio_url is not None:
|
||||
<div class="wrap-instructor-info studio-view">
|
||||
<a class="instructor-info-action" href="${studio_url}">${_("View About Page in studio")}</a>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<div class="inner-wrapper">
|
||||
${get_course_about_section(request, course, "overview")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="course-sidebar">
|
||||
<div class="course-summary">
|
||||
|
||||
<%include file="course_about_sidebar_header.html" />
|
||||
|
||||
<ol class="important-dates">
|
||||
<li class="important-dates-item"><span class="icon fa fa-info-circle" aria-hidden="true"></span><p class="important-dates-item-title">${_("Course Number")}</p><span class="important-dates-item-text course-number">${course.display_number_with_default | h}</span></li>
|
||||
% if not course.self_paced:
|
||||
% if not course.start_date_is_still_default:
|
||||
<%
|
||||
course_start_date = course.start
|
||||
%>
|
||||
<li class="important-dates-item">
|
||||
<span class="icon fa fa-calendar" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Classes Start")}</p>
|
||||
% if isinstance(course_start_date, str):
|
||||
<span class="important-dates-item-text start-date">${course_start_date}</span>
|
||||
% else:
|
||||
<%
|
||||
course_date_string = course_start_date.strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||
%>
|
||||
<span class="important-dates-item-text start-date localized_datetime" data-format="shortDate" data-datetime="${course_date_string}"></span>
|
||||
% endif
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
% if not course.self_paced:
|
||||
## We plan to ditch end_date (which is not stored in course metadata),
|
||||
## but for backwards compatibility, show about/end_date blob if it exists.
|
||||
% if get_course_about_section(request, course, "end_date") or course.end:
|
||||
<%
|
||||
course_end_date = course.end
|
||||
%>
|
||||
<li class="important-dates-item">
|
||||
<span class="icon fa fa-calendar" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Classes End")}</p>
|
||||
% if isinstance(course_end_date, str):
|
||||
<span class="important-dates-item-text final-date">${course_end_date}</span>
|
||||
% else:
|
||||
<%
|
||||
course_date_string = course_end_date.strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||
%>
|
||||
<span class="important-dates-item-text final-date localized_datetime" data-format="shortDate" data-datetime="${course_date_string}"></span>
|
||||
% endif
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
% if course.self_paced:
|
||||
<li class="important-dates-item"><i class="icon fa fa-info-circle"></i><p class="important-dates-item-title">${_("Course Mode")}</p><span class="important-dates-item-text start-date">Self-Paced</span></li>
|
||||
% endif
|
||||
|
||||
% if get_course_about_section(request, course, "effort"):
|
||||
<li class="important-dates-item"><span class="icon fa fa-pencil" aria-hidden="true"></span><p class="important-dates-item-title">${_("Estimated Effort")}</p><span class="important-dates-item-text effort">${get_course_about_section(request, course, "effort")}</span></li>
|
||||
% endif
|
||||
|
||||
##<li class="important-dates-item"><span class="icon fa fa-clock-o" aria-hidden="true"></span><p class="important-dates-item-title">${_('Course Length')}</p><span class="important-dates-item-text course-length">${_('{number} weeks').format(number=15)}</span></li>
|
||||
|
||||
%if course_price and (can_add_course_to_cart or is_cosmetic_price_enabled):
|
||||
<li class="important-dates-item">
|
||||
<span class="icon fa fa-money" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Price")}</p>
|
||||
<span class="important-dates-item-text">${course_price}</span>
|
||||
</li>
|
||||
%endif
|
||||
|
||||
% if pre_requisite_courses:
|
||||
<% prc_target = reverse('about_course', args=[unicode(pre_requisite_courses[0]['key'])]) %>
|
||||
<li class="prerequisite-course important-dates-item">
|
||||
<span class="icon fa fa-list-ul" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Prerequisites")}</p>
|
||||
## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element
|
||||
<span class="important-dates-item-text pre-requisite"><a href="${prc_target}">${pre_requisite_courses[0]['display']}</a></span>
|
||||
<p class="tip">
|
||||
${_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.").format(
|
||||
link_start='<a href="{}">'.format(prc_target),
|
||||
link_end='</a>',
|
||||
prc_display=pre_requisite_courses[0]['display'],
|
||||
)}
|
||||
</p>
|
||||
</li>
|
||||
% endif
|
||||
% if get_course_about_section(request, course, "prerequisites"):
|
||||
<li class="important-dates-item"><span class="icon fa fa-book" aria-hidden="true"></span><p class="important-dates-item-title">${_("Requirements")}</p><span class="important-dates-item-text prerequisites">${get_course_about_section(request, course, "prerequisites")}</span></li>
|
||||
% endif
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
## CourseTalk widget
|
||||
% if show_coursetalk_widget:
|
||||
<div class="coursetalk-read-reviews">
|
||||
<div id="ct-custom-read-review-widget" data-provider="${platform_key}" data-course="${course_review_key}"></div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
## For now, ocw links are the only thing that goes in additional resources
|
||||
% if get_course_about_section(request, course, "ocw_links"):
|
||||
<div class="additional-resources">
|
||||
<header>
|
||||
<h1>${_("Additional Resources")}</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
## "MITOpenCourseware" should *not* be translated
|
||||
<h2 class="opencourseware">MITOpenCourseware</h2>
|
||||
${get_course_about_section(request, course, "ocw_links")}
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Need to put this hidden form on the page so that the registration button works.
|
||||
## Since it's no harm to display a hidden form, we display it with the most permissive conditional
|
||||
## which is when the student is not registered.
|
||||
%if active_reg_button or is_shib_course:
|
||||
<div style="display: none;">
|
||||
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
|
||||
<fieldset class="enroll_fieldset">
|
||||
<legend class="sr">${_("Enroll")}</legend>
|
||||
<input name="course_id" type="hidden" value="${course.id | h}">
|
||||
<input name="enrollment_action" type="hidden" value="enroll">
|
||||
</fieldset>
|
||||
<div class="submit">
|
||||
<input name="submit" type="submit" value="${_('enroll')}">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
<%include file="../video_modal.html" />
|
||||
|
||||
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
||||
DateUtilFactory.transform(iterationKey=".localized_datetime");
|
||||
</%static:require_module_async>
|
|
@ -0,0 +1,329 @@
|
|||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from courseware.courses import get_course_about_section
|
||||
from django.conf import settings
|
||||
from edxmako.shortcuts import marketing_link
|
||||
from openedx.core.lib.courses import course_image_url
|
||||
%>
|
||||
|
||||
<%inherit file="../main.html" />
|
||||
<%block name="headextra">
|
||||
## OG (Open Graph) title and description added below to give social media info to display
|
||||
## (https://developers.facebook.com/docs/opengraph/howtos/maximizing-distribution-media-content#tags)
|
||||
<meta property="og:title" content="${course.display_name_with_default_escaped}" />
|
||||
<meta property="og:description" content="${get_course_about_section(request, course, 'short_description')}" />
|
||||
</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
## CourseTalk widget js script
|
||||
% if show_coursetalk_widget:
|
||||
<script src="//d3q6qq2zt8nhwv.cloudfront.net/s/js/widgets/coursetalk-read-reviews.js"></script>
|
||||
% endif
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
$(".register").click(function(event) {
|
||||
$("#class_enroll_form").submit();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
% if can_add_course_to_cart:
|
||||
add_course_complete_handler = function(jqXHR, textStatus) {
|
||||
if (jqXHR.status == 200) {
|
||||
location.href = "${cart_link}";
|
||||
}
|
||||
if (jqXHR.status == 400) {
|
||||
$("#register_error")
|
||||
.html(jqXHR.responseText ? jqXHR.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
.css("display", "block");
|
||||
}
|
||||
else if (jqXHR.status == 403) {
|
||||
location.href = "${reg_then_add_to_cart_link}";
|
||||
}
|
||||
};
|
||||
|
||||
$("#add_to_cart_post").click(function(event){
|
||||
$.ajax({
|
||||
url: "${reverse('add_course_to_cart', args=[course.id.to_deprecated_string()])}",
|
||||
type: "POST",
|
||||
/* Rant: HAD TO USE COMPLETE B/C PROMISE.DONE FOR SOME REASON DOES NOT WORK ON THIS PAGE. */
|
||||
complete: add_course_complete_handler
|
||||
})
|
||||
event.preventDefault();
|
||||
});
|
||||
% endif
|
||||
|
||||
## making the conditional around this entire JS block for sanity
|
||||
%if settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
|
||||
<%
|
||||
perms_error = _('The currently logged-in user account does not have permission to enroll in this course. '
|
||||
'You may need to {start_logout_tag}log out{end_tag} then try the enroll button again. '
|
||||
'Please visit the {start_help_tag}help page{end_tag} for a possible solution.').format(
|
||||
start_help_tag="<a href='{url}'>".format(url=marketing_link('FAQ')), end_tag='</a>',
|
||||
start_logout_tag="<a href='{url}'>".format(url=reverse('logout'))
|
||||
)
|
||||
%>
|
||||
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
|
||||
if(xhr.status == 200) {
|
||||
location.href = "${reverse('dashboard')}";
|
||||
} else if (xhr.status == 403) {
|
||||
location.href = "${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}?course_id=${course.id | u}&enrollment_action=enroll";
|
||||
} else if (xhr.status == 400) { //This means the user did not have permission
|
||||
$('#register_error').html("${perms_error}").css("display", "block");
|
||||
} else {
|
||||
$('#register_error').html(
|
||||
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
).css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
%else:
|
||||
|
||||
$('#class_enroll_form').on('ajax:complete', function(event, xhr) {
|
||||
if(xhr.status == 200) {
|
||||
if (xhr.responseText == "") {
|
||||
location.href = "${reverse('dashboard')}";
|
||||
}
|
||||
else {
|
||||
location.href = xhr.responseText;
|
||||
}
|
||||
} else if (xhr.status == 403) {
|
||||
location.href = "${reverse('register_user')}?course_id=${course.id | u}&enrollment_action=enroll";
|
||||
} else {
|
||||
$('#register_error').html(
|
||||
(xhr.responseText ? xhr.responseText : "${_("An error occurred. Please try again later.")}")
|
||||
).css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
%endif
|
||||
|
||||
})(this)
|
||||
</script>
|
||||
|
||||
<script src="${static.url('js/course_info.js')}"></script>
|
||||
</%block>
|
||||
|
||||
<%block name="pagetitle">${course.display_name_with_default_escaped}</%block>
|
||||
|
||||
<section class="course-info">
|
||||
<header class="course-profile">
|
||||
<div class="intro-inner-wrapper">
|
||||
<div class="table">
|
||||
<section class="intro">
|
||||
<div class="heading-group">
|
||||
<h1>
|
||||
${course.display_name_with_default_escaped}
|
||||
<a href="#">${course.display_org_with_default | h}</a>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="main-cta">
|
||||
%if user.is_authenticated() and registered:
|
||||
%if show_courseware_link:
|
||||
<a href="${course_target}">
|
||||
%endif
|
||||
|
||||
<span class="register disabled">${_("You are enrolled in this course")}</span>
|
||||
|
||||
%if show_courseware_link:
|
||||
<strong>${_("View Course")}</strong>
|
||||
</a>
|
||||
%endif
|
||||
|
||||
%elif in_cart:
|
||||
<span class="add-to-cart">
|
||||
${_('This course is in your <a href="{cart_link}">cart</a>.').format(cart_link=cart_link)}
|
||||
</span>
|
||||
% elif is_course_full:
|
||||
<span class="register disabled">
|
||||
${_("Course is full")}
|
||||
</span>
|
||||
% elif invitation_only and not can_enroll:
|
||||
<span class="register disabled">${_("Enrollment in this course is by invitation only")}</span>
|
||||
## Shib courses need the enrollment button to be displayed even when can_enroll is False,
|
||||
## because AnonymousUsers cause can_enroll for shib courses to be False, but we need them to be able to click
|
||||
## so that they can register and become a real user that can enroll.
|
||||
% elif not is_shib_course and not can_enroll:
|
||||
<span class="register disabled">${_("Enrollment is Closed")}</span>
|
||||
%elif can_add_course_to_cart:
|
||||
<%
|
||||
if user.is_authenticated():
|
||||
reg_href = "#"
|
||||
reg_element_id = "add_to_cart_post"
|
||||
else:
|
||||
reg_href = reg_then_add_to_cart_link
|
||||
reg_element_id = "reg_then_add_to_cart"
|
||||
%>
|
||||
<% if ecommerce_checkout:
|
||||
reg_href = ecommerce_checkout_link
|
||||
reg_element_id = ""
|
||||
%>
|
||||
<a href="${reg_href}" class="add-to-cart" id="${reg_element_id}">
|
||||
${_("Add {course_name} to Cart <span>({price} USD)</span>")\
|
||||
.format(course_name=course.display_number_with_default, price=course_price)}
|
||||
</a>
|
||||
<div id="register_error"></div>
|
||||
%else:
|
||||
<%
|
||||
if ecommerce_checkout:
|
||||
reg_href = ecommerce_checkout_link
|
||||
else:
|
||||
reg_href="#"
|
||||
if professional_mode:
|
||||
href_class = "add-to-cart"
|
||||
else:
|
||||
href_class = "register"
|
||||
%>
|
||||
<a href="${reg_href}" class="${href_class}">
|
||||
${_("Enroll in {course_name}").format(course_name=course.display_number_with_default) | h}
|
||||
</a>
|
||||
<div id="register_error"></div>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
</section>
|
||||
% if get_course_about_section(request, course, "video"):
|
||||
<a href="#video-modal" class="media" rel="leanModal">
|
||||
<div class="hero">
|
||||
<img src="${course_image_urls['large']}" alt="" />
|
||||
<div class="play-intro"></div>
|
||||
</div>
|
||||
</a>
|
||||
%else:
|
||||
<div class="media">
|
||||
<div class="hero">
|
||||
<img src="${course_image_urls['large']}" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<div class="details">
|
||||
% if staff_access and studio_url is not None:
|
||||
<div class="wrap-instructor-info studio-view">
|
||||
<a class="instructor-info-action" href="${studio_url}">${_("View About Page in studio")}</a>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<div class="inner-wrapper">
|
||||
${get_course_about_section(request, course, "overview")}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="course-sidebar">
|
||||
<div class="course-summary">
|
||||
|
||||
<%include file="course_about_sidebar_header.html" />
|
||||
|
||||
<ol class="important-dates">
|
||||
<li class="important-dates-item"><span class="icon fa fa-info-circle" aria-hidden="true"></span><p class="important-dates-item-title">${_("Course Number")}</p><span class="important-dates-item-text course-number">${course.display_number_with_default | h}</span></li>
|
||||
% if not course.self_paced:
|
||||
% if not course.start_date_is_still_default:
|
||||
<li class="important-dates-item"><span class="icon fa fa-calendar" aria-hidden="true"></span><p class="important-dates-item-title">${_("Classes Start")}</p><span class="important-dates-item-text start-date">${course.start_datetime_text()}</span></li>
|
||||
% endif
|
||||
## We plan to ditch end_date (which is not stored in course metadata),
|
||||
## but for backwards compatibility, show about/end_date blob if it exists.
|
||||
% if get_course_about_section(request, course, "end_date") or course.end:
|
||||
<li class="important-dates-item">
|
||||
<span class="icon fa fa-calendar" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Classes End")}</p>
|
||||
<span class="important-dates-item-text final-date">
|
||||
% if get_course_about_section(request, course, "end_date"):
|
||||
${get_course_about_section(request, course, "end_date")}
|
||||
% else:
|
||||
${course.end_datetime_text()}
|
||||
% endif
|
||||
</span>
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
% if course.self_paced:
|
||||
<li class="important-dates-item"><i class="icon fa fa-info-circle"></i><p class="important-dates-item-title">${_("Course Mode")}</p><span class="important-dates-item-text start-date">Self-Paced</span></li>
|
||||
% endif
|
||||
% if get_course_about_section(request, course, "effort"):
|
||||
<li class="important-dates-item"><span class="icon fa fa-pencil" aria-hidden="true"></span><p class="important-dates-item-title">${_("Estimated Effort")}</p><span class="important-dates-item-text effort">${get_course_about_section(request, course, "effort")}</span></li>
|
||||
% endif
|
||||
|
||||
##<li class="important-dates-item"><span class="icon fa fa-clock-o" aria-hidden="true"></span><p class="important-dates-item-title">${_('Course Length')}</p><span class="important-dates-item-text course-length">${_('{number} weeks').format(number=15)}</span></li>
|
||||
|
||||
%if course_price and (can_add_course_to_cart or is_cosmetic_price_enabled):
|
||||
<li class="important-dates-item">
|
||||
<span class="icon fa fa-money" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Price")}</p>
|
||||
<span class="important-dates-item-text">${course_price}</span>
|
||||
</li>
|
||||
%endif
|
||||
|
||||
% if pre_requisite_courses:
|
||||
<% prc_target = reverse('about_course', args=[unicode(pre_requisite_courses[0]['key'])]) %>
|
||||
<li class="prerequisite-course important-dates-item">
|
||||
<span class="icon fa fa-list-ul" aria-hidden="true"></span>
|
||||
<p class="important-dates-item-title">${_("Prerequisites")}</p>
|
||||
## Multiple pre-requisite courses are not supported on frontend that's why we are pulling first element
|
||||
<span class="important-dates-item-text pre-requisite"><a href="${prc_target}">${pre_requisite_courses[0]['display']}</a></span>
|
||||
<p class="tip">
|
||||
${_("You must successfully complete {link_start}{prc_display}{link_end} before you begin this course.").format(
|
||||
link_start='<a href="{}">'.format(prc_target),
|
||||
link_end='</a>',
|
||||
prc_display=pre_requisite_courses[0]['display'],
|
||||
)}
|
||||
</p>
|
||||
</li>
|
||||
% endif
|
||||
% if get_course_about_section(request, course, "prerequisites"):
|
||||
<li class="important-dates-item"><span class="icon fa fa-book" aria-hidden="true"></span><p class="important-dates-item-title">${_("Requirements")}</p><span class="important-dates-item-text prerequisites">${get_course_about_section(request, course, "prerequisites")}</span></li>
|
||||
% endif
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
## CourseTalk widget
|
||||
% if show_coursetalk_widget:
|
||||
<div class="coursetalk-read-reviews">
|
||||
<div id="ct-custom-read-review-widget" data-provider="${platform_key}" data-course="${course_review_key}"></div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
## For now, ocw links are the only thing that goes in additional resources
|
||||
% if get_course_about_section(request, course, "ocw_links"):
|
||||
<div class="additional-resources">
|
||||
<header>
|
||||
<h1>${_("Additional Resources")}</h1>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
## "MITOpenCourseware" should *not* be translated
|
||||
<h2 class="opencourseware">MITOpenCourseware</h2>
|
||||
${get_course_about_section(request, course, "ocw_links")}
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Need to put this hidden form on the page so that the registration button works.
|
||||
## Since it's no harm to display a hidden form, we display it with the most permissive conditional
|
||||
## which is when the student is not registered.
|
||||
%if active_reg_button or is_shib_course:
|
||||
<div style="display: none;">
|
||||
<form id="class_enroll_form" method="post" data-remote="true" action="${reverse('change_enrollment')}">
|
||||
<fieldset class="enroll_fieldset">
|
||||
<legend class="sr">${_("Enroll")}</legend>
|
||||
<input name="course_id" type="hidden" value="${course.id | h}">
|
||||
<input name="enrollment_action" type="hidden" value="enroll">
|
||||
</fieldset>
|
||||
<div class="submit">
|
||||
<input name="submit" type="submit" value="${_('enroll')}">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
%endif
|
||||
|
||||
<%include file="../video_modal.html" />
|
|
@ -0,0 +1,150 @@
|
|||
<%page expression_filter="h"/>
|
||||
<%inherit file="../main.html" />
|
||||
<%def name="online_help_token()"><% return "courseinfo" %></%def>
|
||||
<%namespace name='static' file='../static_content.html'/>
|
||||
<%!
|
||||
from datetime import datetime
|
||||
from pytz import timezone, utc
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from courseware.courses import get_course_info_section, get_course_date_blocks
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
%>
|
||||
|
||||
<%block name="pagetitle">${_("{course_number} Course Info").format(course_number=course.display_number_with_default)}</%block>
|
||||
|
||||
<%block name="headextra">
|
||||
<%static:css group='style-course-vendor'/>
|
||||
<%static:css group='style-course'/>
|
||||
</%block>
|
||||
|
||||
% if show_enroll_banner:
|
||||
<div class="wrapper-msg urgency-low" id="failed-verification-banner">
|
||||
<div class="msg msg-reverify is-dismissable">
|
||||
<div class="msg-content">
|
||||
<h2 class="title">${_("You are not enrolled yet")}</h2>
|
||||
<div class="copy">
|
||||
<p class='enroll-message'>
|
||||
${Text(_("You are not currently enrolled in this course. {link_start}Sign up now!{link_end}")).format(
|
||||
link_start=HTML("<a href={}>").format(url_to_enroll),
|
||||
link_end=HTML("</a>")
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<%include file="/courseware/course_navigation.html" args="active_page='info'" />
|
||||
|
||||
<%static:require_module_async module_name="js/courseware/toggle_element_visibility" class_name="ToggleElementVisibility">
|
||||
ToggleElementVisibility();
|
||||
</%static:require_module_async>
|
||||
<%static:require_module_async module_name="js/courseware/course_home_events" class_name="CourseHomeEvents">
|
||||
CourseHomeEvents();
|
||||
</%static:require_module_async>
|
||||
|
||||
<%block name="js_extra">
|
||||
## CourseTalk widget js script
|
||||
% if show_coursetalk_widget:
|
||||
<script src="//d3q6qq2zt8nhwv.cloudfront.net/s/js/widgets/coursetalk-write-reviews.js"></script>
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
<%block name="bodyclass">view-in-course view-course-info ${course.css_class or ''}</%block>
|
||||
|
||||
<main id="main" aria-label="Content" tabindex="-1">
|
||||
<div class="container">
|
||||
<div class="home">
|
||||
<div class="page-header-main">
|
||||
<h3 class="page-title">${_("Welcome to {org}'s {course_name}!").format(org=course.display_org_with_default, course_name=course.display_number_with_default)}
|
||||
<div class="page-subtitle">${course.display_name_with_default}</div>
|
||||
</h3>
|
||||
</div>
|
||||
% if last_accessed_courseware_url:
|
||||
<div class="page-header-secondary">
|
||||
<a href="${last_accessed_courseware_url}" class="last-accessed-link">${_("Resume Course")}</a>
|
||||
</div>
|
||||
% endif
|
||||
</div>
|
||||
<div class="info-wrapper">
|
||||
% if user.is_authenticated():
|
||||
<section class="updates">
|
||||
% if studio_url is not None and masquerade and masquerade.role == 'staff':
|
||||
<div class="wrap-instructor-info studio-view">
|
||||
<a class="instructor-info-action" href="${studio_url}">
|
||||
${_("View Updates in Studio")}
|
||||
</a>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<h4>${_("Course Updates and News")}</h4>
|
||||
${HTML(get_course_info_section(request, masquerade_user, course, 'updates'))}
|
||||
|
||||
## CourseTalk widget
|
||||
% if show_coursetalk_widget:
|
||||
<div class="coursetalk-write-reviews">
|
||||
<div id="ct-custom-read-review-widget" data-provider="${platform_key}" data-course="${course_review_key}"></div>
|
||||
</div>
|
||||
% endif
|
||||
</section>
|
||||
|
||||
<section aria-label="${_('Handout Navigation')}" class="handouts">
|
||||
|
||||
% if SelfPacedConfiguration.current().enable_course_home_improvements:
|
||||
<h4 class="handouts-header">${_("Important Course Dates")}</h4>
|
||||
## Should be organized by date, last date appearing at the bottom
|
||||
|
||||
% for course_date in get_course_date_blocks(course, user):
|
||||
<div class="date-summary-container">
|
||||
<div class="date-summary date-summary-${course_date.css_class}">
|
||||
% if course_date.title:
|
||||
% if course_date.title == 'current_datetime':
|
||||
<h3 class="heading localized-datetime" data-datetime="${course_date.date}" data-string="${_(u'Today is {date}')}" data-timezone="${user_timezone}" data-language="${user_language}"></h3>
|
||||
% else:
|
||||
<h3 class="heading">${course_date.title}</h3>
|
||||
% endif
|
||||
% endif
|
||||
% if course_date.date and course_date.title != 'current_datetime':
|
||||
<h4 class="date localized-datetime" data-format="shortDate" data-datetime="${course_date.date}" data-timezone="${user_timezone}" data-language="${user_language}" data-string="${_(course_date.relative_datestring)}"></h4>
|
||||
% endif
|
||||
% if course_date.description:
|
||||
<p class="description">${course_date.description}</p>
|
||||
% endif
|
||||
% if course_date.link and course_date.link_text:
|
||||
<span class="date-summary-link">
|
||||
<a href="${course_date.link}">${course_date.link_text}</a>
|
||||
</span>
|
||||
% endif
|
||||
</div>
|
||||
</div>
|
||||
% endfor
|
||||
% endif
|
||||
% if course.self_paced:
|
||||
<h3>${_("Course run end date")}</h3>
|
||||
<b>${course.end_datetime_text()}</b><br>
|
||||
<br>After this date, the course will be archived. If you enrolled in the course before the run end date, you can still access the course content.<br>
|
||||
% endif
|
||||
<h4 class="handouts-header">${_(course.info_sidebar_name)}</h4>
|
||||
${HTML(get_course_info_section(request, masquerade_user, course, 'handouts'))}
|
||||
</section>
|
||||
% else:
|
||||
<section class="updates">
|
||||
<h4 class="handouts-header">${_("Course Updates and News")}</h4>
|
||||
${HTML(get_course_info_section(request, masquerade_user, course, 'guest_updates'))}
|
||||
</section>
|
||||
<section aria-label="${_('Handout Navigation')}" class="handouts">
|
||||
<h4 class="handouts-header">${_("Course Handouts")}</h4>
|
||||
${HTML(get_course_info_section(request, masquerade_user, course, 'guest_handouts'))}
|
||||
</section>
|
||||
% endif <!-- if course authenticated -->
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<%static:require_module_async module_name="js/dateutil_factory" class_name="DateUtilFactory">
|
||||
DateUtilFactory.transform(iterationKey=".localized-datetime");
|
||||
</%static:require_module_async>
|
|
@ -0,0 +1,15 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Welcome to {course_name}").format(course_name=course.display_name_with_default_escaped)}
|
||||
|
||||
${_("To get started, please visit https://{site_name}. The login information for your account follows.").format(site_name=site_name)}
|
||||
|
||||
${_("email: {email}").format(email=email_address)}
|
||||
${_("password: {password}").format(password=password)}
|
||||
|
||||
${_("It is recommended that you change your password.")}
|
||||
|
||||
${_("Sincerely yours,"
|
||||
""
|
||||
"The {course_name} Team").format(course_name=course.display_name_with_default_escaped)}
|
|
@ -0,0 +1,24 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<%! from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers %>
|
||||
${_("Thank you for creating an account with {platform_name}!").format(
|
||||
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME)
|
||||
)}
|
||||
|
||||
${_("There's just one more step before you can enroll in a course: "
|
||||
"you need to activate your {platform_name} account. To activate "
|
||||
"your account, click the following link. If that doesn't work, "
|
||||
"copy and paste the link into your browser's address bar.").format(
|
||||
platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME)
|
||||
)}
|
||||
|
||||
% if is_secure:
|
||||
https://${ site }/activate/${ key }
|
||||
% else:
|
||||
http://${ site }/activate/${ key }
|
||||
% endif
|
||||
|
||||
${_("If you didn't create an account, you don't need to do anything; you "
|
||||
"won't receive any more email from us. If you need assistance, please "
|
||||
"do not reply to this email message. Check the help section of the "
|
||||
"{platform_name} website.").format(platform_name=configuration_helpers.get_value('PLATFORM_NAME', settings.PLATFORM_NAME))}
|
|
@ -0,0 +1,26 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear {full_name}").format(full_name=full_name)}
|
||||
|
||||
${_("You have been invited to be a beta tester for {course_name} at {site_name} by a "
|
||||
"member of the course staff.").format(
|
||||
course_name=course.display_name_with_default_escaped,
|
||||
site_name=site_name
|
||||
)}
|
||||
|
||||
% if auto_enroll:
|
||||
${_("To start accessing course materials, please visit {course_url}").format(
|
||||
course_url=course_url
|
||||
)}
|
||||
% elif course_about_url is not None:
|
||||
${_("Visit {course_about_url} to join the course and begin the beta test.").format(course_about_url=course_about_url)}
|
||||
% else:
|
||||
${_("Visit {site_name} to enroll in the course and begin the beta test.").format(site_name=site_name)}
|
||||
% endif
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} to "
|
||||
"{email_address}").format(
|
||||
site_name=site_name, email_address=email_address
|
||||
)}
|
|
@ -0,0 +1,44 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear student,")}
|
||||
|
||||
${_("You have been invited to join {course_name} at {site_name} by a "
|
||||
"member of the course staff.").format(
|
||||
course_name=display_name or course.display_name_with_default_escaped,
|
||||
site_name=site_name
|
||||
)}
|
||||
% if is_shib_course:
|
||||
% if auto_enroll:
|
||||
|
||||
${_("To access the course visit {course_url} and login.").format(course_url=course_url)}
|
||||
% elif course_about_url is not None:
|
||||
|
||||
${_("To access the course visit {course_about_url} and register for the course.").format(
|
||||
course_about_url=course_about_url)}
|
||||
% endif
|
||||
% else:
|
||||
|
||||
${_("To finish your registration, please visit {registration_url} and fill "
|
||||
"out the registration form making sure to use {email_address} in the E-mail field.").format(
|
||||
registration_url=registration_url,
|
||||
email_address=email_address
|
||||
)}
|
||||
% if auto_enroll:
|
||||
${_("Once you have registered and activated your account, you will see "
|
||||
"{course_name} listed on your dashboard.").format(
|
||||
course_name=display_name or course.display_name_with_default_escaped
|
||||
)}
|
||||
% elif course_about_url is not None:
|
||||
${_("Once you have registered and activated your account, visit {course_about_url} "
|
||||
"to join the course.").format(course_about_url=course_about_url)}
|
||||
% else:
|
||||
${_("You can then enroll in {course_name}.").format(course_name=display_name or course.display_name_with_default_escaped)}
|
||||
% endif
|
||||
% endif
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} to "
|
||||
"{email_address}").format(
|
||||
site_name=site_name, email_address=email_address
|
||||
)}
|
|
@ -0,0 +1,21 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear {full_name}").format(full_name=full_name)}
|
||||
|
||||
${_("You have been enrolled in {course_name} at {site_name} by a member "
|
||||
"of the course staff. The course should now appear on your {site_name} "
|
||||
"dashboard.").format(
|
||||
course_name=display_name or course.display_name_with_default_escaped,
|
||||
site_name=site_name
|
||||
)}
|
||||
|
||||
${_("To start accessing course materials, please visit {course_url}").format(
|
||||
course_url=course_url
|
||||
)}
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} to "
|
||||
"{full_name}").format(
|
||||
site_name=site_name, full_name=full_name
|
||||
)}
|
|
@ -0,0 +1,19 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear {full_name}").format(full_name=full_name)}
|
||||
|
||||
${_("You have been removed as a beta tester for {course_name} at {site_name} by a "
|
||||
"member of the course staff. The course will remain on your dashboard, but "
|
||||
"you will no longer be part of the beta testing group.").format(
|
||||
course_name=course.display_name_with_default_escaped,
|
||||
site_name=site_name
|
||||
)}
|
||||
|
||||
${_("Your other courses have not been affected.")}
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} to "
|
||||
"{email_address}").format(
|
||||
site_name=site_name, email_address=email_address
|
||||
)}
|
|
@ -0,0 +1,14 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear Student,")}
|
||||
|
||||
${_("You have been un-enrolled from course {course_name} by a member "
|
||||
"of the course staff. Please disregard the invitation "
|
||||
"previously sent.").format(course_name=display_name or course.display_name_with_default_escaped)}
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} "
|
||||
"to {email_address}").format(
|
||||
site_name=site_name, email_address=email_address
|
||||
)}
|
|
@ -0,0 +1,18 @@
|
|||
<%inherit file="../rex_email_footer.html"/>
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
|
||||
${_("Dear {full_name}").format(full_name=full_name)}
|
||||
|
||||
${_("You have been un-enrolled in {course_name} at {site_name} by a member "
|
||||
"of the course staff. The course will no longer appear on your "
|
||||
"{site_name} dashboard.").format(
|
||||
course_name=display_name or course.display_name_with_default_escaped, site_name=site_name
|
||||
)}
|
||||
|
||||
${_("Your other courses have not been affected.")}
|
||||
|
||||
----
|
||||
${_("This email was automatically sent from {site_name} to "
|
||||
"{full_name}").format(
|
||||
full_name=full_name, site_name=site_name
|
||||
)}
|
|
@ -0,0 +1,44 @@
|
|||
## mako
|
||||
<%page expression_filter="h"/>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from branding.api import get_footer
|
||||
%>
|
||||
<% footer = get_footer(is_secure=is_secure) %>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
from datetime import date
|
||||
%>
|
||||
<div class="wrapper wrapper-footer">
|
||||
<footer>
|
||||
<div class="colophon" style="width:auto">
|
||||
<nav class="nav-colophon">
|
||||
<ol>
|
||||
<li>
|
||||
© ${_(' {year} Microsoft').format( year=date.today().year)}
|
||||
</li>
|
||||
<li><a href="https://www.microsoft.com/en-us/privacystatement/default.aspx" target="_blank">Privacy & Cookies</a></li>
|
||||
<li><a href="${reverse('tos')}" target="_blank">Terms of Service</a></li>
|
||||
<li><a href="https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/en-us.aspx" target="_blank">Trademarks</a></li>
|
||||
<li><a href="/faq" target="_blank">Support</a></li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="references" style="width:auto" >
|
||||
<a href="https://open.edx.org/" target="_blank"><img class="iconDetails" src="https://files.edx.org/openedx-logos/edx-openedx-logo-tag.png" width="160" alt="Powered by Open edX" style="vertical-align:bottom"></a>
|
||||
<a href="https://azure.microsoft.com" target="_blank"><img src="/static/comprehensive/images/azure_logo.png"alt="on Microsoft Azure" style="vertical-align:bottom" width="160" height="28"></a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
% if include_dependencies:
|
||||
<%static:js group='base_vendor'/>
|
||||
<%static:css group='style-vendor'/>
|
||||
<%include file="widgets/segment-io.html" />
|
||||
<%include file="widgets/segment-io-footer.html" />
|
||||
% endif
|
||||
% if footer_css_urls:
|
||||
% for url in footer_css_urls:
|
||||
<link rel="stylesheet" type="text/css" href="${url}"></link>
|
||||
% endfor
|
||||
% endif
|
|
@ -0,0 +1,97 @@
|
|||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
%>
|
||||
|
||||
<section id="forgot-password-modal" class="modal" role="dialog" tabindex="-1" aria-label="${_('Password Reset')}">
|
||||
<div class="inner-wrapper">
|
||||
<button class="close-modal">
|
||||
<span class="icon fa fa-remove" aria-hidden="true"></span>
|
||||
<span class="sr">
|
||||
## Translators: this is a control to allow users to exit out of this modal interface (a menu or piece of UI that takes the full focus of the screen)
|
||||
${_('Close')}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<div id="password-reset">
|
||||
<header>
|
||||
<h2>${_("Password Reset")}</h2>
|
||||
</header>
|
||||
|
||||
<div class="instructions">
|
||||
<p>${_("Please enter your e-mail address below, and we will e-mail instructions for setting a new password.")}</p>
|
||||
</div>
|
||||
|
||||
<form id="pwd_reset_form" action="${reverse('password_reset')}" method="post" data-remote="true">
|
||||
<fieldset class="group group-form group-form-requiredinformation">
|
||||
<legend class="is-hidden">${_("Required Information")}</legend>
|
||||
|
||||
<ol class="list-input">
|
||||
<li class="field required text" id="forgot-password-modal-field-email">
|
||||
<label for="pwd_reset_email">${_("Your E-mail Address")}</label>
|
||||
<input class="" id="pwd_reset_email" type="email" name="email" value="" placeholder="example: username@domain.com" aria-describedby="pwd_reset_email-tip" aria-required="true" required />
|
||||
<span class="tip tip-input" id="pwd_reset_email-tip">${_("This is the e-mail address you used to register with {platform}").format(platform=static.get_platform_name())}</span>
|
||||
</li>
|
||||
</ol>
|
||||
</fieldset>
|
||||
|
||||
<div class="form-actions">
|
||||
<button name="submit" type="submit" id="pwd_reset_button" class="action action-primary action-update">${_("Reset My Password")}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function() {
|
||||
$(document).delegate('#pwd_reset_form', 'ajax:success', function(data, json, xhr) {
|
||||
if(json.success) {
|
||||
$("#password-reset").html(json.value);
|
||||
} else {
|
||||
if($('#pwd_error').length == 0) {
|
||||
$('#pwd_reset_form').prepend('<div id="pwd_error" class="modal-form-error">${_("Email is incorrect.")}</div>');
|
||||
}
|
||||
$('#pwd_error').stop().css("display", "block");
|
||||
}
|
||||
});
|
||||
|
||||
// removing close link's default behavior
|
||||
$('#login-modal .close-modal').click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var onModalClose = function() {
|
||||
$("#forgot-password-modal").attr("aria-hidden", "true");
|
||||
$("#forgot-password-link").focus();
|
||||
};
|
||||
|
||||
var cycle_modal_tab = function(from_element_name, to_element_name) {
|
||||
$(from_element_name).on('keydown', function(e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
var TAB_KEY = 9; // 9 corresponds to the tab key
|
||||
if (keyCode === TAB_KEY) {
|
||||
e.preventDefault();
|
||||
$(to_element_name).focus();
|
||||
}
|
||||
});
|
||||
};
|
||||
$("#forgot-password-modal .close-modal").click(onModalClose);
|
||||
cycle_modal_tab("#forgot-password-modal .close-modal", "#pwd_reset_email");
|
||||
cycle_modal_tab("#pwd_reset_email", "#pwd_reset_button");
|
||||
cycle_modal_tab("#pwd_reset_button", "#forgot-password-modal .close-modal");
|
||||
|
||||
// Hitting the ESC key will exit the modal
|
||||
$("#forgot-password-modal").on("keydown", function(e) {
|
||||
var keyCode = e.keyCode || e.which;
|
||||
// 27 is the ESC key
|
||||
if (keyCode === 27) {
|
||||
e.preventDefault();
|
||||
$("#forgot-password-modal .close-modal").click();
|
||||
}
|
||||
});
|
||||
|
||||
})(this)
|
||||
</script>
|
|
@ -0,0 +1,80 @@
|
|||
<%page expression_filter="h"/>
|
||||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%!
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
%>
|
||||
|
||||
<main id="main" aria-label="Content" tabindex="-1">
|
||||
<section class="home">
|
||||
<header>
|
||||
<div class="outer-wrapper">
|
||||
<div class="title">
|
||||
<div class="heading-group">
|
||||
% if homepage_overlay_html:
|
||||
${homepage_overlay_html | n, decode.utf8}
|
||||
% else:
|
||||
## Translators: 'Open edX' is a registered trademark, please keep this untranslated. See http://open.edx.org for more information.
|
||||
<h1>${_("Welcome to Microsoft Learning!")}</h1>
|
||||
## Translators: 'Open edX' is a registered trademark, please keep this untranslated. See http://open.edx.org for more information.
|
||||
<h2>${_("Learn. Engage. Achieve.")}</h2>
|
||||
% endif
|
||||
</div>
|
||||
% if settings.FEATURES.get('ENABLE_COURSE_DISCOVERY'):
|
||||
<div class="course-search">
|
||||
<form method="get" action="/courses">
|
||||
<label><span class="sr">${_("Search for a course")}</span>
|
||||
<input class="search-input" name="search_query" type="text" placeholder="${_("Search for a course")}"></input>
|
||||
</label>
|
||||
<button class="search-button" type="submit">
|
||||
<span class="icon fa fa-search" aria-hidden="true"></span><span class="sr">${_("Search")}</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
</div>
|
||||
|
||||
% if show_homepage_promo_video:
|
||||
<a href="#video-modal" class="media" rel="leanModal">
|
||||
<div class="hero">
|
||||
<div class="play-intro"></div>
|
||||
</div>
|
||||
</a>
|
||||
% endif
|
||||
</div>
|
||||
|
||||
</header>
|
||||
<%include file="${courses_list}" />
|
||||
|
||||
</section>
|
||||
</main>
|
||||
|
||||
% if show_homepage_promo_video:
|
||||
<section id="video-modal" class="modal home-page-video-modal video-modal">
|
||||
<div class="inner-wrapper">
|
||||
<iframe title="YouTube Video" width="640" height="360" src="//www.youtube.com/embed/${homepage_promo_video_youtube_id}?showinfo=0" frameborder="0" allowfullscreen></iframe>
|
||||
</div>
|
||||
</section>
|
||||
% endif
|
||||
|
||||
<%block name="js_extra">
|
||||
<script type="text/javascript">
|
||||
$(window).load(function() {
|
||||
if(getParameterByName('next')) {
|
||||
$('#login').trigger("click");
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
% if show_signup_immediately is not UNDEFINED:
|
||||
## NOTE: This won't work in production, because anonymous views are cached, so it will
|
||||
## show either with or without this extra js for 3 minutes at a time.
|
||||
<script type="text/javascript">
|
||||
$(window).load(function() {$('#signup_action').trigger("click");});
|
||||
</script>
|
||||
% endif
|
|
@ -0,0 +1,249 @@
|
|||
<%inherit file="main.html" />
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
import third_party_auth
|
||||
from third_party_auth import provider, pipeline
|
||||
%>
|
||||
|
||||
<%block name="pagetitle">${_("Sign into your {platform_name} Account").format(platform_name=platform_name)}</%block>
|
||||
|
||||
<%block name="bodyclass">view-login</%block>
|
||||
|
||||
<%block name="js_extra">
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
|
||||
// adding js class for styling with accessibility in mind
|
||||
$('body').addClass('js');
|
||||
|
||||
// show forgot password modal UI if URL contains matching DOM ID
|
||||
if ($.deparam.fragment()['forgot-password-modal'] !== undefined) {
|
||||
$('.pwd-reset').click();
|
||||
}
|
||||
|
||||
// new window/tab opening
|
||||
$('a[rel="external"], a[class="new-vp"]')
|
||||
.click( function() {
|
||||
window.open( $(this).attr('href') );
|
||||
return false;
|
||||
});
|
||||
|
||||
// form field label styling on focus
|
||||
$("form :input").focus(function() {
|
||||
$("label[for='" + this.id + "']").parent().addClass("is-focused");
|
||||
}).blur(function() {
|
||||
$("label").parent().removeClass("is-focused");
|
||||
});
|
||||
|
||||
$("#email").focus();
|
||||
});
|
||||
|
||||
(function() {
|
||||
toggleSubmitButton(true);
|
||||
|
||||
$('#login-form').on('submit', function() {
|
||||
toggleSubmitButton(false);
|
||||
});
|
||||
|
||||
$('#login-form').on('ajax:error', function(event, request, status_string) {
|
||||
toggleSubmitButton(true);
|
||||
|
||||
if (request.status === 403) {
|
||||
$('.message.submission-error').removeClass('is-shown');
|
||||
$('.third-party-signin.message').addClass('is-shown').focus();
|
||||
$('.third-party-signin.message .instructions').html(request.responseText);
|
||||
} else {
|
||||
$('.third-party-signin.message').removeClass('is-shown');
|
||||
$('.message.submission-error').addClass('is-shown').focus();
|
||||
$('.message.submission-error').html(gettext("Your request could not be completed. Please try again."));
|
||||
}
|
||||
});
|
||||
|
||||
$('#login-form').on('ajax:success', function(event, json, xhr) {
|
||||
if(json.success) {
|
||||
var nextUrl = "${login_redirect_url}";
|
||||
if (json.redirect_url) {
|
||||
nextUrl = json.redirect_url; // Most likely third party auth completion. This trumps 'nextUrl' above.
|
||||
}
|
||||
if (!isExternal(nextUrl)) {
|
||||
location.href=nextUrl;
|
||||
} else {
|
||||
location.href="${reverse('dashboard')}";
|
||||
}
|
||||
} else if(json.hasOwnProperty('redirect')) {
|
||||
// Shibboleth authentication redirect requested by the server:
|
||||
var u=decodeURI(window.location.search);
|
||||
if (!isExternal(json.redirect)) { // a paranoid check. Our server is the one providing json.redirect
|
||||
location.href=json.redirect+u;
|
||||
} // else we just remain on this page, which is fine since this particular path implies a login failure
|
||||
// that has been generated via packet tampering (json.redirect has been messed with).
|
||||
} else {
|
||||
toggleSubmitButton(true);
|
||||
$('.message.submission-error').addClass('is-shown').focus();
|
||||
$('.message.submission-error .message-copy').html(json.value);
|
||||
}
|
||||
});
|
||||
$("#forgot-password-link").click(function() {
|
||||
$("#forgot-password-modal").show();
|
||||
$("#forgot-password-modal .close-modal").focus();
|
||||
});
|
||||
|
||||
})(this);
|
||||
|
||||
function toggleSubmitButton(enable) {
|
||||
var $submitButton = $('form .form-actions #submit');
|
||||
|
||||
if(enable) {
|
||||
$submitButton.
|
||||
removeClass('is-disabled').
|
||||
attr('aria-disabled', false).
|
||||
removeProp('disabled').
|
||||
html("${_('Sign into My {platform_name} Account').format(platform_name=platform_name)} <span class='orn-plus'>+</span> ${_('Access My Courses')}");
|
||||
}
|
||||
else {
|
||||
$submitButton.
|
||||
addClass('is-disabled').
|
||||
prop('disabled', true).
|
||||
text("${_(u'Processing your account information')}");
|
||||
}
|
||||
}
|
||||
|
||||
function thirdPartySignin(event, url) {
|
||||
event.preventDefault();
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
(function post_form_if_pipeline_running(pipeline_running) {
|
||||
// If the pipeline is running, the user has already authenticated via a
|
||||
// third-party provider. We want to invoke /login_ajax to loop in the
|
||||
// code that does logging and sets cookies on the request. It is most
|
||||
// consistent to do that by using the same mechanism that is used when
|
||||
// the use does first-party sign-in: POSTing the sign-in form.
|
||||
if (pipeline_running) {
|
||||
$('#login-form').submit();
|
||||
}
|
||||
})(${pipeline_running})
|
||||
</script>
|
||||
</%block>
|
||||
|
||||
<%include file="forgot_password_modal.html" />
|
||||
|
||||
<section class="introduction">
|
||||
<header>
|
||||
<h1 class="title">
|
||||
<span class="title-super">${_("Please sign in")}</span>
|
||||
<span class="title-sub">${_("to access your account and courses")}</span>
|
||||
</h1>
|
||||
</header>
|
||||
</section>
|
||||
|
||||
<section class="login container">
|
||||
<section role="main" class="content">
|
||||
<form role="form" id="login-form" method="post" data-remote="true" action="/login_ajax" novalidate>
|
||||
|
||||
<!-- status messages -->
|
||||
<div role="alert" class="status message">
|
||||
<h3 class="message-title">${_("We're Sorry, {platform_name} accounts are unavailable currently").format(platform_name=platform_name)}</h3>
|
||||
</div>
|
||||
|
||||
<div role="alert" class="status message submission-error" tabindex="-1">
|
||||
<h3 class="message-title">${_("We couldn't sign you in.")} </h3>
|
||||
<ul class="message-copy">
|
||||
<li>${_("Your email or password is incorrect")}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div role="alert" class="third-party-signin message" tabindex="-1">
|
||||
<p class="instructions"> </p>
|
||||
</div>
|
||||
|
||||
% if third_party_auth_error:
|
||||
<div role="alert" class="status message third-party-auth-error is-shown" tabindex="-1">
|
||||
<h3 class="message-title">${_("An error occurred when signing you in to {platform_name}.").format(platform_name=platform_name)} </h3>
|
||||
<ul class="message-copy">
|
||||
<li>${third_party_auth_error}</li>
|
||||
</ul>
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<p class="instructions sr">
|
||||
${_('Please provide the following information to sign into your {platform_name} account. Required fields are noted by <strong class="indicator">bold text and an asterisk (*)</strong>.').format(platform_name=platform_name)}
|
||||
</p>
|
||||
|
||||
<div class="group group-form group-form-requiredinformation">
|
||||
<h2 class="sr">${_('Required Information')}</h2>
|
||||
|
||||
<ol class="list-input">
|
||||
<li class="field required text" id="field-email">
|
||||
<label for="email">${_('E-mail')}</label>
|
||||
<input class="" id="email" type="email" name="email" value="" placeholder="${_('example: username@domain.com')}" required aria-required="true" aria-described-by="email-tip" />
|
||||
<span class="tip tip-input" id="email-tip">${_("This is the e-mail address you used to register with {platform}").format(platform=platform_name)}</span>
|
||||
</li>
|
||||
<li class="field required password" id="field-password">
|
||||
<label for="password">${_('Password')}</label>
|
||||
<input id="password" type="password" name="password" value="" required aria-required="true" />
|
||||
<span class="tip tip-input">
|
||||
<a href="#forgot-password-modal" rel="leanModal" class="pwd-reset action action-forgotpw" id="forgot-password-link" role="button" aria-haspopup="true">${_('Forgot password?')}</a>
|
||||
</span>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="group group-form group-form-secondary group-form-accountpreferences">
|
||||
<h2 class="sr">${_('Account Preferences')}</h2>
|
||||
|
||||
<ol class="list-input">
|
||||
<li class="field checkbox" id="field-remember">
|
||||
<input id="remember-yes" type="checkbox" name="remember" value="true" />
|
||||
<label for="remember-yes">${_('Remember me')}</label>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button name="submit" type="submit" id="submit" class="action action-primary action-update login-button"></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
% if third_party_auth.is_enabled():
|
||||
|
||||
<span class="deco-divider">
|
||||
## Developers: this is a sentence fragment, which is usually frowned upon. The design of the pags uses this fragment to provide an "else" clause underneath a number of choices. It's OK to leave it.
|
||||
## Translators: this is the last choice of a number of choices of how to log in to the site.
|
||||
<span class="copy">${_('or')}</span>
|
||||
</span>
|
||||
|
||||
<div class="form-actions form-third-party-auth">
|
||||
|
||||
% for enabled in provider.Registry.displayed_for_login():
|
||||
## Translators: provider_name is the name of an external, third-party user authentication provider (like Google or LinkedIn).
|
||||
<button type="submit" class="button button-primary button-${enabled.provider_id} login-${enabled.provider_id}" onclick="thirdPartySignin(event, '${pipeline_url[enabled.provider_id]}');">
|
||||
% if enabled.icon_class:
|
||||
<span class="icon fa ${enabled.icon_class}" aria-hidden="true"></span>
|
||||
% else:
|
||||
<span class="icon" aria-hidden="true"><img class="icon-image" src="${enabled.icon_image.url}" alt="${enabled.name} icon" /></span>
|
||||
% endif
|
||||
${_('Sign in with {provider_name}').format(provider_name=enabled.name)}
|
||||
</button>
|
||||
% endfor
|
||||
|
||||
</div>
|
||||
|
||||
% endif
|
||||
|
||||
</section>
|
||||
|
||||
<aside role="complementary">
|
||||
|
||||
<%
|
||||
# allow for theming overrides on the registration sidebars, otherwise default to pre-existing ones
|
||||
sidebar_file = static.get_template_path('login-sidebar.html')
|
||||
%>
|
||||
|
||||
<%include file="${sidebar_file}" />
|
||||
|
||||
</aside>
|
||||
</section>
|
|
@ -0,0 +1,228 @@
|
|||
## coding=utf-8
|
||||
|
||||
## This is the main Mako template that all page templates should include.
|
||||
## Note: there are a handful of pages that use Django Templates and which
|
||||
## instead include main_django.html. It is important that these two files
|
||||
## remain in sync, so changes made in one should be applied to the other.
|
||||
|
||||
## Pages currently use v1 styling by default. Once the Pattern Library
|
||||
## rollout has been completed, this default can be switched to v2.
|
||||
<%! main_css = "style-main-v1" %>
|
||||
|
||||
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<% online_help_token = self.online_help_token() if hasattr(self, 'online_help_token') else None %>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.http import urlquote_plus
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import get_language_bidi
|
||||
from branding import api as branding_api
|
||||
from pipeline_mako import render_require_js_path_overrides
|
||||
%>
|
||||
<!DOCTYPE html>
|
||||
<!--[if lte IE 9]><html class="ie ie9 lte9" lang="${LANGUAGE_CODE}"><![endif]-->
|
||||
<!--[if !IE]><!--><html lang="${LANGUAGE_CODE}"><!--<![endif]-->
|
||||
<head dir="${static.dir_rtl()}">
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
## Define a couple of helper functions to make life easier when
|
||||
## embedding theme conditionals into templates. All inheriting
|
||||
## templates have access to these functions, and we can import these
|
||||
## into non-inheriting templates via the %namespace tag.
|
||||
|
||||
## this needs to be here to prevent the title from mysteriously appearing in the body, in one case
|
||||
<%def name="pagetitle()" />
|
||||
<%block name="title">
|
||||
<title>
|
||||
${static.get_page_title_breadcrumbs(self.pagetitle())}
|
||||
</title>
|
||||
</%block>
|
||||
|
||||
% if not allow_iframing:
|
||||
<script type="text/javascript">
|
||||
/* Microsoft customization: Adding cookie related JS functions */
|
||||
function setCookie(cname, cvalue, exdays) {
|
||||
var d = new Date();
|
||||
d.setTime(d.getTime() + (exdays*24*60*60*1000));
|
||||
var expires = "expires="+d.toUTCString();
|
||||
document.cookie = cname + "=" + cvalue + "; " + expires;
|
||||
}
|
||||
function getCookie(cname) {
|
||||
var name = cname + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0; i<ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0)==' ') c = c.substring(1);
|
||||
if (c.indexOf(name) == 0) return c.substring(name.length,c.length);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
function closeCookieBanner() {
|
||||
var cookieContainer = document.getElementById("cookie-notice");
|
||||
if (cookieContainer) {
|
||||
cookieContainer.style.display = "none";
|
||||
}
|
||||
var navWrapper = document.getElementsByClassName("nav-wrapper");
|
||||
if (navWrapper.length > 0) {
|
||||
navWrapper[0].className = "nav-wrapper";
|
||||
}
|
||||
setCookie("cookie-banner","true",365);
|
||||
}
|
||||
|
||||
/* immediately break out of an iframe if coming from the marketing website */
|
||||
(function(window) {
|
||||
if (window.location !== window.top.location) {
|
||||
window.top.location = window.location;
|
||||
}
|
||||
})(this);
|
||||
</script>
|
||||
% endif
|
||||
|
||||
<%
|
||||
jsi18n_path = "js/i18n/{language}/djangojs.js".format(language=LANGUAGE_CODE)
|
||||
%>
|
||||
|
||||
<script type="text/javascript" src="${static.url(jsi18n_path)}"></script>
|
||||
|
||||
<link rel="icon" type="image/x-icon" href="${static.url(static.get_value('favicon_path', settings.FAVICON_PATH))}" />
|
||||
|
||||
<%static:css group='style-vendor'/>
|
||||
<%static:css group='${self.attr.main_css}'/>
|
||||
|
||||
% if not uses_pattern_library:
|
||||
% if disable_courseware_js:
|
||||
<%static:js group='base_vendor'/>
|
||||
<%static:js group='base_application'/>
|
||||
% else:
|
||||
<%static:js group='main_vendor'/>
|
||||
<%static:js group='application'/>
|
||||
% endif
|
||||
% else:
|
||||
## TODO: Update to only bring in RequireJS
|
||||
## https://openedx.atlassian.net/browse/FEDX-140
|
||||
<%static:js group='base_vendor'/>
|
||||
<%static:js group='base_application'/>
|
||||
% endif
|
||||
|
||||
<script>
|
||||
window.baseUrl = "${settings.STATIC_URL}";
|
||||
(function (require) {
|
||||
require.config({
|
||||
baseUrl: window.baseUrl
|
||||
});
|
||||
}).call(this, require || RequireJS.require);
|
||||
</script>
|
||||
<script type="text/javascript" src="${static.url("lms/js/require-config.js")}"></script>
|
||||
<%block name="js_overrides">
|
||||
${render_require_js_path_overrides(settings.REQUIRE_JS_PATH_OVERRIDES)}
|
||||
</%block>
|
||||
|
||||
% if not disable_courseware_js:
|
||||
<%static:js group='module-js'/>
|
||||
% endif
|
||||
|
||||
<%block name="headextra"/>
|
||||
|
||||
<%static:optional_include_mako file="head-extra.html" is_theming_enabled="True" />
|
||||
|
||||
<%include file="widgets/optimizely.html" />
|
||||
<%include file="widgets/segment-io.html" />
|
||||
|
||||
<meta name="path_prefix" content="${EDX_ROOT_URL}">
|
||||
<meta name="google-site-verification" content="_mipQ4AtZQDNmbtOkwehQDOgCxUUV2fb_C0b6wbiRHY" />
|
||||
|
||||
<% ga_acct = static.get_value("GOOGLE_ANALYTICS_ACCOUNT", settings.GOOGLE_ANALYTICS_ACCOUNT) %>
|
||||
% if ga_acct:
|
||||
<script type="text/javascript">
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', '${ga_acct}']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
})();
|
||||
</script>
|
||||
% endif
|
||||
|
||||
</head>
|
||||
|
||||
<body class="${static.dir_rtl()} <%block name='bodyclass'/> lang_${LANGUAGE_CODE}">
|
||||
|
||||
<%static:optional_include_mako file="body-initial.html" is_theming_enabled="True" />
|
||||
<div id="page-prompt"></div>
|
||||
% if not disable_window_wrap:
|
||||
<div class="window-wrap" dir="${static.dir_rtl()}">
|
||||
% endif
|
||||
<a class="nav-skip" href="#main">${_("Skip to main content")}</a>
|
||||
|
||||
% if not disable_header:
|
||||
<%include file="${static.get_template_path('header.html')}" args="online_help_token=online_help_token" />
|
||||
% endif
|
||||
|
||||
<div class="content-wrapper" id="content">
|
||||
${self.body()}
|
||||
<%block name="bodyextra"/>
|
||||
</div>
|
||||
|
||||
% if not disable_footer:
|
||||
<%include file="${static.get_template_path('footer.html')}" />
|
||||
% endif
|
||||
|
||||
% if not disable_window_wrap:
|
||||
</div>
|
||||
% endif
|
||||
|
||||
<%block name="js_extra"/>
|
||||
|
||||
<%include file="widgets/segment-io-footer.html" />
|
||||
<script type="text/javascript" src="${static.url('js/vendor/noreferrer.js')}" charset="utf-8"></script>
|
||||
<script type="text/javascript" src="${static.url('js/utils/navigation.js')}" charset="utf-8"></script>
|
||||
<script type="text/javascript">
|
||||
(function(a,b,c,d){
|
||||
a='//tags.tiqcdn.com/utag/msft/lex-openedx/prod/utag.js';
|
||||
b=document;c='script';d=b.createElement(c);d.src=a;d.type='text/java'+c;d.async=true;
|
||||
a=b.getElementsByTagName(c)[0];a.parentNode.insertBefore(d,a);
|
||||
})();
|
||||
</script>
|
||||
<%static:optional_include_mako file="body-extra.html" is_theming_enabled="True" />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<%def name="login_query()">${
|
||||
u"?next={0}".format(urlquote_plus(login_redirect_url)) if login_redirect_url else ""
|
||||
}</%def>
|
||||
|
||||
<!-- Performance beacon for onload times -->
|
||||
% if settings.FEATURES.get('ENABLE_ONLOAD_BEACON', False):
|
||||
<script>
|
||||
(function () {
|
||||
var sample_rate = ${settings.ONLOAD_BEACON_SAMPLE_RATE};
|
||||
var roll = Math.floor(Math.random() * 100)/100;
|
||||
var onloadBeaconSent = false;
|
||||
|
||||
if(roll < sample_rate){
|
||||
$(window).load(function() {
|
||||
setTimeout(function(){
|
||||
var t = window.performance.timing;
|
||||
|
||||
var data = {
|
||||
event: "onload",
|
||||
value: t.loadEventEnd - t.navigationStart,
|
||||
page: window.location.href,
|
||||
};
|
||||
|
||||
if (!onloadBeaconSent) {
|
||||
$.ajax({method: "POST", url: "/performance", data: data});
|
||||
}
|
||||
onloadBeaconSent = true;
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
% endif
|
|
@ -0,0 +1,225 @@
|
|||
## mako
|
||||
<%page expression_filter="h" args="online_help_token"/>
|
||||
<%namespace name='static' file='static_content.html'/>
|
||||
<%namespace file='main.html' import="login_query"/>
|
||||
<%!
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from context_processors import doc_url
|
||||
from lms.djangoapps.ccx.overrides import get_current_ccx
|
||||
from openedx.core.djangolib.markup import HTML, Text
|
||||
|
||||
# App that handles subdomain specific branding
|
||||
from branding import api as branding_api
|
||||
# app that handles site status messages
|
||||
from status.status import get_site_status_msg
|
||||
from util.enterprise_helpers import get_enterprise_customer_logo_url
|
||||
%>
|
||||
|
||||
## Provide a hook for themes to inject branding on top.
|
||||
<%block name="navigation_top" />
|
||||
|
||||
## Add UI Toolkit components if using the Pattern Library
|
||||
% if uses_pattern_library:
|
||||
<%block name="js_extra">
|
||||
<%static:require_module module_name="js/header_factory" class_name="HeaderFactory">
|
||||
HeaderFactory();
|
||||
</%static:require_module>
|
||||
</%block>
|
||||
% endif
|
||||
|
||||
<%block>
|
||||
<%
|
||||
try:
|
||||
course_id = course.id
|
||||
except:
|
||||
# can't figure out a better way to get at a possibly-defined course var
|
||||
course_id = None
|
||||
site_status_msg = get_site_status_msg(course_id)
|
||||
%>
|
||||
% if site_status_msg:
|
||||
<div class="site-status">
|
||||
<div class="inner-wrapper">
|
||||
<span class="white-error-icon"></span>
|
||||
<p>${site_status_msg}</p>
|
||||
</div>
|
||||
</div>
|
||||
% endif
|
||||
</%block>
|
||||
<header id="global-navigation" class="header-global ${"slim" if course else ""}" >
|
||||
<nav class="wrapper-header" aria-label="${_('Global')}">
|
||||
<h1 class="logo">
|
||||
<a href="${marketing_link('ROOT')}">
|
||||
<%block name="navigation_logo">
|
||||
<%
|
||||
logo_url = get_enterprise_customer_logo_url(request)
|
||||
logo_size = 'ec-logo-size'
|
||||
if logo_url is None:
|
||||
logo_url = branding_api.get_logo_url(is_secure)
|
||||
logo_size = ''
|
||||
%>
|
||||
<img class="${logo_size}" src="${logo_url}" width="108" height="23" vspace="15" alt="${_("{platform_name} Home Page").format(platform_name=static.get_platform_name())}"/>
|
||||
</%block>
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
% if course:
|
||||
<h2 class="course-header"><span class="provider">${course.display_org_with_default}:</span>
|
||||
<span class="course-number">${course.display_number_with_default}</span>
|
||||
<%
|
||||
display_name = course.display_name_with_default
|
||||
if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
|
||||
ccx = get_current_ccx(course.id)
|
||||
if ccx:
|
||||
display_name = ccx.display_name
|
||||
%>
|
||||
<span class="course-name">${display_name}</span></h2>
|
||||
% endif
|
||||
|
||||
% if user.is_authenticated():
|
||||
<ol class="left nav-global list-inline authenticated">
|
||||
<%block name="navigation_global_links_authenticated">
|
||||
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE') and not show_program_listing:
|
||||
<li class="item nav-global-01">
|
||||
<a href="${marketing_link('COURSES')}">${_('Explore courses')}</a>
|
||||
</li>
|
||||
% endif
|
||||
% if show_program_listing:
|
||||
<li class="tab-nav-item">
|
||||
<a class="${'active ' if reverse('dashboard') == request.path else ''}tab-nav-link" href="${reverse('dashboard')}">
|
||||
${_("Courses")}
|
||||
</a>
|
||||
</li>
|
||||
<li class="tab-nav-item">
|
||||
<a class="${'active ' if reverse('program_listing_view') in request.path else ''}tab-nav-link" href="${reverse('program_listing_view')}">
|
||||
${_("Programs")}
|
||||
</a>
|
||||
</li>
|
||||
% endif
|
||||
%if settings.FEATURES.get('ENABLE_SYSADMIN_DASHBOARD','') and user.is_staff:
|
||||
<li class="item">
|
||||
## Translators: This is short for "System administration".
|
||||
<a href="${reverse('sysadmin')}">${_("System Admin")}</a>
|
||||
</li>
|
||||
%endif
|
||||
</%block>
|
||||
</ol>
|
||||
|
||||
<%include file="user_dropdown.html"/>
|
||||
|
||||
<a href="${get_online_help_info(online_help_token)['doc_url']}"
|
||||
target="_blank"
|
||||
class="doc-link">${_("Help")}</a>
|
||||
|
||||
% if should_display_shopping_cart_func() and not (course and static.is_request_in_themed_site()): # see shoppingcart.context_processor.user_has_cart_context_processor
|
||||
<ol class="user">
|
||||
<li class="primary">
|
||||
<a class="shopping-cart" href="${reverse('shoppingcart.views.show_cart')}">
|
||||
<span class="icon fa fa-shopping-cart" aria-hidden="true"></span> ${_("Shopping Cart")}
|
||||
</a>
|
||||
</li>
|
||||
</ol>
|
||||
% endif
|
||||
% else:
|
||||
<ol class="left list-inline nav-global">
|
||||
<%block name="navigation_global_links">
|
||||
% if static.get_value('ENABLE_MKTG_SITE', settings.FEATURES.get('ENABLE_MKTG_SITE', False)):
|
||||
<li class="item nav-global-01">
|
||||
<a href="${marketing_link('HOW_IT_WORKS')}">${_("How it Works")}</a>
|
||||
</li>
|
||||
% if settings.FEATURES.get('COURSES_ARE_BROWSABLE'):
|
||||
<li class="item nav-global-02">
|
||||
<a href="${marketing_link('COURSES')}">${_("Courses")}</a>
|
||||
</li>
|
||||
% endif
|
||||
<li class="item nav-global-03">
|
||||
<a href="${marketing_link('SCHOOLS')}">${_("Schools")}</a>
|
||||
</li>
|
||||
% endif
|
||||
</%block>
|
||||
|
||||
<%block name="navigation_other_global_links">
|
||||
% if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
|
||||
% if settings.FEATURES.get('ENABLE_COURSE_DISCOVERY'):
|
||||
<li class="item nav-global-05">
|
||||
<a class="btn" href="/courses">${_("Explore Courses")}</a>
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
</%block>
|
||||
</ol>
|
||||
|
||||
<ol class="right nav-courseware list-inline">
|
||||
<%block name="navigation_sign_in">
|
||||
% if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
|
||||
% if course and settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
|
||||
<li class="item nav-global-04">
|
||||
<a class="btn-neutral btn-register" style="padding:10px 20px;" href="${reverse('course-specific-register', args=[course.id.to_deprecated_string()])}">${_("Register Now")}</a>
|
||||
</li>
|
||||
% else:
|
||||
<li class="item nav-global-04">
|
||||
<a class="btn-neutral btn-register" style="padding:10px 20px;" href="/register${login_query()}">${_("Register Now")}</a>
|
||||
</li>
|
||||
% endif
|
||||
% endif
|
||||
<li class="item nav-courseware-01">
|
||||
% if not settings.FEATURES['DISABLE_LOGIN_BUTTON']:
|
||||
% if course and settings.FEATURES.get('RESTRICT_ENROLL_BY_REG_METHOD') and course.enrollment_domain:
|
||||
<a class="btn btn-primary" href="${reverse('course-specific-login', args=[course.id.to_deprecated_string()])}${login_query()}">${_("Sign in")}</a>
|
||||
% else:
|
||||
<a class="btn btn-primary" href="/login${login_query()}">${_("Sign in")}</a>
|
||||
% endif
|
||||
% endif
|
||||
</li>
|
||||
</%block>
|
||||
</ol>
|
||||
% endif
|
||||
% if static.show_language_selector():
|
||||
<% languages = static.get_released_languages() %>
|
||||
% if len(languages) > 1:
|
||||
<ol class="user">
|
||||
<li class="primary">
|
||||
<form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form">
|
||||
<input type="hidden" id="csrf_token" name="csrfmiddlewaretoken" value="${csrf_token}">
|
||||
% if user.is_authenticated():
|
||||
<input title="preference api" type="hidden" class="url-endpoint" value="${reverse('preferences_api', kwargs={'username': user.username})}" data-user-is-authenticated="true">
|
||||
% else:
|
||||
<input title="session update url" type="hidden" class="url-endpoint" value="${reverse('session_language')}" data-user-is-authenticated="false">
|
||||
% endif
|
||||
<label><span class="sr">${_("Choose Language")}</span>
|
||||
<select class="input select language-selector" id="settings-language-value" name="language">
|
||||
% for language in languages:
|
||||
% if language[0] == LANGUAGE_CODE:
|
||||
<option value="${language[0]}" selected="selected">${language[1]}</option>
|
||||
% else:
|
||||
<option value="${language[0]}" >${language[1]}</option>
|
||||
% endif
|
||||
% endfor
|
||||
</select>
|
||||
</label>
|
||||
</form>
|
||||
</li>
|
||||
</ol>
|
||||
% endif
|
||||
% endif
|
||||
</nav>
|
||||
</header>
|
||||
% if course:
|
||||
<!--[if lte IE 9]>
|
||||
<div class="ie-banner" aria-hidden="true">${Text(_('{begin_strong}Warning:{end_strong} Your browser is not fully supported. We strongly recommend using {chrome_link} or {ff_link}.')).format(
|
||||
begin_strong=HTML('<strong>'),
|
||||
end_strong=HTML('</strong>'),
|
||||
chrome_link=HTML('<a href="https://www.google.com/chrome" target="_blank">Chrome</a>'),
|
||||
ff_link=HTML('<a href="http://www.mozilla.org/firefox" target="_blank">Firefox</a>'),
|
||||
)}</div>
|
||||
<![endif]-->
|
||||
% endif
|
||||
|
||||
<%include file="help_modal.html"/>
|
||||
## Dont show cookie-banner if already accepted.
|
||||
<script type="text/javascript">
|
||||
if (getCookie("cookie-banner") == "true") {
|
||||
closeCookieBanner();
|
||||
}
|
||||
</script>
|