===============
Virtual Hosting
===============

:Revision: $Id: virtual-hosting.txt 30313 2005-12-05 21:20:03Z dkuhlman $

.. sectnum::    :depth: 4
.. contents::   :depth: 4


This document explains how to deal with inside-out virtual hosting
when building URLs to objects, including breadcrumbs URLs.

Related tickets:

- http://svn.nuxeo.org/trac/pub/ticket/436: "getBaseUrl.py doesn't
  work as expected behind Apache virtual hosts"

- http://svn.nuxeo.org/trac/pub/ticket/654: "Subsites and virtual
  hosting"

These tickets are fixed by using proper methods (portal_url methods) to
get proper paths (relative or not) to objects.

Still, some issues need to be fixed:

- http://svn.nuxeo.org/trac/pub/ticket/847: "Unresolved issues
  when using virtual hosting"


General Case of Virtual Hosting
===============================

The most complex case or need of virtual hosting is the case where
part of the portal is hidden in the URL, and part of the URL is
completely virtual:

- virtual url: ``http://www.site.com/foo/bar/my-folder/my-file``

- Zope absolute path: ``/cps/workspaces/my-folder/my-file``

This can be achieved with a rewrite rule like::

  RewriteRule ^/foo/bar(.*)$ http://localhost:20000/VirtualHostBase/http/%{SERVER_NAME}:80/cps/workspaces/VirtualHostRoot/_vh_foo/_vh_bar/$1 [L,P]


Fundamental concepts
====================

The fundamental concepts manipulated inside CPS are:

- Object's physical path: ('', 'cps', 'workspaces', 'my-folder',
  'my-file')

- Same as a string: ``/cps/workspaces/my-folder/my-file``

- Object's rpath: ``workspaces/my-folder/my-file``

- Object's URL: ``http://www.site.com/foo/bar/my-folder/my-file``

The rpath is the Zope path relative to the portal. It's called
"relativeContentURL" by CMF, but this is wrong as it's not a URL.

An object's URL is only used on output; it's not used for internal
treatments.


Public methods
==============

The only public methods to be used by user code are:

- ``getRpath(ob)``: gets an rpath from an object

- ``ob.absolute_url()`` or ``ob.absolute_url_path()``: get a URL
  from an object.

- ``getUrlFromRpath(rpath)``: get a URL from an rpath.

- ``portal.restrictedTraverse(rpath)``: get an object from an
  .rpath


Internals
=========

OFS.Traversable methods:

- ``absolute_url(self)``:
  ``http://www.site.com/foo/bar/my-folder/my-file``

- ``absolute_url(self, relative=1)``: ``my-folder/my-file``

  This should never be used by user code.

- ``absolute_url_path(self)``: ``/foo/bar/my-folder/my-file``

  This is a valid URL shortened to not use a site specification.

- ``virtual_url_path(self)``: ``my-folder/my-file``

  This should never be used by user code.

- ``getPhysicalPath(self)``:
  ('', 'cps', 'workspaces', 'my-folder', 'my-file').

CMF URLTool methods:

- ``getPortalPath(self)``: ``/cps``

  This method does not take care of virtual hosting.

- ``getRelativeContentPath(self, content)``:
  ('workspaces', 'my-folder', 'my-file')

- ``getRelativeContentURL(self, content)`` or
  ``getRelativeUrl(self, content)``:
  ``workspaces/my-folder/my-file``.

CPS URLTool adds new methods:

- ``getRpath(self, content)``: alias for
  ``getRelativeContentURL(self, content)``
  and ``getRelativeUrl(self, content)``

- ``getBaseUrl(self)``: ``/foo/bar/``

- ``getVirtualRootPhysicalPath(self)``: ('', 'cps', 'workspaces')

  This should never be used by user code (private method)

- ``getVirtualHostPhysicalPath(self)``: ('', 'foo', 'bar').

  This should never be used by user code (private method).

- ``getUrlFromRpath(self, rpath)``:
  returns ``http://www.site.com/foo/bar/my-folder/my-file`` when given
  relative_url ``workspaces/my-folder/my-file``.

- ``getRpathFromPath(self, path)``: returns
  ``workspaces/my-folder/my-file`` with
  path either ('', 'cps', 'workspaces', 'my-folder', 'my-file') or
  ``/cps/workspaces/my-folder/my-file``.

  This is useful to get the object rpath from the object path in
  catalog (``brain.getPath()``).

- ``getBreadCrumbs(self, context=None, only_parents=0)``: returns
  parents, omitting objects that are hidden by virtual hosting,
  and with portal as greater parent.

- ``getBreadCrumbsInfo(self, context=None, only_parents=0, title_size=20)``:
  returns a list of parents info to be presented in a template.
  Info is a dictionary with various information (id, title,
  url...).
