Skip to content

Commit

Permalink
comunity theming horizon zen
Browse files Browse the repository at this point in the history
  • Loading branch information
zzacharo committed Nov 24, 2023
1 parent 6c9669d commit f8ef68e
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 9 deletions.
5 changes: 5 additions & 0 deletions invenio_communities/communities/records/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

"""Records API."""

from invenio_communities.communities.records.systemfields.community_theme import (
CommunityThemeField,
)
from invenio_records.dumpers import SearchDumper
from invenio_records.dumpers.relations import RelationDumperExt
from invenio_records.systemfields import ConstantField, DictField, ModelField
Expand Down Expand Up @@ -120,6 +123,8 @@ class Community(Record):

deletion_status = CommunityDeletionStatusField()

theme = CommunityThemeField()

tombstone = TombstoneField()


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,21 @@
}
}
},
"theme": {
"type": "object",
"description": "Branded theme configuration of community.",
"additionalProperties": false,
"properties": {
"template_theme": {
"description": "Theme name for community templates.",
"type": "string"
},
"config": {
"description": "Theme css config.",
"type": "object"
}
}
},
"tombstone": {
"type": "object",
"description": "Tombstone information for the community.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
},
"ids": {
"type": "array",
"items": {"type": "string"},
"items": {
"type": "string"
},
"uniqueItems": true
}
}
Expand All @@ -27,7 +29,9 @@
},
"affiliations": {
"type": "array",
"items": {"$ref": "#/affiliation"},
"items": {
"$ref": "#/affiliation"
},
"uniqueItems": true
},
"agent": {
Expand Down Expand Up @@ -455,7 +459,9 @@
},
"subjects": {
"type": "array",
"items": {"$ref": "#/subject"},
"items": {
"$ref": "#/subject"
},
"uniqueItems": true
},
"title_type": {
Expand All @@ -474,7 +480,10 @@
"additionalProperties": false,
"properties": {
"user": {
"type": ["integer", "string"]
"type": [
"integer",
"string"
]
}
}
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2023 CERN.
#
# Invenio-RDM-Records is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
"""Community theme systemfield."""

from invenio_records.systemfields import SystemField


class CommunityThemeField(SystemField):
"""Systemfield for controlling community theme indexing."""

#
# Data descriptor methods (i.e. attribute access)
#
def __get__(self, record, owner=None):
"""Get the deletion status of the community."""
if record is None:
return self # returns the field itself.

return record.get("theme")

def pre_dump(self, record, data, **kwargs):
"""Remove theme information from indexing."""
data.pop("theme", None)
record.pop("theme", None)
14 changes: 14 additions & 0 deletions invenio_communities/communities/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ class DeletionStatusSchema(Schema):
status = fields.String(dump_only=True)


class CommunityThemeSchema(Schema):
"""Community theme schema."""

template_theme = fields.String()
config = fields.Dict()


class CommunitySchema(BaseRecordSchema, FieldPermissionsMixin):
"""Schema for the community metadata."""

Expand All @@ -174,6 +181,10 @@ class Meta:
"is_verified": "moderate",
}

field_load_permissions = {
"theme": "theme_create",
}

id = fields.String(dump_only=True)
slug = SanitizedUnicode(
required=True,
Expand All @@ -196,7 +207,10 @@ class Meta:

is_verified = fields.Boolean(dump_only=True)

theme = fields.Nested(CommunityThemeSchema)

tombstone = fields.Nested(TombstoneSchema, dump_only=True)

deletion_status = fields.Nested(DeletionStatusSchema, dump_only=True)

@post_dump
Expand Down
13 changes: 13 additions & 0 deletions invenio_communities/communities/services/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,21 @@ def unmark(self, identity, data=None, record=None, **kwargs):
record.tombstone = record.tombstone


class CommunityThemeComponent(ServiceComponent):
"""Service component for Community PIDs."""

def create(self, identity, data=None, record=None, errors=None, **kwargs):
"""Inject parsed metadata to the record."""
record["theme"] = data.get("theme", {})

def update(self, identity, data=None, record=None, **kwargs):
"""Inject parsed theme to the record."""
record["theme"] = data.get("theme", {})


DefaultCommunityComponents = [
MetadataComponent,
CommunityThemeComponent,
CustomFieldsComponent,
PIDComponent,
RelationsComponent,
Expand Down
7 changes: 6 additions & 1 deletion invenio_communities/communities/services/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,12 @@
)

from ...permissions import CommunityPermissionPolicy, can_perform_action
from ..schema import CommunityFeaturedSchema, CommunitySchema, TombstoneSchema
from ..schema import (
CommunityFeaturedSchema,
CommunitySchema,
CommunityThemeSchema,
TombstoneSchema,
)
from .components import DefaultCommunityComponents
from .links import CommunityLink
from .search_params import IncludeDeletedCommunitiesParam, StatusParam
Expand Down
4 changes: 3 additions & 1 deletion invenio_communities/communities/services/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
from marshmallow.exceptions import ValidationError
from sqlalchemy.orm.exc import NoResultFound

from invenio_communities.communities.records.models import CommunityFeatured
from invenio_communities.communities.records.models import (
CommunityFeatured,
)
from invenio_communities.communities.services.links import CommunityLinksTemplate
from invenio_communities.communities.services.uow import (
CommunityFeaturedCommitOp,
Expand Down
11 changes: 11 additions & 0 deletions invenio_communities/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ def init_app(self, app):
self.init_hooks(app)
self.init_cache(app)

from jinja2 import ChoiceLoader, FileSystemLoader

app.jinja_env.loader = ChoiceLoader(
loaders=[
# Explore maybe how can we add the brand theme prefix
# There is also this https://github.com/inveniosoftware/invenio-app/blob/master/invenio_app/helpers.py#L58
FileSystemLoader("branded_theme"),
app.jinja_env.loader,
]
)

def init_config(self, app):
"""Initialize configuration.
Expand Down
3 changes: 3 additions & 0 deletions invenio_communities/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ class CommunityPermissionPolicy(BasePermissionPolicy):
# correct permissions based on which the field will be exposed only to moderators
can_moderate = [Disable()]

# Permissions to crud community theming
can_theme_create = [Administration(), SystemProcess()]


def can_perform_action(community, context):
"""Check if the given action is available on the request."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,10 @@
#}

{% extends config.BASE_TEMPLATE %}

{%- block css %}
{{ super() }}
{% if community %}
<link rel="stylesheet" type="text/css" href="/communities/{{community.id}}/brand_theme.css">
{% endif %}
{%- endblock css %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.invenio-page-body {
.page-subheader-outer {
background-color: {{ theme.headerBackgroundColor }} !important;
.theme-new-upload {
background-color: {{theme.newUploadButtonBackgroundColor}} !important;
color: {{theme.newUploadButtonColor}} !important;
}

.theme-menu-items {
background-color: {{theme.menuItemsBackgroundColor}} !important;
> a {
color: {{theme.menuItemsColor}} !important;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ <h1 class="ui medium header mb-0">{{ community.metadata.title }}</h1>
<div
class="sixteen wide mobile sixteen wide tablet three wide computer right aligned middle aligned column">
<a href="/uploads/new?community={{ community.slug }}"
class="ui positive button labeled icon rel-mt-1">
class="ui positive button labeled icon rel-mt-1 theme-new-upload">
<i class="upload icon" aria-hidden="true"></i>
{{ _("New upload") }}
</a>
Expand Down Expand Up @@ -146,7 +146,7 @@ <h1 class="ui medium header mb-0">{{ community.metadata.title }}</h1>
</div>
<div class="ui divider mobile only"></div>
<div
class="ui container secondary pointing stackable menu page-subheader pl-0 pr-0">
class="ui container secondary pointing stackable menu page-subheader pl-0 pr-0 theme-menu-items">
{% for item in current_menu.submenu('communities').children if (item.permissions == True or permissions[item.permissions]) and item.visible %}
<a
class="item {{ 'active' if active_community_header_menu_item == item.name }} {{ 'disabled' if not item.url }}"
Expand Down
22 changes: 21 additions & 1 deletion invenio_communities/views/communities.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from copy import deepcopy

from flask import current_app, g, render_template
from flask import current_app, g, render_template, stream_template_string
from flask_login import login_required
from invenio_i18n import lazy_gettext as _
from invenio_records_resources.services.errors import PermissionDeniedError
Expand Down Expand Up @@ -400,3 +400,23 @@ def communities_curation_policy(pid_value, community, community_ui):
community=community_ui,
permissions=permissions,
)


@pass_community(serialize=False)
def community_theme_css_config(pid_value, community):
"""Community brand theme view to serve css config."""

theme_config = community.data.get("theme", {}).get("config")

if theme_config is None:
template = ""
else:
template = render_template(
"invenio_communities/community_theme_template.css", theme=theme_config
)

return (
template,
200,
{"Content-Type": "text/css; charset=utf-8"},
)
7 changes: 7 additions & 0 deletions invenio_communities/views/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from ..searchapp import search_app_context
from .communities import (
communities_about,
community_theme_css_config,
communities_curation_policy,
communities_frontpage,
communities_new,
Expand Down Expand Up @@ -179,6 +180,12 @@ def create_ui_blueprint(app):

blueprint.add_url_rule(routes["invitations"], view_func=invitations)

# theme injection view
blueprint.add_url_rule(
"/communities/<pid_value>/brand_theme.css",
view_func=community_theme_css_config,
)

@blueprint.before_app_first_request
def register_menus():
"""Register community menu items."""
Expand Down

0 comments on commit f8ef68e

Please sign in to comment.