Views
#####
.. contents:: Contents
:local:
:depth: 1
Introduction
============
Elgg follows a MVC pattern and Views are the V in MVC. Views are responsible for creating the output. Generally, this will be HTML sent to a web browser, but it could also be RSS, JSON or any number of other data formats.
The Views system handles everything from the layout of pages and chunks of presentation output (like a footer or a toolbar) down to individual links and form inputs. It also allows for advanced features like automatic RSS generation, a swift-to-develop mobile interface, and the alternative interfaces suggested below.
Using views
===========
At their most basic level, the default views are just PHP files with snippets of html. For example:
.. code-block:: html
Hello, World!
Assuming this view is located at ``/views/default/hello.php``, we could output it like so:
.. code-block:: php
echo elgg_view('hello');
For your convenience, Elgg comes with quite a lot of views by default. In order to keep things manageable, they are organized into subdirectories. Elgg handles this situation quite nicely. For example, our simple view might live in ``/views/default/hello/world.php``, in which case it would be called like so:
.. code-block:: php
echo elgg_view('hello/world');
Well that's easy enough to remember! The name of the view simply reflects the location of the view in the views directory.
Views as templates
==================
Views would be pretty useless if they could only contain static information. Fortunately, you can pass arbitrary data to a view via the ``$vars`` array. Our ``hello/world`` view might be modified to accept a variable like so:
.. code-block:: php
Hello, !
In this case, we can pass an arbitrary name parameter to the view like so:
.. code-block:: php
echo elgg_view('hello/world', array('name' => 'World'));
which would produce the following output:
.. code-block:: html
Hello, World!
.. _guides/views#viewtypes:
Viewtypes
=========
You might be wondering, "what's with the 'default' in the directory structure? Why don't we just put the ``hello/world`` view at ``/views/hello/world.php``?".
Great question.
This subdirectory (the one under ``/views``) determines the *viewtype* of the views below it. It's possible that you might want your Elgg site to have several sets of interface pages. For example:
* Standard HTML for desktop browsing (This is the default view)
* HTML optimized for Mobile devices (iPhone, Android, Blackberry, etc.)
* HTML optimized Tablet devices (iPad, etc.)
* RSS
* Atom
* JSON
* etc...
In Elgg, one set of these interface pages is called a *viewtype*. You can force Elgg to use a particular viewtype to render the page simply by setting the ``$view`` input variable. For example, to get an RSS version of the home page, you would access ``http://localhost/elgg/?view=rss``.
You could also write a plugin to set this automatically using the ``set_input()`` function. For example, your plugin might detect that the page was accessed with an iPhone's browser string, and set the viewtype to *handheld* by calling:
.. code-block:: php
set_input('view', 'handheld');
The plugin would presumably also supply a set of views optimized for handheld devices.
.. _guides/views#altering-views-via-plugin:
Altering views via plugins
==========================
Without modifying Elgg's core, Elgg provides several ways to customize almost all output:
* You can `override a view <#overriding-views>`_, completely changing the file used to render it.
* You can `extend a view <#extending-views>`_ by prepending or appending the output of another view to it.
* You can `alter a view's inputs <#altering-view-input>`_ by plugin hook.
* You can `alter a view's output <#altering-view-output>`_ by plugin hook.
Overriding views
----------------
Via plugin you can completely replace the rendering strategy of a view provided by Elgg or another plugin. Each plugin may have its own ``/views`` directory, and within it define its own view implementations.
Views in plugin directories always override views in the core directory, however, when plugins override the views of other plugins, :ref:`later plugins take precedent `.
For example, if we wanted to customize the ``hello/world`` view to use an ``h2`` instead of an ``h1``, we could create a file at ``/mod/example/views/default/hello/world.php`` like this:
.. code-block:: php
Hello,
While it is **not recommended**, one *could* alternatively force the location of a view using the ``set_view_location`` function:
.. code-block:: php
set_view_location($view_name, $full_path_to_view_file);
Again, the best way to override views is to place them in the appropriate place in the views hierarchy.
.. note::
When considering long-term maintenance, overriding views in the core and bundled plugins has a cost: Upgrades may bring changes in views, and if you have overridden them, you will not get those changes. You may instead want to :ref:`alter the input ` or the :ref:`the output ` of the view via plugin hooks.
.. note::
Elgg caches view locations. This means that you should disable the system cache while working with views. When you install the changes to a production environment you mush flush the caches.
Extending views
---------------
There may be other situations in which you don't want to override the whole view, you just want to prepend or append some more content to it. In Elgg this is called *extending* a view.
For example, instead of overriding the ``hello/world`` view, we could extend it like so:
.. code-block:: php
elgg_extend_view('hello/world', 'hello/greeting');
If the contents of ``/views/default/hello/greeting.php`` is:
.. code-block:: php
How are you today?
Then every time we call ``elgg_view('hello/world');``, we'll get:
.. code-block:: html