Skip to content
Open
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
16 changes: 16 additions & 0 deletions src/onegov/core/framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from functools import cached_property, wraps
from itsdangerous import BadSignature, Signer
from libres.db.models import ORMBase
from morepath import dispatch_method
from morepath.publish import resolve_model, get_view_name
from more.content_security import ContentSecurityApp
from more.content_security import ContentSecurityPolicy
Expand All @@ -46,6 +47,8 @@
from more.webassets import WebassetsApp
from more.webassets.core import webassets_injector_tween
from more.webassets.tweens import METHODS, CONTENT_TYPES
from reg import ClassIndex

from onegov.core import cache, log, utils
from onegov.core import directives
from onegov.core.crypto import stored_random_token
Expand All @@ -68,6 +71,7 @@


from typing import overload, Any, Literal, TypeVar, TYPE_CHECKING

if TYPE_CHECKING:
from _typeshed import StrPath
from _typeshed.wsgi import WSGIApplication, WSGIEnvironment, StartResponse
Expand Down Expand Up @@ -1552,6 +1556,18 @@
self.hashed_identity_key
).decrypt(cyphertext).decode('utf-8')

@dispatch_method('model')
def get_layout_class(self, model: object) -> type | None:
return None


@Framework.predicate(Framework.get_layout_class, name='model', default=None, index=ClassIndex)

Check failure on line 1564 in src/onegov/core/framework.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (E501)

src/onegov/core/framework.py:1564:80: E501 Line too long (94 > 79)
def model_predicate(self, model: object) -> type:
# return model if isinstance(model, type) else model.__class__
retval = model if isinstance(model, type) else model.__class__
print('*** tschupre model predicate called for object:', model, 'retval:', retval)

Check failure on line 1568 in src/onegov/core/framework.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (E501)

src/onegov/core/framework.py:1568:80: E501 Line too long (86 > 79)

Check failure on line 1568 in src/onegov/core/framework.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (T201)

src/onegov/core/framework.py:1568:5: T201 `print` found
return retval


@Framework.webasset_url()
def get_webasset_url() -> str:
Expand Down
10 changes: 8 additions & 2 deletions src/onegov/org/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from more.content_security import NONE
from more.content_security.core import content_security_policy_tween_factory
from onegov.core import Framework, utils
from onegov.core.framework import default_content_security_policy
from onegov.core.framework import default_content_security_policy, model_predicate

Check failure on line 15 in src/onegov/org/app.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (E501)

src/onegov/org/app.py:15:80: E501 Line too long (82 > 79)
from onegov.core.i18n import default_locale_negotiator
from onegov.core.orm.cache import orm_cached, request_cached
from onegov.core.templates import PageTemplate, render_template
Expand All @@ -24,6 +24,7 @@
from onegov.org.auth import MTANAuth
from onegov.org.exceptions import MTANAccessLimitExceeded
from onegov.org.initial_content import create_new_organisation
from onegov.org.layout import Layout, DefaultLayout
from onegov.org.models import Dashboard, Organisation, PublicationCollection
from onegov.org.request import OrgRequest
from onegov.org.theme import OrgTheme
Expand Down Expand Up @@ -69,7 +70,6 @@
event_search_widget = directive(directives.EventSearchWidgetAction)
settings_view = directive(directives.SettingsView)
boardlet = directive(directives.Boardlet)
layout = directive(directives.Layout)

#: cronjob settings
send_ticket_statistics = True
Expand Down Expand Up @@ -492,6 +492,12 @@
return URL(request.link(dashboard)).path()


@OrgApp.predicate_fallback(OrgApp.get_layout_class, model_predicate)
def model_not_found(self, model: object) -> type[Layout]:
print('*** tschupre using DEFAULTLAYOUT ORG for model', model)

Check failure on line 497 in src/onegov/org/app.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (T201)

src/onegov/org/app.py:497:5: T201 `print` found
return DefaultLayout


@OrgApp.webasset_path()
def get_shared_assets_path() -> str:
return utils.module_path('onegov.shared', 'assets/js')
Expand Down
27 changes: 0 additions & 27 deletions src/onegov/org/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,30 +293,3 @@ def perform( # type:ignore[override]
'order': self.order,
'icon': self.icon,
}


class Layout(Action):
"""
Registers a layout for a model. This is used to show breadcrumbs
for search results.
"""

config = {
'layout_registry': dict
}

def __init__(self, model: type) -> None:
self.model = model

def identifier( # type:ignore[override]
self,
layout_registry: dict[type, Layout]
) -> str:
return str(self.model)

def perform( # type:ignore[override]
self,
layout: Layout,
layout_registry: dict[type, Layout]
) -> None:
layout_registry[self.model] = layout
14 changes: 2 additions & 12 deletions src/onegov/org/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,16 +289,6 @@ def get_layout(self, model: object) -> Layout | DefaultLayout:
"""
Get the registered layout for a model instance.
"""
layout_registry = self.app.config.layout_registry
model_type = model if isinstance(model, type) else type(model)

layout_class = None
for cls in model_type.mro():
layout_class = layout_registry.get(cls)
if layout_class:
break

if layout_class is None:
layout_class = DefaultLayout

layout_class = self.app.get_layout_class(model)
assert layout_class is not None
return layout_class(model, self)
11 changes: 10 additions & 1 deletion src/onegov/town6/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from sedate import replace_timezone

from onegov.api import ApiApp
from onegov.core import utils
from onegov.core import utils, Framework

Check failure on line 9 in src/onegov/town6/app.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onegov/town6/app.py:9:32: F401 `onegov.core.Framework` imported but unused
from onegov.core.framework import model_predicate
from onegov.core.i18n import default_locale_negotiator
from onegov.core.templates import render_template
from onegov.core.utils import module_path
Expand All @@ -30,6 +31,7 @@
from onegov.core.types import RenderData
from onegov.org.exceptions import MTANAccessLimitExceeded
from onegov.org.models import Organisation
from onegov.town6.layout import Layout, DefaultLayout

Check failure on line 34 in src/onegov/town6/app.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onegov/town6/app.py:34:45: F401 `onegov.town6.layout.DefaultLayout` imported but unused
from onegov.town6.request import TownRequest


Expand Down Expand Up @@ -76,6 +78,13 @@
return False


@TownApp.predicate_fallback(TownApp.get_layout_class, model_predicate)
def model_not_found(self, model: object) -> type[Layout]:
print('*** tschupre using DEFAULTLAYOUT TOWN6 for model', model)

Check failure on line 83 in src/onegov/town6/app.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (T201)

src/onegov/town6/app.py:83:5: T201 `print` found
from onegov.town6.layout import DefaultLayout
return DefaultLayout


@TownApp.webasset_path()
def get_shared_assets_path() -> str:
return utils.module_path('onegov.shared', 'assets/js')
Expand Down
35 changes: 16 additions & 19 deletions src/onegov/town6/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import secrets
from functools import cached_property

from onegov.core import Framework

Check failure on line 6 in src/onegov/town6/layout.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onegov/town6/layout.py:6:25: F401 `onegov.core.Framework` imported but unused
from onegov.core.elements import Confirm, Intercooler, Link, LinkGroup
from onegov.core.static import StaticFile
from onegov.core.utils import append_query_param, to_html_ul
from onegov.chat.collections import ChatCollection
from onegov.chat.models import Chat
from onegov.directory import DirectoryCollection, DirectoryEntry, Directory

Check failure on line 12 in src/onegov/town6/layout.py

View workflow job for this annotation

GitHub Actions / Lint

Ruff (F401)

src/onegov/town6/layout.py:12:51: F401 `onegov.directory.DirectoryEntry` imported but unused
from onegov.event import Event
from onegov.event import OccurrenceCollection, Occurrence
from onegov.org.elements import QrCodeLink, IFrameLink
Expand Down Expand Up @@ -288,7 +289,6 @@
request: TownRequest


@TownApp.layout(model=Topic)
class PageLayout(OrgTopicLayout, AdjacencyListLayout):

app: TownApp
Expand All @@ -301,7 +301,6 @@
)


@TownApp.layout(model=News)
class NewsLayout(OrgNewsLayout, AdjacencyListLayout):

app: TownApp
Expand Down Expand Up @@ -416,7 +415,6 @@
request: TownRequest


@TownApp.layout(model=FormDefinition)
class FormDefinitionLayout(OrgFormDefinitionLayout, DefaultLayout):

app: TownApp
Expand All @@ -442,7 +440,6 @@
request: TownRequest


@TownApp.layout(model=Person)
class PersonLayout(OrgPersonLayout, DefaultLayout):

app: TownApp
Expand All @@ -461,7 +458,6 @@
request: TownRequest


@TownApp.layout(model=Ticket)
class TicketLayout(OrgTicketLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -574,7 +570,6 @@
request: TownRequest


@TownApp.layout(model=Resource)
class ResourceLayout(OrgResourceLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -655,7 +650,6 @@
return links


@TownApp.layout(model=Occurrence)
class OccurrenceLayout(OrgOccurrenceLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -686,7 +680,6 @@
cls_before='EventLayout',
cls_after='TicketChatMessageLayout'
)
@TownApp.layout(model=Event)
class EventLayout(StepsLayoutExtension, OrgEventLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -727,7 +720,6 @@
request: TownRequest


@TownApp.layout(model=ImageSet)
class ImageSetLayout(OrgImageSetLayout, DefaultLayout):

app: TownApp
Expand All @@ -740,7 +732,6 @@
request: TownRequest


@TownApp.layout(model=User)
class UserLayout(OrgUserLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -798,7 +789,6 @@
request: TownRequest


@TownApp.layout(model=Directory)
class DirectoryLayout(OrgDirectoryLayout, DefaultLayout):

app: TownApp
Expand Down Expand Up @@ -932,7 +922,6 @@


@step_sequences.registered_step(1, _('Form'), cls_after='FormSubmissionLayout')
@TownApp.layout(model=DirectoryEntry)
class DirectoryEntryLayout(
StepsLayoutExtension,
OrgDirectoryEntryLayout,
Expand Down Expand Up @@ -968,7 +957,6 @@
request: TownRequest


@TownApp.layout(model=GeneralFile)
class GeneralFileCollectionLayout(DefaultLayout):

def __init__(self, model: Any, request: TownRequest) -> None:
Expand Down Expand Up @@ -1146,7 +1134,6 @@
return None


@TownApp.layout(model=Meeting)
class MeetingLayout(DefaultLayout):

@cached_property
Expand Down Expand Up @@ -1216,7 +1203,6 @@
return None


@TownApp.layout(model=MeetingItem)
class MeetingItemLayout(DefaultLayout):

@cached_property
Expand Down Expand Up @@ -1275,7 +1261,6 @@
return None


@TownApp.layout(model=RISParliamentarian)
class RISParliamentarianLayout(DefaultLayout):

@cached_property
Expand Down Expand Up @@ -1457,7 +1442,6 @@
return None


@TownApp.layout(model=RISParliamentaryGroup)
class RISParliamentaryGroupLayout(DefaultLayout):

@cached_property
Expand Down Expand Up @@ -1593,7 +1577,6 @@
return None


@TownApp.layout(model=RISCommission)
class RISCommissionLayout(DefaultLayout):

@cached_property
Expand Down Expand Up @@ -1686,7 +1669,21 @@
return None


@TownApp.layout(model=PoliticalBusiness)
def register_layout_for(model):
def decorator(cls):
@TownApp.get_layout_class.register(model=model)
def _factory(self, model: object):
print(f'*** tschupre matched! Returning {cls.__name} for {model}')
return cls

# Debug: verify registration happened
print(f'*** tschupre registered {cls.__name__} for {model}')

return cls
return decorator


@register_layout_for(PoliticalBusiness)
class PoliticalBusinessLayout(DefaultLayout):

@cached_property
Expand Down
Loading