Custom Code in PHPtemplate

The following functions were added to PHPtemplate in the lasqueti theme to obtain the required functionality.  Some of these should probably be made into a custom module.

Custom Node (page) titles using images

see: HowTo: Replace node title with a related image | drupal.org

<code>

// This function is used to substitue the node title with an image of the same name.
// Really good candidate to turn into a small module.
function _phptemplate_variables($hook, $vars = array()) {
  switch ($hook) {
    case 'page':
    // substitute node title with an image, if a suitable replacement can be found.
    // save original title text for use in head and breadcrumb.
    $vars['breadcrumb_title'] = $vars['title'];
    $vars['head_title'] = $vars['title'];
    // Substitute title only for nodes...
    if (arg(0) == 'node' && is_numeric(arg(1))) {
      $node = node_load(arg(1));  // (expensive, unless arg(1) is already loaded, which is should be at this point.)
      // ... of one of the listed types - add node types to process to the array.
      if (in_array($node->type, array('page', 'page_layout_b'))) {
        // convert title to suitable filename and derive both file system path and URL.
        $titleFile = clean_title($vars['title']) . '.gif';
        $titleImage = base_path() . "files/images/titles/" . $titleFile;
        $titleURL = "http://" . $_SERVER['SERVER_NAME'] . $titleImage;
        $titlePath = $_SERVER['DOCUMENT_ROOT'] . $titleImage;
        // $vars['title'] = $titleURL;   // DEBUG - see what's being produced

        // Determine if a suitable replacement image for title can be found, and make substitution.
        if ( file_exists($titlePath) ) {
          $newTitle = '<img alt=\'' . $vars['title'] .'\' src=\'' . $titleURL .'\' />';
          $vars['title'] = $newTitle;
        }
      }
    }
    break;
  }
 
  return $vars;
}

// Prepare some general title text for use as a file name.
// Remove special HTML characters, trim whitespace, convert to lower-case
// repace spaces with underscores.
function clean_title($string)
{
    $cleanString = htmlspecialchars_decode( strtolower(trim($string)), ENT_QUOTES );
    $cleanString = str_replace(array("& ", "'"), '', $cleanString);
    // $string = strtolower(preg_replace("/[^a-zA-Z0-9 ]/", "", $string));  // slower, but more general purpose.
    return str_replace(' ', '_', $cleanString );;

}
</code>

Custom Theming for Summary Views

<code>
 
// Create a mock-menu from a view's summary (usually for a block view)
// See Example: How to Display a Summary View as a Mock Menu http://drupal.org/node/42605
function _summary_menu($view, $level, $nodes) {
  foreach ($nodes as $node) {
    $list .= '<li class="leaf">' . views_get_summary_link($view->argument[$level]['type'], $node, $view->real_url) . "</li>\n";
  }

  if ($list) {
    return "<div class='menu'><ul>$list</ul></div>";
  }
}

// Photo albums are per-user, so agrument is user ID UID
function phptemplate_views_summary_photo_albums($view, $type, $level, $nodes, $args) {
  if ($type == 'block') {
    return _summary_menu($view, $level, $nodes);
  }
  else {
    drupal_add_css(drupal_get_path('theme', 'lasqueti') .'/css/image_gallery.css', 'theme');
    // Need generic way to get image file info? - must use name of CCK field.
    // Replace this with the name of your image field.
    // Uncomment the print_r below to figure out what it is.
    $cck_fid_field = 'node_data_field_image_field_image_fid';
    $content .= '<ul class="galleries">';
    $title = "'s Personal Photo Album";
    $baseUrl = $view->url;
    // Build a small, single node teaser for each query in the summary and
    //   use it as a link to the actual view page with that argument.
    foreach ($nodes as $query) { 
       // Get the argument for this view from the query.
       $uid = $query->uid;     // argument is user id;
       $user = $query->name;   // query also has user's name.
       // Build a 1 item query to grab the first node in this view
       $result = views_build_view('items', $view, array($uid), false, 1);

       // Grab the image from that node to display in our summary.
       // The file id comes from the node info. we got back from views.
       // print_r($result['items'][0]);
       $fid = $result['items'][0]->$cck_fid_field;
       $modDate = $result['items'][0]->node_changed;

       // Query the database to get the file object
       $file = _imagefield_file_load($fid);
       $imgTag = theme('imagecache', 'Thumbnail', $file['filepath'], 'Latest image from gallery', $user . $title);

       $url= $baseUrl .'/'. $uid;
       $linkText = $imgTag .' '. $user . $title;
       $content .= _theme_gallery_summary($imgTag, $url, $user.$title, $query->num_nodes, $modDate, NULL);
     }
    $content .= "</ul>\n";

    return $content;
  }
}

// Produce the themed output for the image gallery summary.
// This code was ripped from the image gallery module.
function _theme_gallery_summary($imgTag, $url, $title, $count, $modDate, $description=NULL)
{
   $content = "";
   $content .= '<li class="clear-block">';
   if ($count>0) {
     $content .= l($imgTag, $url, array(), NULL, NULL, FALSE, TRUE);
   }
   $content .= "<h3>". l($title, $url) ."</h3>\n";
   if ($description) {
      $content .= '<div class="description">'. check_markup($description) ."</div>\n";
   }
   $content .= '<p class="count">'. format_plural($count, 'There is 1 photo in this gallery', 'There are @count photos in this gallery') ."</p>\n";
   if ($modDate) {
     $content .= '<p class="last">'. t('Last updated: %date', array('%date' => format_date($modDate))) ."</p>\n";
   }
   $content .= "</li>\n";
   return $content;
}

// Photo galleries are per-term, so argument is taxonomy term.
function phptemplate_views_summary_photo_gallery($view, $type, $level, $nodes, $args) {
  if ($type == 'block') {
    return _summary_menu($view, $level, $nodes);
  }
  else {
    drupal_add_css(drupal_get_path('theme', 'lasqueti') .'/css/image_gallery.css', 'theme');
    // Need generic way to get image file info? - must use name of CCK field.
    // Replace this with the name of your image field.
    // Uncomment the print_r below to figure out what it is.
    $cck_fid_field = 'node_data_field_image_field_image_fid';
    $content .= '<ul class="galleries">';
    $title = " Photo Gallery";
    $baseUrl = $view->url;
   
    // Build a small, single node teaser for each query in the summary and
    //   use it as a link to the actual view page with that argument.
    foreach ($nodes as $query) { 

       // Get the gallery description from the term's vocab.
       $term = $query->letter;  // argument for taxonomy terms;
       $tid = $query->tid;      // term IS the argument!
       $termObj = taxonomy_get_term($tid);
       $description = $termObj->description;
       
       // Build a 1 item query to grab the first node in this view
       $result = views_build_view('items', $view, array($term), false, 1);

       // Grab the image from that node to display in our summary.
       // The file id comes from the node info. we got back from views.
       // print_r($result['items'][0]);
       $fid = $result['items'][0]->$cck_fid_field;
       $modDate = $result['items'][0]->node_changed;

       $file = _imagefield_file_load($fid);
       $imgTag = theme('imagecache', 'Thumbnail', $file['filepath'], 'Latest image from gallery', $term . $title);

       $url= $baseUrl .'/'. $term;
       $linkText = $imgTag .' '. $term . $title;
       $content .= _theme_gallery_summary($imgTag, $url, $term.$title, $query->num_nodes, $modDate, $description);
     }
     $content .= "</ul>\n";

     return $content;
  }
}

Theme the node add / edit forms for custom CCK types

    This simply addes a collapsible fieldset for the CCK fields in the "Market Page" type, and hides the Categories fieldset from non-admins, to try to improve useability. See http://drupal.org/node/101092#comment-748013 for details.

function phptemplate_page_layout_b_node_form($form) {
  // Collapse the taxonomoy fieldset by default (as this rarely changes).
  $form['taxonomy']['#collapsed'] = true;
 
  // enforce crude access rights on the taxonomy terms.
  global $user;
  if (!($user->uid==1 || in_array('contributor',$user->roles)) ) {
    unset($form['taxonomy']);
  }
  // These are the fields that should be in the fieldset
  $fields = array('field_teaser_image', 'field_bio_image', 'field_bio');
 
  // Add fieldsets to the page_layout_b input form & render it.
    _add_fieldset($form, 'Images', $fields);
    return drupal_render($form);
}

/**
 * Add the given fields to a new fieldset on the form.
 * @form - the form to add the fieldset to
 * @name - a string name of the fieldset
 * @fieldsInSet - field ids (names) for the fields in
 *     the form that should go into the fieldset.
 */

function _add_fieldset(&$form, $name, $fieldsInSet) {
  // Add a fieldset to the form to hold related fields.
  $form[$name] = array (
     '#type'        => 'fieldset',
     '#title'       => $name,
     '#collapsible' => 1,
     '#collapsed'   => 0,
     '#weight'      => -2,
     '#tree'        => 1,
  );
 
  // Move all the related fields into the new fieldset.
  foreach ($fieldsInSet as $field) {
    if ($form[$field]) {
      $form[$name][$field] = $form[$field];
      $form[$name][$field]['#parents'] = array ($name, $field);
      unset($form[$field]);
    }
  }
}

Custom theme the book navigation links.

    When a node's page is viewed in a tab, we don't want to show any book navigation.

function phptemplate_book_navigation($node) {
  if ($node->inTab)
    return NULL;
  else
    return theme_book_navigation($node);
}
 

Custom display of Views exposed filter

  Exposed filters allow the user to have control over what nodes are viewed by selecting from a widget.  The default layout is to have the widget displayed above the view, in the page - yuck - very ugly and poor usability.   This  "snippet" hides the default exposed filter for a view with the name "test" - it can be copied for any View where you want to do this.  Then a custom block is created to display the exposed filter widget off to the side, or "rolled-up"!  Much nicer.
See http://www.angrydonuts.com/displaying_views_exposed_filters

function phptemplate_views_display_filters_test() {
    // Do absolutely nothing.
  }