Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

theme code simplification #8900

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 30 additions & 72 deletions kolibri/core/theme_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,84 +10,43 @@
logger = logging.getLogger(__name__)


# previously used for cache busting
THEME_NAME = "themeName"
THEME_VERSION = "themeVersion"

# These constants are used by theme.js and the $theme mixin on the front-end
TOKEN_MAPPING = "tokenMapping"
BRAND_COLORS = "brandColors"
PRIMARY = "primary"
SECONDARY = "secondary"
COLOR_V50 = "v_50"
COLOR_V100 = "v_100"
COLOR_V200 = "v_200"
COLOR_V300 = "v_300"
COLOR_V400 = "v_400"
COLOR_V500 = "v_500"
COLOR_V600 = "v_600"
COLOR_V700 = "v_700"
COLOR_V800 = "v_800"
COLOR_V900 = "v_900"
SIGN_IN = "signIn"
SIDE_NAV = "sideNav"
APP_BAR = "appBar"
BACKGROUND = "background"
BACKGROUND_IMG_CREDIT = "backgroundImgCredit"
SCRIM_OPACITY = "scrimOpacity"
TITLE = "title"
TITLE_STYLE = "titleStyle"
TOP_LOGO = "topLogo"
LOGO = "logo"
BRANDED_FOOTER = "brandedFooter"
PARAGRAPH_ARRAY = "paragraphArray"
IMG_SRC = "src"
IMG_STYLE = "style"
IMG_ALT = "alt"
SHOW_TITLE = "showTitle"
SHOW_K_FOOTER_LOGO = "showKolibriFooterLogo"
SHOW_POWERED_BY = "showPoweredBy"
POWERED_BY_STYLE = "poweredByStyle"


def _validateMetadata(theme):
def deprecated_msg(key):
if key in theme:
logger.info("Note: '{}' is deprecated as of v0.15.0".format(key))

deprecated_msg(THEME_NAME)
deprecated_msg(THEME_VERSION)
_TOKEN_MAPPING = "tokenMapping"
_BRAND_COLORS = "brandColors"
_SIGN_IN = "signIn"
_SIDE_NAV = "sideNav"
_APP_BAR = "appBar"


def _validateBrandColors(theme):
if BRAND_COLORS not in theme:
if _BRAND_COLORS not in theme:
logger.error("brand colors not defined by theme")
return

required_colors = [PRIMARY, SECONDARY]
required_colors = ["primary", "secondary"]
color_names = [
COLOR_V50,
COLOR_V100,
COLOR_V200,
COLOR_V300,
COLOR_V400,
COLOR_V500,
COLOR_V600,
COLOR_V700,
COLOR_V800,
COLOR_V900,
"v_50",
"v_100",
"v_200",
"v_300",
"v_400",
"v_500",
"v_600",
"v_700",
"v_800",
"v_900",
]
for color in required_colors:
if color not in theme[BRAND_COLORS]:
if color not in theme[_BRAND_COLORS]:
logger.error("'{}' not defined by theme".format(color))
for name in color_names:
if name not in theme[BRAND_COLORS][color]:
if name not in theme[_BRAND_COLORS][color]:
logger.error("{} '{}' not defined by theme".format(color, name))


def _validateScrimOpacity(theme):
if SCRIM_OPACITY in theme[SIGN_IN]:
opacity = theme[SIGN_IN][SCRIM_OPACITY]
SCRIM_OPACITY = "scrimOpacity"
if SCRIM_OPACITY in theme[_SIGN_IN]:
opacity = theme[_SIGN_IN][SCRIM_OPACITY]
if opacity is None or opacity < 0 or opacity > 1:
logger.error("scrim opacity should be a value in the closed interval [0,1]")
return
Expand All @@ -97,14 +56,14 @@ def _initFields(theme):
"""
set up top-level dicts if they don't exist
"""
if SIGN_IN not in theme:
theme[SIGN_IN] = {}
if TOKEN_MAPPING not in theme:
theme[TOKEN_MAPPING] = {}
if SIDE_NAV not in theme:
theme[SIDE_NAV] = {}
if APP_BAR not in theme:
theme[APP_BAR] = {}
if _SIGN_IN not in theme:
theme[_SIGN_IN] = {}
if _TOKEN_MAPPING not in theme:
theme[_TOKEN_MAPPING] = {}
if _SIDE_NAV not in theme:
theme[_SIDE_NAV] = {}
if _APP_BAR not in theme:
theme[_APP_BAR] = {}


@hooks.define_hook(only_one_registered=True)
Expand All @@ -118,7 +77,6 @@ class ThemeHook(hooks.KolibriHook):
def get_theme(cls):
theme = list(cls.registered_hooks)[0].theme
_initFields(theme)
_validateMetadata(theme)
_validateBrandColors(theme)
_validateScrimOpacity(theme)
return theme
Expand Down
9 changes: 3 additions & 6 deletions kolibri/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@
from kolibri.core.device.utils import device_provisioned
from kolibri.core.hooks import LogoutRedirectHook
from kolibri.core.hooks import RoleBasedRedirectHook
from kolibri.core.theme_hook import BRAND_COLORS
from kolibri.core.theme_hook import COLOR_V400
from kolibri.core.theme_hook import PRIMARY
from kolibri.core.theme_hook import ThemeHook


Expand Down Expand Up @@ -178,9 +175,9 @@ def get_context_data(self, **kwargs):
context = super(UnsupportedBrowserView, self).get_context_data(**kwargs)
context["brand_primary_v400"] = (
ThemeHook.get_theme()
.get(BRAND_COLORS, {})
.get(PRIMARY, {})
.get(COLOR_V400, "purple")
.get("brandColors", {})
.get("primary", {})
.get("v_400", "purple")
)
return context

Expand Down
75 changes: 33 additions & 42 deletions kolibri/plugins/default_theme/kolibri_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,45 @@ class DefaultThemeHook(theme_hook.ThemeHook):
@property
def theme(self):
return {
# specify primary and secondary brand colors
theme_hook.BRAND_COLORS: {
theme_hook.PRIMARY: {
theme_hook.COLOR_V50: "#f0e7ed",
theme_hook.COLOR_V100: "#dbc3d4",
theme_hook.COLOR_V200: "#c59db9",
theme_hook.COLOR_V300: "#ac799d",
theme_hook.COLOR_V400: "#996189",
theme_hook.COLOR_V500: "#874e77",
theme_hook.COLOR_V600: "#7c4870",
theme_hook.COLOR_V700: "#6e4167",
theme_hook.COLOR_V800: "#5f3b5c",
theme_hook.COLOR_V900: "#4b2e4d",
# primary and secondary brand colors
"brandColors": {
"primary": {
"v_50": "#f0e7ed",
"v_100": "#dbc3d4",
"v_200": "#c59db9",
"v_300": "#ac799d",
"v_400": "#996189",
"v_500": "#874e77",
"v_600": "#7c4870",
"v_700": "#6e4167",
"v_800": "#5f3b5c",
"v_900": "#4b2e4d",
},
theme_hook.SECONDARY: {
theme_hook.COLOR_V50: "#e3f0ed",
theme_hook.COLOR_V100: "#badbd2",
theme_hook.COLOR_V200: "#8dc5b6",
theme_hook.COLOR_V300: "#62af9a",
theme_hook.COLOR_V400: "#479e86",
theme_hook.COLOR_V500: "#368d74",
theme_hook.COLOR_V600: "#328168",
theme_hook.COLOR_V700: "#2c715a",
theme_hook.COLOR_V800: "#26614d",
theme_hook.COLOR_V900: "#1b4634",
"secondary": {
"v_50": "#e3f0ed",
"v_100": "#badbd2",
"v_200": "#8dc5b6",
"v_300": "#62af9a",
"v_400": "#479e86",
"v_500": "#368d74",
"v_600": "#328168",
"v_700": "#2c715a",
"v_800": "#26614d",
"v_900": "#1b4634",
},
},
# sign-in page config
theme_hook.SIGN_IN: {
theme_hook.BACKGROUND: static("background.jpg"),
theme_hook.BACKGROUND_IMG_CREDIT: "Thomas Van Den Driessche",
theme_hook.SCRIM_OPACITY: 0.7,
theme_hook.TITLE: None, # use default: "Kolibri"
theme_hook.TOP_LOGO: {
theme_hook.IMG_SRC: None, # use default Kolibri bird
theme_hook.IMG_STYLE: "padding-left: 64px; padding-right: 64px; margin-bottom: 8px; margin-top: 8px",
theme_hook.IMG_ALT: None,
"signIn": {
"background": static("background.jpg"),
"backgroundImgCredit": "Thomas Van Den Driessche",
"scrimOpacity": 0.7,
"topLogo": {
"style": "padding-left: 64px; padding-right: 64px; margin-bottom: 8px; margin-top: 8px",
},
theme_hook.SHOW_POWERED_BY: False,
theme_hook.SHOW_TITLE: True,
theme_hook.SHOW_K_FOOTER_LOGO: False,
"showTitle": True,
},
# side-nav config
theme_hook.SIDE_NAV: {
theme_hook.TITLE: None, # use default: "Kolibri"
theme_hook.BRANDED_FOOTER: {},
theme_hook.SHOW_K_FOOTER_LOGO: True,
"sideNav": {
"showKolibriFooterLogo": True,
},
# app bar config
theme_hook.APP_BAR: {theme_hook.TOP_LOGO: None},
}