You are here

README.txt in Persistent URL 6

Same filename and directory in other branches
  1. 7 README.txt
Persistent URL for Drupal 6.x


Installation
------------

PURL can be installed like any other Drupal module -- place it in the
`sites/all/modules` (or a site or profile specific module directory) directory
for your site and enable it on the `admin/build/modules` page.

PURL is an API module. It does absolutely nothing for the end user out of the
box without other modules that take advantage of its API.


Core concepts behind PURL
-------------------------

The mission of PURL is to provide an API for other modules to manipulate and
respond to portions of an HTTP request that are not captured by the core
Drupal menu system. By default, the Drupal menu system reacts to only one part
of a request: $_GET['q']. PURL aims to be a pluggable system for reacting to
parts of $GET['q'] but many others as well.

Other than the "normal" drupal path, here are some parts of a request that a
PURL provider may respond to:

  Mozilla    http:// foobar.baz.com / group-a / node/5 ? foo=bar
    |                   |               |         |         |
    |                   |               |         |         |
  User agent     Subdomain/Domain     Prefix      |    Query string
                                                  |
                                        ("Normal" drupal path)

Any modules using the PURL API must define one or more providers.

- A provider is a single concept for responding to or modifying a request.
  Examples: `spaces_og` activates group contexts, `views_modes` sets an active
  views style plugin, `locale` (if it were to use PURL) would activate the
  active language.

- A method is the means by which a provider is activated and modifies a
  request. The parts of the request, like user agent, prefix, query string,
  etc. are all examples of methods.

- A modifier is an id/value pair designated by a provider to trigger a response
  if found in the provider's method. Often modifiers map string aliases to an
  id, like ['mygroup', 5] (where 'mygroup' is the group's path and 5 is the
  group's node id). Other times, there is no reasonable mapping and a provider
  will want the literal value found in the request. These modifiers simply use
  the same string for the id and value, e.g. ['mozilla', 'mozilla']. 

One of PURLs goals is to make it possible for providers to be written to be
independent of the method that it uses. For example, `spaces_og` can activate
a group space when it finds a group identifier as a path prefix,
or a subdomain, or a specified query string, etc. depending on the method that
has been assigned to it by PURL.

The big picture is that PURL allows administrators to assign each provider a
method, and any time a valid modifier is found in a request for that given
method the provider is given a chance to respond via a callback function.

Example provider/method setup:

+---------------+--------------------------------+----------------------+
| Provider      | Method                         | Example modifier     |
+---------------+--------------------------------+----------------------+
| spaces_og     | Path prefix                    | ['mygroup', 5]       |
| views_modes   | Query string, key: 'viewstyle' | ['list', 'list']     |
| iphone_custom | Subdomain                      | ['iphone', 'iphone'] |
+---------------+--------------------------------+----------------------+

A sample URL which would trigger *all* of the providers above:

  http://iphone.foobar.com/mygroup/page-listing?viewstyle=list

**Responding**

When a modifier for a provider is found in a request, the provider's registered
callback is called with the ID for the given modifier. To continue with the
example from above, the callback for provider `spaces_og` will be passed `5`,
the id corresponding to the `mygroup`, and it is then the provider's job to do
whatever it wants to do with that information. `spaces_og`, for example, will
load node `5` and set it as the active group context.

Depending on the method (e.g. any that involve $_GET['q']), PURL may remove the
modifier for the rest of the page load so that the request is passed cleanly to
the rest of the Drupal menu stack. While the original request above would have
had the path `mygroup/page-listing`, PURL will strip `mygroup` leaving the rest
of Drupal to think that the page's path is `page-listing`.

**Modifying**

Depending on the PURL method, outgoing requests may be automatically rewritten
to sustain the modifier found in the incoming request. In the example above,
any paths pushed through `url()` will be given the additional path prefix of
`mygroup`. Thus all links on the page and even requests like form autocomplete
AJAX calls will be prefixed.


API usage: General
------------------

These instructions are for general usage of the PURL API.

Since the scope of PURL goes beyond $_GET['q'], PURL provides several
additional options to the `$options` array passed to `url()` and its derivate
`l()`. These options can also be passed to `purl_goto()`, a wrapper around
`drupal_goto()` that allows an `$options` array to be passed (which
`drupal_goto()` does not allow out of the box).

PURL extends the `$options` array in four ways:

1. If `$options['purl']['disabled']` is true none of the detected and removed
   path modifications will be re-instated. This allows you to drop all PURL
   modifications. Example:

   // On a page with PURL modifiers like `mygroup/node/43?viewstyle=list`,
   // generate a URL to node/43 that drops all PURL modifiers. The resulting
   // URL will point at just `node/43`.

   l('Foobar', 'node/43', array('purl' => array('disabled' => TRUE)));

2. $options['purl']['remove'] can be set to an array of providers which should
   be dropped, while others are maintained. Setting this when
   $options['purl']['disabled'] is true is redundant. Example:

   // On a page with PURL modifiers like `mygroup/node/43?viewstyle=list`,
   // generate a URL to node/43 that drops only the specified PURL modifier.
   // The resulting URL will point at `node/43?viewstyle=list`.

   l('Foobar', 'node/43', array('purl' => array('remove' => array('spaces_og'))));

3. $options['purl']['provider'] and $options['purl']['id'] can be used
   together to set a specific modification to the link.

   // Generate a URL that includes a specific PURL modifier. Note that this
   // should always be used in favor of generating an absolute URL manually
   // as callers should not assume that a provider is using a specific method.
   // Assuming that the modifier is ['mygroup', 5], The resulting URL will
   // point at `mygroup/node/43`

   l('Foobar', 'node/43', array('purl' => array('provider' => 'spaces_og', 'id' => 5)));

4. $options['purl]['add'] can be used to add a set of id's and provider's to
   the link.

   // Generate a URL that adds one or more PURL modifiers, including any that
   // are active for the current request. On a page with PURL modifiers like
   // `mygroup/node/43`, the following will result in a URL that points at
   // `mygroup/node/43?viewstyle=list`.

   l('Foobar', 'node/43', array('purl' => array('add' => array('provider' => 'views_modes', 'id' => 'list'))));

The `l()` function is used in all of the examples above, but the same options
array can be passed to `url()` or `purl_goto()` to capture the equivalent
behavior. For example:

   // Go to `mygroup/node/43`.

   purl_goto('node/43', array('purl' => array('provider' => 'spaces_og', 'id' => 5)));


API usage: Providers
--------------------

These instructions are for modules that would like to respond to or modify
requests using PURL. First, read `purl.api.php` for documentation on the
various hooks called by PURL.

1. Add an implementation of `hook_purl_provider()` to your module.

2. Add a callback function that will be passed the ID of any modifiers found
   by PURL to your module.

3. If your module expects a static set of modifiers or will store and retrieve
   modifiers using its own storage, implement hook_purl_modifiers() to tell
   PURL about modifiers that are valid for your provider.

   OR

   If you would like to store modifiers in PURL's database table, you may want
   to add the elements provided by `purl_form()` to the form for your node,
   user, term, or other element associated with your modifier. You will need to
   implement basic CRUD for the PURL modifier in your form's submit handler -
   see `purl_save()`.

4. Go to `admin/settings/purl` and choose a method to use with your provider.

5. Make a request to your Drupal site that uses a valid modifier and test.


Maintainers
-----------
yhahn (Young Hahn)
jmiccolis (Jeff Miccolis)


Contributors
------------
Ian Ward
dmitrig01 (Dmitri Gaskin)

File

README.txt
View source
  1. Persistent URL for Drupal 6.x
  2. Installation
  3. ------------
  4. PURL can be installed like any other Drupal module -- place it in the
  5. `sites/all/modules` (or a site or profile specific module directory) directory
  6. for your site and enable it on the `admin/build/modules` page.
  7. PURL is an API module. It does absolutely nothing for the end user out of the
  8. box without other modules that take advantage of its API.
  9. Core concepts behind PURL
  10. -------------------------
  11. The mission of PURL is to provide an API for other modules to manipulate and
  12. respond to portions of an HTTP request that are not captured by the core
  13. Drupal menu system. By default, the Drupal menu system reacts to only one part
  14. of a request: $_GET['q']. PURL aims to be a pluggable system for reacting to
  15. parts of $GET['q'] but many others as well.
  16. Other than the "normal" drupal path, here are some parts of a request that a
  17. PURL provider may respond to:
  18. Mozilla http:// foobar.baz.com / group-a / node/5 ? foo=bar
  19. | | | | |
  20. | | | | |
  21. User agent Subdomain/Domain Prefix | Query string
  22. |
  23. ("Normal" drupal path)
  24. Any modules using the PURL API must define one or more providers.
  25. - A provider is a single concept for responding to or modifying a request.
  26. Examples: `spaces_og` activates group contexts, `views_modes` sets an active
  27. views style plugin, `locale` (if it were to use PURL) would activate the
  28. active language.
  29. - A method is the means by which a provider is activated and modifies a
  30. request. The parts of the request, like user agent, prefix, query string,
  31. etc. are all examples of methods.
  32. - A modifier is an id/value pair designated by a provider to trigger a response
  33. if found in the provider's method. Often modifiers map string aliases to an
  34. id, like ['mygroup', 5] (where 'mygroup' is the group's path and 5 is the
  35. group's node id). Other times, there is no reasonable mapping and a provider
  36. will want the literal value found in the request. These modifiers simply use
  37. the same string for the id and value, e.g. ['mozilla', 'mozilla'].
  38. One of PURLs goals is to make it possible for providers to be written to be
  39. independent of the method that it uses. For example, `spaces_og` can activate
  40. a group space when it finds a group identifier as a path prefix,
  41. or a subdomain, or a specified query string, etc. depending on the method that
  42. has been assigned to it by PURL.
  43. The big picture is that PURL allows administrators to assign each provider a
  44. method, and any time a valid modifier is found in a request for that given
  45. method the provider is given a chance to respond via a callback function.
  46. Example provider/method setup:
  47. +---------------+--------------------------------+----------------------+
  48. | Provider | Method | Example modifier |
  49. +---------------+--------------------------------+----------------------+
  50. | spaces_og | Path prefix | ['mygroup', 5] |
  51. | views_modes | Query string, key: 'viewstyle' | ['list', 'list'] |
  52. | iphone_custom | Subdomain | ['iphone', 'iphone'] |
  53. +---------------+--------------------------------+----------------------+
  54. A sample URL which would trigger *all* of the providers above:
  55. http://iphone.foobar.com/mygroup/page-listing?viewstyle=list
  56. **Responding**
  57. When a modifier for a provider is found in a request, the provider's registered
  58. callback is called with the ID for the given modifier. To continue with the
  59. example from above, the callback for provider `spaces_og` will be passed `5`,
  60. the id corresponding to the `mygroup`, and it is then the provider's job to do
  61. whatever it wants to do with that information. `spaces_og`, for example, will
  62. load node `5` and set it as the active group context.
  63. Depending on the method (e.g. any that involve $_GET['q']), PURL may remove the
  64. modifier for the rest of the page load so that the request is passed cleanly to
  65. the rest of the Drupal menu stack. While the original request above would have
  66. had the path `mygroup/page-listing`, PURL will strip `mygroup` leaving the rest
  67. of Drupal to think that the page's path is `page-listing`.
  68. **Modifying**
  69. Depending on the PURL method, outgoing requests may be automatically rewritten
  70. to sustain the modifier found in the incoming request. In the example above,
  71. any paths pushed through `url()` will be given the additional path prefix of
  72. `mygroup`. Thus all links on the page and even requests like form autocomplete
  73. AJAX calls will be prefixed.
  74. API usage: General
  75. ------------------
  76. These instructions are for general usage of the PURL API.
  77. Since the scope of PURL goes beyond $_GET['q'], PURL provides several
  78. additional options to the `$options` array passed to `url()` and its derivate
  79. `l()`. These options can also be passed to `purl_goto()`, a wrapper around
  80. `drupal_goto()` that allows an `$options` array to be passed (which
  81. `drupal_goto()` does not allow out of the box).
  82. PURL extends the `$options` array in four ways:
  83. 1. If `$options['purl']['disabled']` is true none of the detected and removed
  84. path modifications will be re-instated. This allows you to drop all PURL
  85. modifications. Example:
  86. // On a page with PURL modifiers like `mygroup/node/43?viewstyle=list`,
  87. // generate a URL to node/43 that drops all PURL modifiers. The resulting
  88. // URL will point at just `node/43`.
  89. l('Foobar', 'node/43', array('purl' => array('disabled' => TRUE)));
  90. 2. $options['purl']['remove'] can be set to an array of providers which should
  91. be dropped, while others are maintained. Setting this when
  92. $options['purl']['disabled'] is true is redundant. Example:
  93. // On a page with PURL modifiers like `mygroup/node/43?viewstyle=list`,
  94. // generate a URL to node/43 that drops only the specified PURL modifier.
  95. // The resulting URL will point at `node/43?viewstyle=list`.
  96. l('Foobar', 'node/43', array('purl' => array('remove' => array('spaces_og'))));
  97. 3. $options['purl']['provider'] and $options['purl']['id'] can be used
  98. together to set a specific modification to the link.
  99. // Generate a URL that includes a specific PURL modifier. Note that this
  100. // should always be used in favor of generating an absolute URL manually
  101. // as callers should not assume that a provider is using a specific method.
  102. // Assuming that the modifier is ['mygroup', 5], The resulting URL will
  103. // point at `mygroup/node/43`
  104. l('Foobar', 'node/43', array('purl' => array('provider' => 'spaces_og', 'id' => 5)));
  105. 4. $options['purl]['add'] can be used to add a set of id's and provider's to
  106. the link.
  107. // Generate a URL that adds one or more PURL modifiers, including any that
  108. // are active for the current request. On a page with PURL modifiers like
  109. // `mygroup/node/43`, the following will result in a URL that points at
  110. // `mygroup/node/43?viewstyle=list`.
  111. l('Foobar', 'node/43', array('purl' => array('add' => array('provider' => 'views_modes', 'id' => 'list'))));
  112. The `l()` function is used in all of the examples above, but the same options
  113. array can be passed to `url()` or `purl_goto()` to capture the equivalent
  114. behavior. For example:
  115. // Go to `mygroup/node/43`.
  116. purl_goto('node/43', array('purl' => array('provider' => 'spaces_og', 'id' => 5)));
  117. API usage: Providers
  118. --------------------
  119. These instructions are for modules that would like to respond to or modify
  120. requests using PURL. First, read `purl.api.php` for documentation on the
  121. various hooks called by PURL.
  122. 1. Add an implementation of `hook_purl_provider()` to your module.
  123. 2. Add a callback function that will be passed the ID of any modifiers found
  124. by PURL to your module.
  125. 3. If your module expects a static set of modifiers or will store and retrieve
  126. modifiers using its own storage, implement hook_purl_modifiers() to tell
  127. PURL about modifiers that are valid for your provider.
  128. OR
  129. If you would like to store modifiers in PURL's database table, you may want
  130. to add the elements provided by `purl_form()` to the form for your node,
  131. user, term, or other element associated with your modifier. You will need to
  132. implement basic CRUD for the PURL modifier in your form's submit handler -
  133. see `purl_save()`.
  134. 4. Go to `admin/settings/purl` and choose a method to use with your provider.
  135. 5. Make a request to your Drupal site that uses a valid modifier and test.
  136. Maintainers
  137. -----------
  138. yhahn (Young Hahn)
  139. jmiccolis (Jeff Miccolis)
  140. Contributors
  141. ------------
  142. Ian Ward
  143. dmitrig01 (Dmitri Gaskin)