Raptus / raptus.article.core

Provides a configurable article content type (replaces the default Page content type).
0 stars 4 forks source link

Support default Components #5

Closed frisi closed 10 years ago

frisi commented 10 years ago

there are use-cases where components are activated for almost all articles added to the portal. in my case this is raptus.article.teaser for example.

Currently there is an undocumented functionality using the raptus.article.core.interfaces.IDefaultComponents that should be implemented by components that shall be activated by default.

How it this supposed to work?

For integrators, the easiest think would be to add a configuration to the control-panel (or at least to the raptus.artcle properties) where they can choose which components are applied to new articles on creation on a per-site basis.

frisi commented 10 years ago

@skaeser as you have merged my pull requests today, could we have a short discussion on this one too?

skaeser commented 10 years ago

To provide default components named adapters providing IDefaultComponents may be registered which then are looped over in (https://github.com/Raptus/raptus.article.core/blob/master/raptus/article/core/componentsdefault.py) and applied on article creation.

Creating a control panel to select the default components would therefor include writing a dynamic named adapter providing the mentioned interface and the appropriate form and properties field.

frisi commented 10 years ago

thanks for the clarification. some sample code just for reference:

from zope import component
from zope.interface import implements
from raptus.article.core import interfaces

class MyDefaultComponents(object):
    implements(interfaces.IDefaultComponents)
    component.adapts(interfaces.IArticle)

    names = ['teaser.full']

    def __init__(self, context):
        self.context = context

    def getComponents(self):
        result = []

        for name in self.names:
            comp = component.queryAdapter(self.context,
                                          interface=interfaces.IComponent,
                                          name=name,
                                          default=None)
            if comp:
                result.append(comp)
        return result

and apdapter registration:

  <adapter factory=".MyDefaultComponents"
    name="mydefaults" />

i had the idea, to provide a DefaultComponent adapter in raptus.article.core that returns the component that matches the name the adapter is registered under.

this would allow integrators to just provide an adapter registration (without any code) for each component they'd like to be activated by default. eg for setting teaser.full as default component

  <adapter factory="raptus.article.core.componentsdefault.DefaultComponent"
    name="teaser.full" />

something like: components.queryAdapter(self.context, interface=IComponent, name=self.__name__) should do the trick. however, i could not figure out how to access the name an adapter was registered under in the adapter's implementation.

if that is not possible at all, we could pass in the adapter's name in getComponents as a workaround

@skaeser maybe you know how to get the adapter's name? what do you think about the idea of this defaultcomponent adapter?

skaeser commented 10 years ago

I absolutely like the idea.

Getting the adapters name inside an adapter is not possible as far as I know.. we therefor would need to adjust the code in https://github.com/Raptus/raptus.article.core/blob/master/raptus/article/core/componentsdefault.py to either pass the adapters name to getComponents method, this would break existing adapters, which we would have to catch using a try/except or what do you think?

frisi commented 10 years ago

thanks for your feedback @skaeser.

you are right. for exiting adapters that rise a TypeError if called with getComponents('adaptername') we could add a try/except.

on the other hand we could just change the declaration of IDefaultComponent.getComponents and increase the version number to indicate a non-backward compatible change. i'm quite sure apart from you guys at raptus and me (as i now know how to use it) nobody is using this feature by now ;-)

skaeser commented 10 years ago

Another way, which wouldn't break backward compatibility, would be to create a marker interface (say INamedDefaultComponent) and a basic implementation (this would not need any logic at all apart from the interface implementation and adapter constructor) to allow such simple registrations.. All named adapters to this interface would then be iterated over in https://github.com/Raptus/raptus.article.core/blob/master/raptus/article/core/componentsdefault.py

skaeser commented 10 years ago

Implemented and released (2.0) named default component registrations may now be done as followed:

<adapter
    factory="raptus.article.core.componentsdefault.NamedDefaultComponent"
    name="teaser.full" />
frisi commented 10 years ago

Great idea. Thanks!

Für Rechtschreibfehler haftet mein iPhone

Am 28.07.2014 um 08:05 schrieb Simon Käser notifications@github.com:

Implemented and released (2.0) named component registrations may now be done as followed:

<adapter factory="raptus.article.core.componentsdefault.NamedDefaultComponent" name="teaser.full" /> — Reply to this email directly or view it on GitHub.