Пример #1
0
    def include(self, callable, route_prefix=None):
        """Include a configuration callables, to support imperative
        application extensibility.

        .. warning:: In versions of :app:`Pyramid` prior to 1.2, this
            function accepted ``*callables``, but this has been changed
            to support only a single callable.

        A configuration callable should be a callable that accepts a single
        argument named ``config``, which will be an instance of a
        :term:`Configurator`  (be warned that it will not be the same
        configurator instance on which you call this method, however).  The
        code which runs as the result of calling the callable should invoke
        methods on the configurator passed to it which add configuration
        state.  The return value of a callable will be ignored.

        Values allowed to be presented via the ``callable`` argument to
        this method: any callable Python object or any :term:`dotted Python
        name` which resolves to a callable Python object.  It may also be a
        Python :term:`module`, in which case, the module will be searched for
        a callable named ``includeme``, which will be treated as the
        configuration callable.
        
        For example, if the ``includeme`` function below lives in a module
        named ``myapp.myconfig``:

        .. code-block:: python
           :linenos:

           # myapp.myconfig module

           def my_view(request):
               from pyramid.response import Response
               return Response('OK')

           def includeme(config):
               config.add_view(my_view)

        You might cause it be included within your Pyramid application like
        so:

        .. code-block:: python
           :linenos:

           from pyramid.config import Configurator

           def main(global_config, **settings):
               config = Configurator()
               config.include('myapp.myconfig.includeme')

        Because the function is named ``includeme``, the function name can
        also be omitted from the dotted name reference:

        .. code-block:: python
           :linenos:

           from pyramid.config import Configurator

           def main(global_config, **settings):
               config = Configurator()
               config.include('myapp.myconfig')

        Included configuration statements will be overridden by local
        configuration statements if an included callable causes a
        configuration conflict by registering something with the same
        configuration parameters.

        If the ``route_prefix`` is supplied, it must be a string.  Any calls
        to :meth:`pyramid.config.Configurator.add_route` within the included
        callable will have their pattern prefixed with the value of
        ``route_prefix``. This can be used to help mount a set of routes at a
        different location than the included callable's author intended while
        still maintaining the same route names.  For example:
            
        .. code-block:: python
           :linenos:

           from pyramid.config import Configurator

           def included(config):
               config.add_route('show_users', '/show')
               
           def main(global_config, **settings):
               config = Configurator()
               config.include(included, route_prefix='/users')

        In the above configuration, the ``show_users`` route will have an
        effective route pattern of ``/users/show``, instead of ``/show``
        because the ``route_prefix`` argument will be prepended to the
        pattern.

        The ``route_prefix`` parameter is new as of Pyramid 1.2.
        """

        _context = self._ctx
        if _context is None:
            _context = self._ctx = self._make_context(self.autocommit)

        if self.route_prefix:
            old_prefix = self.route_prefix.rstrip('/') + '/'
        else:
            old_prefix = ''

        if route_prefix:
            route_prefix = old_prefix + route_prefix.lstrip('/')

        c = self.maybe_dotted(callable)
        module = inspect.getmodule(c)
        if module is c:
            c = getattr(module, 'includeme')
        spec = module.__name__ + ':' + c.__name__
        sourcefile = inspect.getsourcefile(c)
        if _context.processSpec(spec):
            context = GroupingContextDecorator(_context)
            context.basepath = os.path.dirname(sourcefile)
            context.includepath = _context.includepath + (spec,)
            context.package = package_of(module)
            context.route_prefix = route_prefix
            config = self.__class__.with_context(context)
            c(config)