コード例 #1
0
def kotti_configure(settings):

    nav_settings = navigation_settings(settings=settings)

    # Assign slots. The top location is not a slot. It is handled specially.
    for slot in [u'left', u'right',
                 u'abovecontent', u'belowcontent', u'beforebodyend']:

        display_type = nav_settings['{0}_display_type'.format(slot)]

        if display_type and display_type != 'none':

            if 'hor_' in display_type or display_type == 'ver_list':

                view_name = 'navigation-widget-items-{0}'.format(slot)

            elif 'ver_' in display_type:

                view_name = 'navigation-widget-tree-{0}'.format(slot)

            elif display_type == 'breadcrumbs':

                view_name = 'navigation-widget-breadcrumbs-{0}'.format(slot)

            elif display_type == 'menu':

                view_name = 'navigation-widget-menu-{0}'.format(slot)

            assign_slot(view_name, slot)

    settings['pyramid.includes'] += ' kotti_navigation.include_navigation'

    # We override nav.pt.
    settings['kotti.asset_overrides'] += ' kotti_navigation:kotti-overrides/'
コード例 #2
0
ファイル: widgets.py プロジェクト: j23d/kotti_etherpad
def include_protocol_widget(config, where='right'):
    config.add_view(
        render_protocol_widget,
        name='render-protocol-widget',
        renderer='templates/protocol_widget.pt',
        )
    assign_slot('render-protocol-widget', where)
コード例 #3
0
ファイル: views.py プロジェクト: tojuhaka/kotti_discussion
def includeme(config):
    includeme_edit(config)
    includeme_view(config)

    config.registry.registerAdapter(CommentableDocument, (IDocument,), ICommentable)

    from kotti.views.slots import assign_slot
    config.scan(__name__)
    assign_slot('view_discussion', 'belowcontent')
コード例 #4
0
ファイル: views.py プロジェクト: castaf/kotti_panels
def includeme(config):

    config.scan(__name__)

    # Assign each view to the slot with the same name
    for name in ('left', 'right', 'abovecontent', 'belowcontent',
                 'beforebodyend', ):

        assign_slot(name, name, params=None)
コード例 #5
0
ファイル: widget.py プロジェクト: j23d/kotti_tagcloud
def set_assigned_slot(event):
    """Reset the widget to the choosen slot."""

    # Check if the settings for this module was saved.
    if not event.module == __package__:
        return

    slot = get_setting('slot', u'left')
    remove_from_slots('tagcloud-widget')
    assign_slot('tagcloud-widget', slot)
コード例 #6
0
ファイル: test_util_views.py プロジェクト: Doik/Kotti
    def test_slot_request_has_registry(self):
        from kotti.views.slots import assign_slot

        def my_viewlet(request):
            assert hasattr(request, 'registry')
            return Response(u"Hello world!")
        assign_slot('my-viewlet', 'right')

        self.config.add_view(my_viewlet, name='my-viewlet')
        api = self.make()
        assert api.slots.right == [u"Hello world!"]
コード例 #7
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_assign_to_slots(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            greeting = request.POST['greeting']
            return Response(u"{0} world!".format(greeting))
        config.add_view(foo, name='foo')
        assign_slot('foo', 'left', params=dict(greeting=u"Y\u0153"))

        api = self.make()
        assert api.slots.left == [u"Y\u0153 world!"]
コード例 #8
0
ファイル: views.py プロジェクト: cullerton/kotti_feed
def includeme(config):  # pragma: no cover
    config.add_view(rss_view, name='rss_view', permission='view')

    config.add_view(rss_head_link, name='rss-head-link',
                    renderer='templates/rss-head-link.pt')
    assign_slot('rss-head-link', 'inhead')

    config.add_view(rss_icon, name='rss-icon',
                    renderer='templates/rss-icon.pt')
    assign_slot('rss-icon', 'abovecontent')

    config.add_static_view('static-kotti_feed', 'kotti_feed:static')
コード例 #9
0
ファイル: navigation.py プロジェクト: adamchainz/Kotti
def includeme_local_navigation(config):
    """ Pyramid includeme hook.

    :param config: app config
    :type config: :class:`pyramid.config.Configurator`
    """

    # Import is needed in function scope to resolve circular imports caused by
    # compatibility imports in slots.py.
    from kotti.views.slots import assign_slot
    config.scan(__name__)
    assign_slot('local-navigation', 'right')
コード例 #10
0
ファイル: test_util_views.py プロジェクト: Kotti/Kotti
    def test_assign_to_slots(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            greeting = request.POST["greeting"]
            return Response("{} world!".format(greeting))

        config.add_view(foo, name="foo")
        assign_slot("foo", "left", params=dict(greeting="Y\u0153"))

        api = self.make()
        assert api.slots.left == ["Y\u0153 world!"]
コード例 #11
0
ファイル: config.py プロジェクト: rkintzi/KottiSnippets
def _register_slot(config, view_name, slots):
    if not slots:
        raise ConfigurationError("Parameter `slots' may not be empty")
    if view_name in registered_slots:
        raise ConfigurationError("There are slots already registerd "
            "for view `%s'" % view_name)
    for name, title in list(slots):
        if name not in registered_slots_names:
            params = dict(slot_name = name)
            assign_slot('kottisnippets-render-list', name, params=params)
            registered_slots_names.add(name)
    registered_slots[view_name] = slots
コード例 #12
0
ファイル: widget.py プロジェクト: j23d/kotti_grid
def set_assigned_slot(event):
    """Reset the widget to the choosen slot."""

    # Check if the settings for this module was saved.
    if not event.module == __package__:  # pragma: no cover
        return

    slot = get_setting("slot", u"left")
    names = [name[0] for name in slot_names]

    remove_from_slots("grid-widget")
    assign_slot("grid-widget", slot)
コード例 #13
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_slot_request_has_attributes(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def my_viewlet(request):
            assert hasattr(request, 'registry')
            assert hasattr(request, 'context')
            assert hasattr(request, 'user')
            return Response(u"Hello world!")
        assign_slot('my-viewlet', 'right')

        config.add_view(my_viewlet, name='my-viewlet')
        api = self.make()
        assert api.slots.right == [u"Hello world!"]
コード例 #14
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_slot_request_has_parameters(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            bar = request.POST['bar']
            return Response(u"{0} world!".format(bar))
        config.add_view(foo, name='foo')
        assign_slot('foo', 'left', params=dict(greeting=u"Y\u0153"))

        request = DummyRequest()
        request.params['bar'] = u'Hello'
        api = self.make(request=request)
        assert api.slots.left == [u"Hello world!"]
コード例 #15
0
ファイル: __init__.py プロジェクト: geojeff/kotti_newsitem
def kotti_configure(settings):

    settings['pyramid.includes'] += ' kotti_newsitem'
    settings['kotti.available_types'] += ' kotti_newsitem.resources.NewsItem'

    if 'kotti_newsitem.widget.num_news' in settings:
        settings['kotti_newsitem.widget.num_news'] = int(
            settings['kotti_newsitem.widget.num_news'])
    else:
        settings['kotti_newsitem.widget.num_news'] = 5

    if 'kotti_newsitem.widget.slot' in settings:
        assign_slot('recent_news', settings['kotti_newsitem.widget.slot'])
コード例 #16
0
    def test_slot_request_has_parameters(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            bar = request.POST["bar"]
            return Response("{} world!".format(bar))

        config.add_view(foo, name="foo")
        assign_slot("foo", "left", params=dict(greeting="Y\u0153"))

        request = DummyRequest()
        request.params["bar"] = "Hello"
        api = self.make(request=request)
        assert api.slots.left == ["Hello world!"]
コード例 #17
0
ファイル: test_util_views.py プロジェクト: Kotti/Kotti
    def test_slot_request_has_parameters(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            bar = request.POST["bar"]
            return Response("{} world!".format(bar))

        config.add_view(foo, name="foo")
        assign_slot("foo", "left", params=dict(greeting="Y\u0153"))

        request = DummyRequest()
        request.params["bar"] = "Hello"
        api = self.make(request=request)
        assert api.slots.left == ["Hello world!"]
コード例 #18
0
ファイル: test_util_views.py プロジェクト: Kotti/Kotti
    def test_slot_request_has_attributes(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def my_viewlet(request):
            assert hasattr(request, "registry")
            assert hasattr(request, "context")
            assert hasattr(request, "user")
            return Response("Hello world!")

        assign_slot("my-viewlet", "right")

        config.add_view(my_viewlet, name="my-viewlet")
        api = self.make()
        assert api.slots.right == ["Hello world!"]
コード例 #19
0
    def test_slot_request_has_attributes(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def my_viewlet(request):
            assert hasattr(request, "registry")
            assert hasattr(request, "context")
            assert hasattr(request, "user")
            return Response("Hello world!")

        assign_slot("my-viewlet", "right")

        config.add_view(my_viewlet, name="my-viewlet")
        api = self.make()
        assert api.slots.right == ["Hello world!"]
コード例 #20
0
ファイル: test_util_views.py プロジェクト: xiang12383/Kotti
    def test_slot_request_has_attributes(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def my_viewlet(request):
            assert hasattr(request, 'registry')
            assert hasattr(request, 'context')
            assert hasattr(request, 'user')
            return Response(u"Hello world!")

        assign_slot('my-viewlet', 'right')

        config.add_view(my_viewlet, name='my-viewlet')
        api = self.make()
        assert api.slots.right == [u"Hello world!"]
コード例 #21
0
    def test_slot_view_know_slot(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            slot = request.kotti_slot
            return Response(u"I'm in slot {0}.".format(slot))
        config.add_view(foo, name='foo')
        assign_slot('foo', 'beforebodyend')
        assign_slot('foo', 'right')

        request = DummyRequest()
        api = self.make(request=request)
        assert api.slots.beforebodyend == [u"I'm in slot beforebodyend."]
        assert api.slots.right == [u"I'm in slot right."]
コード例 #22
0
ファイル: test_util_views.py プロジェクト: rkintzi/Kotti
    def test_assign_to_slot_predicate_mismatch(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def special(context, request):
            return Response(u"Hello world!")
        assign_slot('special', 'right')

        config.add_view(special, name='special', request_method="GET")
        api = self.make()
        assert api.slots.right == []

        config.add_view(special, name='special')
        api = self.make()
        assert api.slots.right == [u"Hello world!"]
コード例 #23
0
ファイル: test_util_views.py プロジェクト: xiang12383/Kotti
    def test_slot_request_has_parameters(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            bar = request.POST['bar']
            return Response(u"{0} world!".format(bar))

        config.add_view(foo, name='foo')
        assign_slot('foo', 'left', params=dict(greeting=u"Y\u0153"))

        request = DummyRequest()
        request.params['bar'] = u'Hello'
        api = self.make(request=request)
        assert api.slots.left == [u"Hello world!"]
コード例 #24
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_slot_view_know_slot(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            slot = request.kotti_slot
            return Response(u"I'm in slot {0}.".format(slot))
        config.add_view(foo, name='foo')
        assign_slot('foo', 'beforebodyend')
        assign_slot('foo', 'right')

        request = DummyRequest()
        api = self.make(request=request)
        assert api.slots.beforebodyend == [u"I'm in slot beforebodyend."]
        assert api.slots.right == [u"I'm in slot right."]
コード例 #25
0
ファイル: __init__.py プロジェクト: geojeff/kotti_navigation
def kotti_configure(settings):

    nav_settings = navigation_settings(settings=settings)

    slot = nav_settings['slot']
    if slot is None:
        slot = 'none'

    nav_widget_directive = \
            'kotti_navigation.include_navigation_widget_{0}'.format(slot)

    settings['pyramid.includes'] += ' {0}'.format(nav_widget_directive)

    if 'kotti_navigation.widget.slot' in settings:
        assign_slot('recent_news', settings['kotti_newsitem.widget.slot'])
コード例 #26
0
    def test_assign_to_slot_forbidden(self, config, db_session, events):
        from kotti.views.slots import assign_slot
        from pyramid.exceptions import HTTPForbidden

        def special(context, request):
            return Response(u"Hello world!")

        assign_slot('special', 'right')

        config.add_view(special, name='special', permission='admin')
        # the slot rendering must not fail if a HTTPForbidden exception
        api = self.make()
        with patch('kotti.views.slots.render_view') as render_view:
            render_view.side_effect = HTTPForbidden()
            assert api.slots.right == []
コード例 #27
0
ファイル: test_util_views.py プロジェクト: eugeneai/Kotti
    def test_assign_to_slot_predicate_mismatch(self):
        from kotti.views.slots import assign_slot

        def special(context, request):
            return Response(u"Hello world!")

        assign_slot('special', 'right')

        self.config.add_view(special, name='special', request_method="GET")
        api = self.make()
        assert api.slots.right == []

        self.config.add_view(special, name='special')
        api = self.make()
        assert api.slots.right == [u"Hello world!"]
コード例 #28
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_assign_to_slot_forbidden(self, config, db_session,
                                      events):
        from kotti.views.slots import assign_slot
        from pyramid.exceptions import HTTPForbidden

        def special(context, request):
            return Response(u"Hello world!")
        assign_slot('special', 'right')

        config.add_view(special, name='special', permission='admin')
        # the slot rendering must not fail if a HTTPForbidden exception
        api = self.make()
        with patch('kotti.views.slots.render_view') as render_view:
            render_view.side_effect = HTTPForbidden()
            assert api.slots.right == []
コード例 #29
0
    def test_slot_view_know_slot(self, config, db_session):
        from kotti.views.slots import assign_slot

        def foo(context, request):
            slot = request.kotti_slot
            return Response(f"I'm in slot {slot}.")

        config.add_view(foo, name="foo")
        assign_slot("foo", "beforebodyend")
        assign_slot("foo", "right")

        request = DummyRequest()
        api = self.make(request=request)
        assert api.slots.beforebodyend == ["I'm in slot beforebodyend."]
        assert api.slots.right == ["I'm in slot right."]
コード例 #30
0
    def test_assign_to_slot_predicate_mismatch(self, config, db_session, events):
        from kotti.views.slots import assign_slot

        def special(context, request):
            return Response("Hello world!")

        assign_slot("special", "right")

        config.add_view(special, name="special", request_method="GET")
        api = self.make()
        assert api.slots.right == []

        config.add_view(special, name="special")
        api = self.make()
        assert api.slots.right == ["Hello world!"]
コード例 #31
0
def kotti_configure(settings):
    """ Add a line like this to you .ini file::

            kotti.configurators =
                kotti_google_analytics.kotti_configure

        to enable the ``kotti_google_analytics`` add-on.

    :param settings: Kotti configuration dictionary.
    :type settings: dict
    """

    settings['pyramid.includes'] += ' kotti_google_analytics'
    settings['kotti.populators'] += ' kotti_google_analytics.populate.populate'
    settings[
        'kotti.fanstatic.view_needed'] += ' kotti_google_analytics.fanstatic.css_and_js'
    assign_slot('analytics-code', 'belowcontent')
コード例 #32
0
ファイル: util.py プロジェクト: Kotti/kotti_navigation
def set_assigned_slot(event):
    """Reset the widget to the enabled slots."""
    if get_setting(u'left_display_type'):
        if not widget_in_slot('navigation-widget', 'left'):
            assign_slot('navigation-widget', 'left')
    if get_setting(u'right_display_type'):
        if not widget_in_slot('navigation-widget', 'right'):
            assign_slot('navigation-widget', 'right')
    if get_setting(u'abovecontent_display_type'):
        if not widget_in_slot('navigation-widget', 'abovecontent'):
            assign_slot('navigation-widget', 'abovecontent')
    if get_setting(u'belowcontent_display_type'):
        if not widget_in_slot('navigation-widget', 'belowcontent'):
            assign_slot('navigation-widget', 'belowcontent')
    if get_setting(u'beforebodyend_display_type'):
        if not widget_in_slot('navigation-widget', 'beforebodyend'):
            assign_slot('navigation-widget', 'beforebodyend')
コード例 #33
0
ファイル: test_util.py プロジェクト: j23d/kotti_settings
def test_remove_widget_from_slot(config, db_session, events,
                                 dummy_request, root):
    from pyramid.response import Response
    from kotti.views.slots import assign_slot
    from kotti.views.util import TemplateAPI
    from kotti_settings.util import remove_from_slots

    def a_widget(request):
        return Response(u"The widget speaks")
    config.add_view(a_widget, name='a-widget')
    assign_slot('a-widget', 'right')

    api = TemplateAPI(root, dummy_request)
    assert api.slots.right == [u"The widget speaks"]

    remove_from_slots('a-widget')
    api = TemplateAPI(root, dummy_request)
    assert api.slots.right == []
コード例 #34
0
ファイル: populate.py プロジェクト: Kotti/kotti_navigation
def populate():
    add_settings(NavigationSettingsLeft)
    add_settings(NavigationSettingsRight)
    add_settings(NavigationSettingsTop)
    add_settings(NavigationSettingsAboveContent)
    add_settings(NavigationSettingsBelowContent)
    add_settings(NavigationSettingsBeforeBodyEnd)

    if get_setting(u'left_display_type'):
        assign_slot(u'navigation-widget', 'left')
    if get_setting(u'right_display_type'):
        assign_slot(u'navigation-widget', 'right')
    if get_setting(u'abovecontent_display_type'):
        assign_slot(u'navigation-widget', 'abovecontent')
    if get_setting(u'belowcontent_display_type'):
        assign_slot(u'navigation-widget', 'belowcontent')
    if get_setting(u'beforebodyend_display_type'):
        assign_slot(u'navigation-widget', 'beforebodyend')
コード例 #35
0
ファイル: __init__.py プロジェクト: b4oshany/kotti_alert
def kotti_configure(settings):
    """ Add a line like this to you .ini file::

            kotti.configurators =
                kotti_alert.kotti_configure

        to enable the ``kotti_alert`` add-on.

    :param settings: Kotti configuration dictionary.
    :type settings: dict
    """

    settings['pyramid.includes'] += ' kotti_alert'
    settings['kotti.alembic_dirs'] += ' kotti_alert:alembic'
    settings['kotti.available_types'] += ' kotti_alert.resources.Alert'
    settings['kotti.fanstatic.view_needed'] += ' kotti_alert.fanstatic.css_and_js'
    assign_slot('kotti-alert', 'abovecontent')
    CONTROL_PANEL_LINKS.append(Link('all-alerts', title=_(u'Alerts')))
コード例 #36
0
    def test_slots_only_rendered_when_accessed(self, config, events):
        from kotti.views.slots import assign_slot

        called = []

        def foo(context, request):
            called.append(True)
            return Response(u"")

        config.add_view(foo, name='foo')
        assign_slot('foo', 'abovecontent')

        api = self.make()
        api.slots.belowcontent
        assert called == []

        api.slots.abovecontent
        assert len(called) == 1
        api.slots.abovecontent
        assert len(called) == 1
コード例 #37
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_slots_only_rendered_when_accessed(self, config, events):
        from kotti.views.slots import assign_slot

        called = []

        def foo(context, request):
            called.append(True)
            return Response(u"")

        config.add_view(foo, name='foo')
        assign_slot('foo', 'abovecontent')

        api = self.make()
        api.slots.belowcontent
        assert called == []

        api.slots.abovecontent
        assert len(called) == 1
        api.slots.abovecontent
        assert len(called) == 1
コード例 #38
0
ファイル: widget.py プロジェクト: geojeff/kotti_grid
def set_assigned_slot(event):
    """Reset the widget to the choosen slot."""

    # Check if the settings for this module was saved.
    if not event.module == __package__:
        return

    slot = get_setting('slot', u'left')
    names = [name[0] for name in slot_names]

    # This is somewhat awkward. We check all slots if the widget is already
    # set and remove it from the listener before we set it to another one.
    for slot_event in slot_events:
        if slot_event.name not in names:
            continue
        try:
            listener = objectevent_listeners[(slot_event, None)]
        except TypeError:
            listener = None
        if listener is not None:
            for func in listener:
                if func.func_closure[1].cell_contents == 'grid-widget':
                    listener.remove(func)
    assign_slot('grid-widget', slot)
コード例 #39
0
def kotti_configure(settings):

    nav_settings = navigation_settings(settings=settings)

    # Assign slots. The top location is not a slot. It is handled specially.
    for slot in [
            u'left', u'right', u'abovecontent', u'belowcontent',
            u'beforebodyend'
    ]:

        display_type = nav_settings['{0}_display_type'.format(slot)]

        if display_type and display_type != 'none':

            if 'hor_' in display_type or display_type == 'ver_list':

                view_name = 'navigation-widget-items-{0}'.format(slot)

            elif 'ver_' in display_type:

                view_name = 'navigation-widget-tree-{0}'.format(slot)

            elif display_type == 'breadcrumbs':

                view_name = 'navigation-widget-breadcrumbs-{0}'.format(slot)

            elif display_type == 'menu':

                view_name = 'navigation-widget-menu-{0}'.format(slot)

            assign_slot(view_name, slot)

    settings['pyramid.includes'] += ' kotti_navigation.include_navigation'

    # We override nav.pt.
    settings['kotti.asset_overrides'] += ' kotti_navigation:kotti-overrides/'
コード例 #40
0
def includeme_upcoming_events(config):
    assign_slot('upcoming-events', 'right')
コード例 #41
0
    def test_assign_slot_bad_name(self):
        from kotti.views.slots import assign_slot

        with raises(KeyError):
            assign_slot('viewname', 'noslotlikethis')
コード例 #42
0
def includeme_upcoming_events(config):
    config.add_view(upcoming_events,
                    name='upcoming-events',
                    renderer='kotti_calendar:templates/upcoming-events.pt')
    assign_slot('upcoming-events', 'right')
コード例 #43
0
def includeme_previous_events(config):
    config.add_view(previous_events,
                    name='previous-events',
                    renderer='kotti_calendar:templates/previous-events.pt')
    assign_slot('previous-events', 'right')
コード例 #44
0
ファイル: populate.py プロジェクト: geojeff/kotti_grid
def populate():
    add_settings(GridSettings)
    slot = get_setting(u'slot', u'belowcontent')
    assign_slot('grid-widget', slot)
コード例 #45
0
ファイル: test_util_views.py プロジェクト: disko/Kotti
    def test_assign_slot_bad_name(self):
        from kotti.views.slots import assign_slot

        with raises(KeyError):
            assign_slot('viewname', 'noslotlikethis')
コード例 #46
0
ファイル: widgets.py プロジェクト: naterh/kotti_calendar
def includeme_previous_events(config):
    config.add_view(
        previous_events,
        name='previous-events',
        renderer='kotti_calendar:templates/previous-events.pt')
    assign_slot('previous-events', 'right')
コード例 #47
0
ファイル: __init__.py プロジェクト: geojeff/kotti_navigation
def include_navigation_widget(config, where='left'):  # pragma: no cover

    include_view(config)
    if where != 'none':
        assign_slot('navigation-widget', where)
コード例 #48
0
ファイル: navigation.py プロジェクト: nightmarebadger/Kotti
def includeme_local_navigation(config):
    # Import is needed in function scope to resolve circular imports caused by
    # compatibility imports in slots.py.
    from kotti.views.slots import assign_slot
    config.scan(__name__)
    assign_slot('local-navigation', 'right')
コード例 #49
0
def include_profile_widget(config, where='right'):  # pragma: no cover
    config.add_view(render_profile_widget,
                    name='twitter-profile',
                    renderer='templates/profile_widget.pt')
    assign_slot('twitter-profile', where)
コード例 #50
0
def include_search_widget(config, where='right'):  # pragma: no cover
    config.add_view(render_search_widget,
                    name='twitter-search',
                    renderer='templates/search_widget.pt')
    assign_slot('twitter-search', where)