0

I'm trying to build a custom responsive theme using Zurb Foundation. I'm also using Views to render a grid of nodes, let's call them Events, that are each wrapped in Foundation classes to lay them out in a responsive grid.

The Problem:

The Foundation classes I need to use need to change based on the visible regions on the page.

For example, if the sidebar_first region is showing, each item in the events list needs to have the classes: columns large-4 medium-6 small-6.

If the sidebar is not rendered, each item needs the classes: columns large-3 medium-4 small-6.

I cannot find a way to evaluate which regions will be rendered at the time the View is being built. I'm currently using template_preprocess_views_view_unformatted() to add the Foundation classes to the Views template, however this hook is being fired well before template_preprocess_page() for example, where I might be able to evaluate the visible regions and set a variable with information about the sidebar.

See the below pseudo code for the ideal structure when the sidebar is rendered:

<div class="row">
  <div class="region-content columns large-9">
    <div class="row">
      <div class="views-row columns large-4">...</div>
      <div class="views-row columns large-4">...</div>
      <div class="views-row columns large-4">...</div>
      ...
    </div>
  </div>
  <div class="region-sidebar-first columns large-3">...</div>
</div>

See the below pseudo code for the ideal structure when the sidebar is not rendered:

<div class="row">
  <div class="region-content columns large-12">
    <div class="row">
      <div class="views-row columns large-3">...</div>
      <div class="views-row columns large-3">...</div>
      <div class="views-row columns large-3">...</div>
      <div class="views-row columns large-3">...</div>
      ...
    </div>
  </div>
</div>

Ideally, without the sidebar rendered the events will be 4 across spanning all 12 columns. With the sidebar rendered they will be 3 across spanning only 9 columns, as the above classes in the pseudo code imply.

4
  • I don't know if you would have access to the correct variables in a Views pre-process function, but this could be done with a bit of JS.
    – Geoff
    Commented Dec 24, 2014 at 2:06
  • Delay the rendering of the view and do it manually with views_embed_view or equivalent when you are ready to do so. Commented Dec 24, 2014 at 4:19
  • @J.Reynolds that is certainly an option. At the moment the view is being rendered as a page display of the main view, so I would have to render the view in a node page or something in order to delay.
    – ffnathan
    Commented Dec 24, 2014 at 18:19
  • @Geoff that will also work. I'm going to exhaust my PHP options before I resort to JS though :)
    – ffnathan
    Commented Dec 24, 2014 at 18:20

1 Answer 1

1

I must be addicted to Drupal because it is Christmas and I'm working on this, but here goes.

Delete the page display of your view so that only the master display is left. Then create a custom module with this code in it. (I created a module 'custom', my view is called 'zurb', and my path is 'zurb').

In custom module:

function custom_menu(){
  $items['zurb'] = array(
    'page callback' => 'custom_zurb_callback',
    'access callback' => true,
  );
  return $items;
}

function custom_zurb_callback(){
  $view = array(
    '#theme' => 'render_view',
    '#view' => 'zurb',
  );
  return $view;
}

function custom_theme(){
  return array(
    'render_view' => array(
      'variables' => array(
        'view' => NULL,
        'display' => 'default',
        'args' => array(),
        'regions' => array(),
      ),
    ),
  );
}

function theme_render_view($variables){
  $view = views_get_view($variables['view']);
  $view->set_display($variables['display']);
  $view->set_arguments($variables['args']);
  $view->pre_execute();
  $view->custom_regions = $variables['regions'];
  $view->execute();
  return $view->render();
}

function custom_preprocess_page(&$vars){
    if (current_path() == 'zurb' && count($vars['page']['sidebar_first'])) {
      $regions = array();
      $regions[] = 'sidebar-first';
      $vars['page']['content']['system_main']['#regions'] = $regions;
    }
}

Now in your views template file or views preprocess function you can access $view->custom_regions.

Perhaps there is a better way to pass the $regions to the view than adding it as a member on the $view object, but I don't see it being a problem. If it is a concern you can always just use drupal_static

This code is also re-usable as it uses a theme function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.