Powering Views Through Panels
One of difficulties of Drupal is the fragmentation of administration interfaces. Chapter Three addresses this difficulty by customizing the administration experience by championing the Panels as The Administrative Interface.
A Real World Example
Note: I wasn't able to record audio to this video, the 'click track' is a bug from my video capturing software. The video shows me changing the view's style plugin via a customized Panels interface.
One of our clients wanted the ability to decide if their data would show in a one, two, or three column display. We had three options:
- Train the user on the Views to change the display setting to grid
- Make more view displays to go with the options (requiring more than 50 displays, in this case)
- Customize the administration process to allow this feature
On this particular project, option three was the right choice. We were already exposing the Panels interface, so we could reuse what we already had. We decided to change the view based on a panel setting.
Three Easy Steps
- Make sure you have Content Pane view displays to play with
- Use hook_form_alter() to offer the option in the Panels settings form
- Use Views' alter hooks to pragmatically change the view depending on the options
1. Creating Content Panes
Creating content panes is out of the scope of this post, but it’s easy. The cool kids at Node One have a video tutorial walking you through the process.
2. Offering The Option
This step is a straight forward use of hook_form_alter();
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #007700">function </span><span style="color: #0000BB">c3_example_form_alter</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form</span><span style="color: #007700">, </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">, </span><span style="color: #0000BB">$form_id</span><span style="color: #007700">) {<br> switch (</span><span style="color: #0000BB">$form_id</span><span style="color: #007700">) {<br> case </span><span style="color: #0000BB">‘views_content_views_panes_content_type_edit_form’</span><span style="color: #007700">:<br> </span><span style="color: #FF8000">// Get the pane configuration<br> </span><span style="color: #0000BB">$conf </span><span style="color: #007700">= </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">[</span><span style="color: #0000BB">‘conf’</span><span style="color: #007700">];<br><br> </span><span style="color: #FF8000">// Add our column configuration item<br> </span><span style="color: #0000BB">$form</span><span style="color: #007700">[</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">] = array(<br> </span><span style="color: #DD0000">'#type' </span><span style="color: #007700">=> </span><span style="color: #DD0000">'select'</span><span style="color: #007700">,<br> </span><span style="color: #DD0000">'#options' </span><span style="color: #007700">=> array( </span><span style="color: #0000BB">1 </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'1 Column'</span><span style="color: #007700">), </span><span style="color: #0000BB">2 </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'2 Columns'</span><span style="color: #007700">), </span><span style="color: #0000BB">3 </span><span style="color: #007700">=> </span><span style="color: #0000BB">t</span><span style="color: #007700">(</span><span style="color: #DD0000">'3 Columns'</span><span style="color: #007700">) ),<br> </span><span style="color: #DD0000">'#default_value' </span><span style="color: #007700">=> </span><span style="color: #0000BB">$conf</span><span style="color: #007700">[</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">] ? </span><span style="color: #0000BB">$conf</span><span style="color: #007700">[</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">] : </span><span style="color: #0000BB">1</span><span style="color: #007700">,<br> );<br><br> </span><span style="color: #FF8000">// Add our submit handler to capture our option<br> </span><span style="color: #0000BB">$form</span><span style="color: #007700">[</span><span style="color: #DD0000">'#submit'</span><span style="color: #007700">][] = </span><span style="color: #DD0000">'c3_example_views_content_views_pane_submit'</span><span style="color: #007700">; <br> break;<br> }<br>}<br><br></span><span style="color: #0000BB">?></span></span>
We also need to make sure we are storing our option in pane configurations:
<span style="color: #000000"><span style="color: #0000BB"><?php<br> </span><span style="color: #007700">function </span><span style="color: #0000BB">c3_example_views_content_views_pane_submit</span><span style="color: #007700">(&</span><span style="color: #0000BB">$form</span><span style="color: #007700">, &</span><span style="color: #0000BB">$form_state</span><span style="color: #007700">) {<br> </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">[</span><span style="color: #DD0000">'conf'</span><span style="color: #007700">][</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">] = </span><span style="color: #0000BB">$form_state</span><span style="color: #007700">[</span><span style="color: #DD0000">'values'</span><span style="color: #007700">][</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">];<br> } <br></span><span style="color: #0000BB">?></span></span>
3. Changing the View
Now we act upon the set options. The life stages of a view are handy to know:
- Initialize sets up the the view object
- Build builds the query
- Execute executes the query
- Render renders the results into HTML
Views follows the Drupal event model and allows modules to alter the view during this lifecycle. Depending on the options you are supplying, you figure out where in the lifecycle you want to change the view. Anything you can do in the Views UI is programmatically possible. Any option in the Views UI can be exposed to your client.
In our example, our column option doesn’t change the SQL query so we can interrupt the view after it has been executed but before HTML is rendered.
We write code that programmatically sets the view style to Grid and sets the number of columns. You’ll notice that we have access to the pane configuration in $view->display_handler->options[‘pane_conf’]. That is what using Content Panes display type gives us.
<span style="color: #000000"><span style="color: #0000BB"><?php<br></span><span style="color: #007700">function </span><span style="color: #0000BB">c3_example_views_pre_render</span><span style="color: #007700">(&</span><span style="color: #0000BB">$view</span><span style="color: #007700">) {<br> </span><span style="color: #FF8000">// Grab the view object in the pane configuration<br> </span><span style="color: #0000BB">$conf </span><span style="color: #007700">= </span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">display_handler</span><span style="color: #007700">-></span><span style="color: #0000BB">options</span><span style="color: #007700">[</span><span style="color: #DD0000">'pane_conf'</span><span style="color: #007700">];<br> <br> </span><span style="color: #FF8000">// Now change our view based on the pane configuration<br> // In the case, we set the display plugin to ‘Grid’ and set the appropriate number of columns<br> </span><span style="color: #007700">if (</span><span style="color: #0000BB">$conf</span><span style="color: #007700">[</span><span style="color: #0000BB">‘view</span><span style="color: #007700">-</span><span style="color: #0000BB">columns’</span><span style="color: #007700">] > </span><span style="color: #0000BB">1</span><span style="color: #007700">) { <br> </span><span style="color: #FF8000">// We have to reset the style_plugin since init_style() has already been called. <br> // TODO: There maybe a more appropriate place to attach to alter the view. <br> </span><span style="color: #007700">unset(</span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">plugin_name</span><span style="color: #007700">);<br> unset(</span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">style_plugin</span><span style="color: #007700">);<br><br> </span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">display_handler</span><span style="color: #007700">-></span><span style="color: #0000BB">set_option</span><span style="color: #007700">(</span><span style="color: #DD0000">'style_plugin'</span><span style="color: #007700">, </span><span style="color: #DD0000">'grid'</span><span style="color: #007700">);<br> </span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">display_handler</span><span style="color: #007700">-></span><span style="color: #0000BB">set_option</span><span style="color: #007700">(</span><span style="color: #DD0000">'style_options'</span><span style="color: #007700">, array(</span><span style="color: #DD0000">'columns' </span><span style="color: #007700">=> </span><span style="color: #0000BB">$conf</span><span style="color: #007700">[</span><span style="color: #DD0000">'view-columns'</span><span style="color: #007700">]));<br><br> </span><span style="color: #0000BB">$view</span><span style="color: #007700">-></span><span style="color: #0000BB">init_style</span><span style="color: #007700">();<br> }<br>}<br></span><span style="color: #0000BB">?></span></span>
This is just one example of what you can do with Panels setting interface. We really like the one-to-one metaphor of Panels and Panels In Place Editor. We think it's smart, accessible and the future of website building.