diff --git a/lms/djangoapps/branding/api.py b/lms/djangoapps/branding/api.py index 6c9f05f1b2..987f8a8d9b 100644 --- a/lms/djangoapps/branding/api.py +++ b/lms/djangoapps/branding/api.py @@ -98,10 +98,13 @@ def get_footer(is_secure=True): "copyright": _footer_copyright(), "logo_image": _footer_logo_img(is_secure), "social_links": _footer_social_links(), - "navigation_links": _footer_navigation_links(), + "business_links": _footer_business_links(), "mobile_links": _footer_mobile_links(is_secure), - "legal_links": _footer_legal_links(), + "more_info_links": _footer_more_info_links(), + "connect_links": _footer_connect_links(), "openedx_link": _footer_openedx_link(), + "navigation_links": _footer_navigation_links(), + "legal_links": _footer_legal_links(), "edx_org_link": { "url": "https://www.edx.org/?utm_medium=affiliate_partner&utm_source=opensource-partner&utm_content=open-edx-partner-footer-link&utm_campaign=open-edx-footer", "text": _("Take free online courses at edX.org"), @@ -166,6 +169,25 @@ def _footer_social_links(): return links +def _footer_connect_links(): + """Return the connect links to display in the footer. """ + return [ + { + "name": link_name, + "title": link_title, + "url": link_url, + } + for link_name, link_url, link_title in [ + ("blog", marketing_link("BLOG"), _("Blog")), + ("contact", marketing_link("CONTACT"), _("Contact Us")), + ("help-center", settings.SUPPORT_SITE_LINK, _("Help Center")), + ("media_kit", marketing_link("MEDIA_KIT"), _("Media Kit")), + ("donate", marketing_link("DONATE"), _("Donate")), + ] + if link_url and link_url != "#" + ] + + def _footer_navigation_links(): """Return the navigation links to display in the footer. """ platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME) @@ -221,6 +243,59 @@ def _footer_legal_links(): ] +def _footer_business_links(): + """Return the business links to display in the footer. """ + platform_name = configuration_helpers.get_value('platform_name', settings.PLATFORM_NAME) + + return [ + { + "name": link_name, + "title": link_title, + "url": link_url, + } + for link_name, link_url, link_title in [ + ("about", marketing_link("ABOUT"), _("About")), + ("enterprise", marketing_link("ENTERPRISE"), + _("{platform_name} for Business").format(platform_name=platform_name)), + ("affiliates", marketing_link("AFFILIATES"), _("Affiliates")), + ("openedx", _footer_openedx_link()["url"], _("Open edX")), + ("careers", marketing_link("CAREERS"), _("Careers")), + ("news", marketing_link("NEWS"), _("News")), + ] + if link_url and link_url != "#" + ] + + +def _footer_more_info_links(): + """Return the More Information footer links (e.g. terms of service). """ + + links = [ + ("terms_of_service_and_honor_code", marketing_link("TOS_AND_HONOR"), _("Terms of Service & Honor Code")), + ("privacy_policy", marketing_link("PRIVACY"), _("Privacy Policy")), + ("accessibility_policy", marketing_link("ACCESSIBILITY"), _("Accessibility Policy")), + ("sitemap", marketing_link("SITE_MAP"), _("Sitemap")), + ] + + # Backwards compatibility: If a combined "terms of service and honor code" + # link isn't provided, add separate TOS and honor code links. + tos_and_honor_link = marketing_link("TOS_AND_HONOR") + if not (tos_and_honor_link and tos_and_honor_link != "#"): + links.extend([ + ("terms_of_service", marketing_link("TOS"), _("Terms of Service")), + ("honor_code", marketing_link("HONOR"), _("Honor Code")), + ]) + + return [ + { + "name": link_name, + "title": link_title, + "url": link_url, + } + for link_name, link_url, link_title in links + if link_url and link_url != "#" + ] + + def _footer_mobile_links(is_secure): """Return the mobile app store links. diff --git a/lms/djangoapps/branding/tests/test_api.py b/lms/djangoapps/branding/tests/test_api.py index 29e4695490..cb09f24c01 100644 --- a/lms/djangoapps/branding/tests/test_api.py +++ b/lms/djangoapps/branding/tests/test_api.py @@ -47,6 +47,7 @@ class TestFooter(TestCase): "ABOUT": "/about-us", "NEWS": "/news-announcements", "CONTACT": "/contact", + "CAREERS": '/careers', "FAQ": "/student-faq", "BLOG": "/edx-blog", "DONATE": "/donate", @@ -55,17 +56,20 @@ class TestFooter(TestCase): "TOS_AND_HONOR": "/edx-terms-service", "PRIVACY": "/edx-privacy-policy", "ACCESSIBILITY": "/accessibility", + "AFFILIATES": '/affiliates', "MEDIA_KIT": "/media-kit", "ENTERPRISE": "/enterprise" }) @override_settings(PLATFORM_NAME='\xe9dX') def test_get_footer(self): actual_footer = get_footer(is_secure=True) + import pprint + pprint.pprint(actual_footer) + print('******************************************!!!!!!!!!!!!!!!!!!!!!!!!!!!*******************************************') expected_footer = { - 'copyright': - '\xa9 \xe9dX. All rights reserved except where noted. ' - 'EdX, Open edX and their respective logos ' - 'are trademarks or registered trademarks of edX Inc.', + 'copyright': '\xa9 \xe9dX. All rights reserved except where noted. ' + ' EdX, Open edX and their respective logos are ' + 'trademarks or registered trademarks of edX Inc.', 'navigation_links': [ {'url': 'https://edx.org/about-us', 'name': 'about', 'title': 'About'}, {'url': 'https://edx.org/enterprise', 'name': 'enterprise', 'title': '\xe9dX for Business'}, @@ -73,6 +77,34 @@ class TestFooter(TestCase): {'url': 'https://edx.org/news-announcements', 'name': 'news', 'title': 'News'}, {'url': 'https://support.example.com', 'name': 'help-center', 'title': 'Help Center'}, {'url': 'https://edx.org/contact', 'name': 'contact', 'title': 'Contact'}, + {'url': 'https://edx.org/careers', 'name': 'careers', 'title': 'Careers'}, + {'url': 'https://edx.org/donate', 'name': 'donate', 'title': 'Donate'} + ], + 'business_links': [ + {'url': 'https://edx.org/about-us', 'name': 'about', 'title': 'About'}, + {'url': 'https://edx.org/enterprise', 'name': 'enterprise', 'title': '\xe9dX for Business'}, + {'url': 'https://edx.org/affiliates', 'name': 'affiliates', 'title': 'Affiliates'}, + {'url': 'http://open.edx.org', 'name': 'openedx', 'title': 'Open edX'}, + {'url': 'https://edx.org/careers', 'name': 'careers', 'title': 'Careers'}, + {'url': 'https://edx.org/news-announcements', 'name': 'news', 'title': 'News'}, + + ], + 'more_info_links': [ + {'url': 'https://edx.org/edx-terms-service', + 'name': 'terms_of_service_and_honor_code', + 'title': 'Terms of Service & Honor Code'}, + {'url': 'https://edx.org/edx-privacy-policy', 'name': 'privacy_policy', 'title': 'Privacy Policy'}, + {'url': 'https://edx.org/accessibility', + 'name': 'accessibility_policy', + 'title': 'Accessibility Policy'}, + {'url': 'https://edx.org/sitemap', 'name': 'sitemap', 'title': 'Sitemap'}, + + ], + 'connect_links': [ + {'url': 'https://edx.org/edx-blog', 'name': 'blog', 'title': 'Blog'}, + {'url': 'https://edx.org/contact', 'name': 'contact', 'title': 'Contact Us'}, + {'url': 'https://support.example.com', 'name': 'help-center', 'title': 'Help Center'}, + {'url': 'https://edx.org/media-kit', 'name': 'media_kit', 'title': 'Media Kit'}, {'url': 'https://edx.org/donate', 'name': 'donate', 'title': 'Donate'} ], 'legal_links': [ @@ -84,21 +116,23 @@ class TestFooter(TestCase): 'name': 'accessibility_policy', 'title': 'Accessibility Policy'}, {'url': 'https://edx.org/sitemap', 'name': 'sitemap', 'title': 'Sitemap'}, - {'url': 'https://edx.org/media-kit', 'name': 'media_kit', 'title': 'Media Kit'} + {'name': 'media_kit', + 'title': u'Media Kit', + 'url': u'https://edx.org/media-kit'} ], 'social_links': [ {'url': '#', 'action': 'Like \xe9dX on Facebook', 'name': 'facebook', 'icon-class': 'fa-facebook-square', 'title': 'Facebook'}, {'url': '#', 'action': 'Follow \xe9dX on Twitter', 'name': 'twitter', - 'icon-class': 'fa-twitter', 'title': 'Twitter'}, + 'icon-class': 'fa-twitter-square', 'title': 'Twitter'}, {'url': '#', 'action': 'Subscribe to the \xe9dX YouTube channel', - 'name': 'youtube', 'icon-class': 'fa-youtube', 'title': 'Youtube'}, + 'name': 'youtube', 'icon-class': 'fa-youtube-square', 'title': 'Youtube'}, {'url': '#', 'action': 'Follow \xe9dX on LinkedIn', 'name': 'linkedin', 'icon-class': 'fa-linkedin-square', 'title': 'LinkedIn'}, {'url': '#', 'action': 'Follow \xe9dX on Google+', 'name': 'google_plus', 'icon-class': 'fa-google-plus-square', 'title': 'Google+'}, {'url': '#', 'action': 'Subscribe to the \xe9dX subreddit', - 'name': 'reddit', 'icon-class': 'fa-reddit', 'title': 'Reddit'} + 'name': 'reddit', 'icon-class': 'fa-reddit-square', 'title': 'Reddit'} ], 'mobile_links': [], 'logo_image': 'https://edx.org/static/images/logo.png', @@ -112,4 +146,5 @@ class TestFooter(TestCase): 'text': 'Take free online courses at edX.org', }, } + pprint.pprint(expected_footer) self.assertEqual(actual_footer, expected_footer) diff --git a/lms/envs/common.py b/lms/envs/common.py index 5cc5766c0f..ce86ba1531 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -2387,7 +2387,7 @@ SOCIAL_MEDIA_FOOTER_DISPLAY = { # Translators: This is the website name of www.twitter.com. Please # translate this the way that Twitter advertises in your language. "title": _("Twitter"), - "icon": "fa-twitter", + "icon": "fa-twitter-square", "action": _("Follow {platform_name} on Twitter") }, "linkedin": { @@ -2420,7 +2420,7 @@ SOCIAL_MEDIA_FOOTER_DISPLAY = { # Translators: This is the website name of www.reddit.com. Please # translate this the way that Reddit advertises in your language. "title": _("Reddit"), - "icon": "fa-reddit", + "icon": "fa-reddit-square", "action": _("Subscribe to the {platform_name} subreddit"), }, "vk": { @@ -2439,7 +2439,7 @@ SOCIAL_MEDIA_FOOTER_DISPLAY = { # Translators: This is the website name of www.youtube.com. Please # translate this the way that YouTube advertises in your language. "title": _("Youtube"), - "icon": "fa-youtube", + "icon": "fa-youtube-square", "action": _("Subscribe to the {platform_name} YouTube channel") } } diff --git a/lms/envs/devstack_docker.py b/lms/envs/devstack_docker.py index a3c04d51ea..3687cd07d7 100644 --- a/lms/envs/devstack_docker.py +++ b/lms/envs/devstack_docker.py @@ -46,8 +46,9 @@ ENABLE_MKTG_SITE = os.environ.get('ENABLE_MARKETING_SITE', False) MARKETING_SITE_ROOT = os.environ.get('MARKETING_SITE_ROOT', 'http://localhost:8080') MKTG_URLS = { - 'ABOUT': '/about-us', + 'ABOUT': '/about', 'ACCESSIBILITY': '/accessibility', + 'AFFILIATES': '/affiliates', 'BLOG': '/blog', 'CAREERS': '/careers', 'CONTACT': '/contact', diff --git a/lms/static/sass/shared/_footer-edx.scss b/lms/static/sass/shared/_footer-edx.scss index 51b51627a9..39352645e7 100644 --- a/lms/static/sass/shared/_footer-edx.scss +++ b/lms/static/sass/shared/_footer-edx.scss @@ -2,11 +2,12 @@ // ==================== @import '../base/grid-settings'; @import 'neat/neat'; // lib - Neat - +@import 'bootstrap/scss/functions'; +@import 'bootstrap/scss/variables'; +@import 'bootstrap/scss/mixins/breakpoints'; $edx-footer-link-color: $link-color; -$edx-footer-bg-color: rgb(252,252,252); - +$edx-footer-bg-color: rgb(252, 252, 252); // Aggressively scoped for Drupal // ============================== @@ -15,9 +16,96 @@ $edx-footer-bg-color: rgb(252,252,252); // CMS styles footer#footer-edx-v3 { background: $edx-footer-bg-color; - padding: 20px; + padding: $baseline*0.75 0; border-top: 1px solid $courseware-button-border-color; + .main-row { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + flex-wrap: wrap; + } + + .flex-column { + flex-direction: column; + } + + a.social-links.external:hover { + text-decoration: none; + } + + .full-height { + height: 100%; + } + + .social-app-links-div { + float: none; + display: table-cell; + vertical-align: top; + } + + div.container { + min-width: 0; + padding: 0 $baseline*0.75; + } + + .row.small-screen { + display: none; + } + + .row.all-screens { + display: flex; + } + + ul li h3 { + font-weight: 600; + padding: $baseline*0.25 0; + color: $lighter-base-font-color; + } + + .widget_nav_menu ul { + list-style: outside none none; + padding-left: 0; + margin-bottom: $baseline*0.75; + } + + .footer-language-selector { + @include float(right); + } + + .app-links { + margin-top: $baseline*0.75; + height: auto; + display: inline-flex; + } + + .clear-margins { + margin-top: $baseline*0.75; + border-bottom: 1px solid $courseware-button-border-color; + } + + .social { + margin-top: $baseline*1.5; + height: auto; + } + + ul.social li { + display: table-cell; + width: 1%; + } + + .edx-footer-logo { + display: inline-flex; + } + + .border-left { + @include border-left( 1px solid $courseware-button-border-color); + + border-bottom: none; + } + + // To match the Pattern Library -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -36,6 +124,9 @@ footer#footer-edx-v3 { .copyright { margin-top: 30px; + + @include font-size(16); + @include line-height(24); } .site-nav, @@ -43,7 +134,7 @@ footer#footer-edx-v3 { li { @include font-size(14); @include line-height(14); - @include margin-right(20px); + @include margin-right($baseline); color: $edx-footer-link-color; @@ -122,19 +213,45 @@ footer#footer-edx-v3 { color: $edx-footer-link-color; } + + a.sm-link { @include float(left); - @include margin(0, 0, 10px, 10px); - @include font-size(28); + @include margin(0, 6, 10, 0); + @include font-size(40); @include line-height(28); width: 35px; height: 30px; + line-height: 1; + position: relative; + display: inline; + background: none; + + @include text-align(left); + + &:first-of-type { + @include margin-left(0); + } + + &:hover, + &:focus { + opacity: 0.7; + border: none; + } + } + + a.social-links { + @include margin(0, -7, 10, 0); + @include font-size(45); + @include line-height(28); + line-height: 1; position: relative; display: inline; background: none; text-align: left; + padding: $baseline*0.35; &:first-of-type { @include margin-left(0); @@ -160,6 +277,8 @@ footer#footer-edx-v3 { height: 40px; max-width: 200px; } + + padding: $baseline*0.35; } .site-nav, @@ -181,8 +300,37 @@ footer#footer-edx-v3 { } } - @include media($edx-bp-large) { - padding: 20px 10px; + @include media-breakpoint-up(sm) { + padding: $baseline $baseline*0.5; + + div.container { + min-width: 0; + padding: 0; + } + + .edx-footer-logo { + @include padding-left($baseline); + } + + div.col-xl-4.col-lg-4.col-md-9.ml-md-auto.col-sm-6.flex-column.border-left { + @include border-left(1px solid $courseware-button-border-color); + } + + div.col-xl-6 div.col-xl-4 div div { + border-bottom: 1px solid $courseware-button-border-color; + } + + div.col-xl-6 div.col-xl-4:nth-child(3) div div { + border: none; + } + + .remove-border-left { + @include border-left(none); + } + + .remove-bottom-border { + border-bottom: none; + } .site-details { @include span-columns(8); @@ -200,9 +348,236 @@ footer#footer-edx-v3 { .social-media-links { margin-bottom: 40px; } + + ul.clear-margins { + margin-top: 5px; + border-bottom: none; + } + + .app-link img { + height: 40px; + margin-top: 10px; + } + + a.social-links { + @include font-size(50); + + margin-top: 5px; + + @include margin-left($baseline*0.25); + } + + .social { + display: inline; + margin-top: 0; + } + + + .col-sm-7 .footer-language-selector { + display: inline-block; + float: none; + } + + ul.social li { + display: inline; + width: 0; + } } - @include media($edx-bp-huge) { + @include media-breakpoint-up(md) { + .no-left-border { + @include border-left(none); + } + + div.col-xl-6 div.col-xl-4 div div { + border-bottom: none; + } + + div.border-left:nth-child(1) { + border: none; + } + + div.col-xl-4.col-lg-4.col-md-9.ml-md-auto.col-sm-6.flex-column.border-left { + border: none; + } + + padding: $baseline $baseline*0.5; + + .site-details { + @include span-columns(8); + } + + .external-links { + @include span-columns(4); + } + + .social-media-links, + .mobile-app-links { + @include float(right); + } + + .social-media-links { + margin-bottom: 40px; + } + + ul.clear-margins { + margin-top: 15px; + border-bottom: none; + } + + .app-link img { + height: 40px; + } + + a.social-links { + @include font-size(40); + } + + .col-xl-10 div.row div:nth-child(2) div.row:nth-child(1) { + @include border-left(1px solid $courseware-button-border-color); + } + + .col-xl-10 div.row div:nth-child(3) div.row:nth-child(1) { + @include border-left(1px solid $courseware-button-border-color); + } + + .social { + display: inline-flex; + vertical-align: middle; + margin-top: $baseline*1.5; + } + + .app-links { + display: inline-flex; + + @include margin-left($baseline*0.25); + + vertical-align: middle; + } + + .widget_nav_menu ul li { + @include font-size(16); + } + + ul li h3 { + font-weight: 700; + } + + .footer-language-selector { + float: none; + display: block; + + @include margin-left($baseline*1.5); + } + + ul.social li { + display: inline-flex; + width: auto; + } + } + + @include media-breakpoint-up(lg) { + padding: $baseline $baseline*0.5; + + .edx-footer-logo { + @include margin-left($baseline); + } + + div.col-xl-6 div.col-xl-4 div div { + border-bottom: none; + } + + .col-xl-10 div.row div div.row { + @include border-left(1px solid $courseware-button-border-color); + } + + div.col-xl-4.col-lg-4.col-md-9.ml-md-auto.col-sm-6.flex-column.border-left { + @include border-left(1px solid $courseware-button-border-color); + } + + .col-xl-10 div.row div:nth-child(1) div.row:nth-child(1) { + @include padding-left($baseline*1.75); + } + + .col-xl-2.col-md-12.col-sm-3.col-xs-10 { + text-align: left; + } + + .site-details { + @include span-columns(8); + } + + .external-links { + @include span-columns(4); + } + + div.border-left:nth-child(1) { + border: none; + } + + .social-media-links, + .mobile-app-links { + @include float(right); + } + + .social-media-links { + margin-bottom: 40px; + } + + ul.clear-margins { + margin-top: $baseline*0.75; + border-bottom: none; + } + + .app-link img { + height: 40px; + } + + a.social-links { + @include font-size(40); + } + + .social { + display: inline-flex; + vertical-align: middle; + margin-top: $baseline; + } + + .app-links { + display: inline-flex; + vertical-align: middle; + } + + .widget_nav_menu ul li { + @include font-size(16); + + padding-bottom: $baseline*0.25; + } + + ul li h3 { + font-weight: 700; + padding-bottom: $baseline*0.5; + } + + .footer-language-selector { + float: none; + display: inline-block; + } + + ul.social li { + display: inline; + } + } + + @include media-breakpoint-up(xl) { + div.border-left:nth-child(1) { + @include border-left(1px solid $courseware-button-border-color); + } + + div.col-xl-6 div.col-xl-4 div div { + border-bottom: none; + } + .footer-logo { @include span-columns(2); } @@ -215,8 +590,40 @@ footer#footer-edx-v3 { @include span-columns(3); } + .widget_nav_menu ul li { + @include font-size(16); + } + + .edx-footer-logo { + @include margin-left(0); + } + .social-media-links { - margin-bottom: 50px; + margin-bottom: $baseline*2.5; + } + + ul.social li { + display: inline; + } + + + .col-xl-10 div.row div div.row { + height: 100%; + + @include border-left( 1px solid $courseware-button-border-color); + } + + .clear-margins { + border-bottom: none; + } + + .col-xl-10 div.row div:nth-child(1) div.row:nth-child(1) { + padding: 0; + } + + .footer-language-selector { + margin: 20px 0; + float: none; } } diff --git a/themes/edx.org/lms/templates/footer.html b/themes/edx.org/lms/templates/footer.html index ea8a0d2244..2718abdf6d 100644 --- a/themes/edx.org/lms/templates/footer.html +++ b/themes/edx.org/lms/templates/footer.html @@ -9,6 +9,8 @@ <% footer = get_footer(is_secure=is_secure) %> <%namespace name='static' file='static_content.html'/> + + ## WARNING: These files are specific to edx.org and are not used in installations outside of that domain. Open edX users will want to use the file "footer.html" for any changes or overrides. % if include_dependencies: