Theme filer

At theme Drupal 7 er en sjov opgave. Ofte kræver det, at du ændre selve html koden for mange af template filerne.
Her under kan du se hvordan mine Drupal theme filer ofte ser ud. Typsik er de renset for en masse unødig kode som jeg ikke behøver.

Template.php

filnavn: template.php

<?php

/**
* Her fjerners class på ul i menuen
*/

function THEME-NAVN_menu_tree($variables) {return "\t<ul>\n" . $variables['tree'] . "\t</ul>\n";}

/**
* Her fjernes class på li i menuen
*/

function THEME-NAVN_menu_link(array $variables) {
 
$element = $variables['element'];
 
$sub_menu = '';

  if (
$element['#below']) {
   
$sub_menu = drupal_render($element['#below']);
  }
 
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return
"\t\t<li>" . $output . $sub_menu . "</li>\n";
}


// Purge needless XHTML stuff.
function THEME-NAVN_process_html_tag(&$vars) {
 
$el = &$vars['element'];

 
// Remove type="..." and CDATA prefix/suffix.
 
unset($el['#attributes']['type'], $el['#value_prefix'], $el['#value_suffix']);

 
// Remove media="all" but leave others unaffected.
 
if (isset($el['#attributes']['media']) && $el['#attributes']['media'] === 'all') {
    unset(
$el['#attributes']['media']);
  }
}
/**
* Her fjernes height på billeder  - vigtigt ved responsive webdesign!
*/
function THEME-NAVN_image($vars) {
 
$attributes = $vars['attributes'];
 
$attributes['src'] = file_create_url($vars['path']);
  foreach (array(
'alt', 'title') as $key) {
    if (isset(
$vars[$key])) {
     
$attributes[$key] = $vars[$key];
    }
  }
  return
'<img' . drupal_attributes($attributes) . ' />';
}
?>

NB! luk IKKE med ?> i template.php

Custom node.tpl til custom node type

Arbejder du med flere content typer, kan det nogen gang være nødvendigt at tilknytte en helt speciel node.tpl.

<?php

function THEME-NAVN_preprocess_page(&$vars) {
   
// - page--example.tpl.php 
 
if (isset($vars['node'])) {
$vars['theme_hook_suggestion'] = 'page__'.$vars['node']->type; //
}
}
?>

Google plus rel=author

<?php
function THEME-NAVN_preprocess_username(&$vars) {
 
// Username is linked, use the link_attributes to inject the rel attribute
 
if (isset($vars['link_path'])) {
   
$vars['link_attributes']['rel'][] = 'author';
  }
 
// Username is NOT linked, use the attributes_array to inject the rel attribute
 
else {
   
$vars['attributes_array']['rel'][] = 'author';
  }
}
?>

Andre ofte anvendte overrides

Påkræver webdesignet at der skal bruges en Regeion inde i noden kan følgende benyttes:
I Template.php indsættes:

<?php
function THEME-NAVN_preprocess_node(&$vars) {
  if (
$blocks = block_get_blocks_by_region('XXX')) {
   
$vars['XXX'] = $blocks;
  }
 }
?>

XXX er navnet på den nye Drupal region! (skal også angives i .info-filen)
I node.tpl.php indsættes den nye region med følgende:

<?php if ($XXX = render($XXX)): ?><?php print $XXX; ?><?php endif; ?>

EDIT:
Har fjernet nedenstående, da det umiddelbart giver mere mening, at skrive .tpl filerne på en overskuelig måde!

<?php
// Minify HTML output.
function THEME-NAVN_process_html(&$vars) {
 
$before = array(
   
"/>\s\s+/",
   
"/\s\s+</",
   
"/>\t+</",
   
"/\s\s+(?=\w)/",
   
"/(?<=\w)\s\s+/"
 
);

 
$after = array('> ', ' <', '> <', ' ', ' ');

 
// Page top.
 
$page_top = $vars['page_top'];
 
$page_top = preg_replace($before, $after, $page_top);
 
$vars['page_top'] = $page_top;

 
// Page content.
 
if (!preg_match('/<pre|<textarea/', $vars['page'])) {
   
$page = $vars['page'];
   
$page = preg_replace($before, $after, $page);
   
$vars['page'] = $page;
  }

 
// Page bottom.
 
$page_bottom = $vars['page_bottom'];
 
$page_bottom = preg_replace($before, $after, $page_bottom);
 
$vars['page_bottom'] = $page_bottom . drupal_get_js('footer');
}
?>

Søgefelt på søgereultatsiden

Formularen kan fjernes ved hjælp af:

<?php
function THEME_page_alter(&$page) {
 
// This assumes everything being output in the "content" page region.
  // Logged in
 
if (!empty($page['content']['system_main']['content']['search_form'])) {
    unset(
$page['content']['system_main']['content']['search_form']);
  }
 
// Not logged in
 
if (!empty($page['content']['system_main']['search_form'])) {
    unset(
$page['content']['system_main']['search_form']);
  }
}
?>

jQuery UI

Tilføj jQuery UI til dit theme via

<?php
drupal_add_library
('system', 'ui');
?>

Tilføj body class efter region

Du kan tilføje din egen Body Class alt efter om der findes en block i en region eller ej.
Her vises den hvis der ikke er noget i!

<?php
function THEME-NAVN_preprocess_html(&$variables) {
if (empty(
$variables['page']['REGION'])) {
$variables['classes_array'][] = 'DIN-NY-BODY-CLASS';
}
}
?>

Form - søgeform og user

<?php
function THEME-NAVN_form_alter(&$form, &$form_state, $form_id) {
  if (
$form_id == 'search_block_form') {
    unset(
$form['search_block_form']['#title_display']);
    unset(
$form['search_block_form']['#theme_wrappers']);
   
$form['search_block_form']['#size'] = 15;
   
$form['search_block_form']['#attributes']['placeholder'] = t('Enter search terms');
   
/*
    $form['actions']['submit']['#type'] = 'image_button';
    $form['actions']['submit']['#src'] = drupal_get_path('theme', 'clean') . '/css/images/imgSearch.png';
    $form['actions']['submit']['#attributes']['alt'] = "Search Button"; //adds an alt attribute to the image button
    */
   
unset($form['actions']['submit']['#value']); // Remove the value attribute from the input tag, since it is not valid when input type = image
   
   
$form['#attributes']['onsubmit'] = "if(this.search_block_form.value=='search'){ alert('Please enter a search'); return false; }"; // Prevent user from searching the default text
 
}

  if (
in_array( $form_id, array( 'user_login', 'user_login_block')))
    {
       
$form['name']['#attributes']['placeholder'] = t( 'Username' );
       
$form['pass']['#attributes']['placeholder'] = t( 'Password' );
    }
}
?>

block.tpl.php

filnavn: block.tpl.php

<section id="block-<?php print $block->module .'-'. $block->delta; ?>" class="block block-<?php print $block->module ?>">
<?php if ($block->subject): ?>
<h3><?php print $block->subject ?></h3>
<?php endif;?>
<?php print $content ?>

</section>

Ved brug af Devel Themer kan det være nødvendigt, at printe Drupal's block ID i kode for at kunne undersøge hvilken block der arbejdes med!

book-all-books-block.tpl.php

filnavn: book-all-books-block.tpl.php

<?php foreach ($book_menus as $book_id => $menu): ?>
<?php print PHP_EOL; ?>
<nav class="book book-<?php print $book_id; ?>">
<?php print render($menu); ?>
</nav>
<?php print PHP_EOL; ?>
<?php endforeach; ?>

Den første class book i nav er for at kunne style alle menuer samtidig!
Man kan altid diskutere hvor mange class og id, man skal benytte i sin HTML. Jeg er bestemt fortaler for så få som muligt. Hvorfor overbrodere sin kode med noget som ikke benyttes?

book-navigation.tpl.php

filnavn: book-navigation.tpl.php

<?php if ($tree || $has_links): ?>
<?php print PHP_EOL; ?><?php print PHP_EOL; ?>
<nav class="book-navigation-<?php print $book_id; ?> book-navigation">
<?php print $tree; ?>
<?php if ($has_links): ?>
<ul class="footer-navigation">
<?php if ($prev_url): ?>
<li><a href="<?php print $prev_url; ?>" class="page-previous" title="<?php print t('Go to previous page'); ?>"><?php print t('‹ ') . $prev_title; ?></a></li>
<?php endif; ?>
<?php if ($parent_url): ?>
<li><a href="<?php print $parent_url; ?>" class="page-up" title="<?php print t('Go to parent page'); ?>"><?php print t('up'); ?></a></li>
<?php endif; ?>
<?php if ($next_url): ?>
<li><a href="<?php print $next_url; ?>" class="page-next" title="<?php print t('Go to next page'); ?>"><?php print $next_title . t(' ›'); ?></a></li>
<?php endif; ?>
</ul>
<?php endif; ?>
</nav>
<?php print PHP_EOL; ?>
<?php endif; ?>

comment-wrapper.tpl.php

filnavn: comment-wrapper.tpl.php

<?php
$comments
= render($content['comments']);
$comment_form = render($content['comment_form']);
?>

<section id="kommentar">
<p class="kommentar-antal"><?php print format_plural($node->comment_count, '1 comment', '@count comments'); ?></p>
  <?php print $comments; ?>
  <?php if ($comment_form): ?>
    <?php print $comment_form; ?>
  <?php endif; ?>
</section>

comment.tpl.php

filnavn: comment.tpl.php

<article>
<header>
  <?php print $picture; ?>
  <?php if ($status == 'comment-unpublished'): ?>
    <div class="unpublished"><?php print t('Unpublished'); ?></div>
  <?php endif; ?>
     <?php print t('Comment by'); ?> <?php print $author; ?>
<div class="kommentar-dato">
<span class="day"><?php print format_date($comment->created, 'custom', "d."); ?></span>
<span class="month"><?php print format_date($comment->created, 'custom', "F"); ?></span>
<span class="year"><?php print format_date($comment->created, 'custom', "Y"); ?></span>
</div>
  </header>
<div class="kommentar">
    <?php
      hide
($content['links']);
      print
render($content);
   
?>

</div>
<footer>
  <?php print render($content['links']) ?>
</footer>
</article>

field-collection.tpl.php

filnavn: field-collection.tpl.php

<?php print render($content); ?>

Fjerner html omkring Field Collection

Hvis der laves en tpl fil som wrapper for hele field-gruppen vil html umiddelbart slå igennem på alle felter ... for at undgå dette kan benytte nedestående:

<?php
function THEME-NAVN_preprocess_field(&$variables, $hook) {
  if (
$variables['element']['#entity_type'] == 'field_collection_item') {
   
// Check if the bundle name (i.e. the field collection field name) is
    // among the theme hook suggestions.
   
$index = array_search('field__' . $variables['element']['#bundle'],
     
$variables['theme_hook_suggestions']);

   
// Remove the bundle theme hook suggestion.
   
if ($index !== false) {
      unset(
$variables['theme_hook_suggestions'][$index]);
    }
  }
}
?>

Modul: https://www.drupal.org/project/field_collection

field-collection-item.tpl.php

<?php print render($content); ?>

field.tpl.php

filnavn: field.tpl.php

<?php print render($item); ?>

Oprettes der field.tpl.php filer til specifikke felter, ser koden ud som følgende:

<div class="fakta">
<?php if (!$label_hidden): ?>
<div class="field-label"<?php print $title_attributes; ?>"><?php print $label ?>:&nbsp;</div>
<?php endif; ?>
<?php foreach ($items as $delta => $item) : ?>
<?php print render($item); ?>
<?php endforeach; ?>
</div>

Ovenstående er koden til en Faktaboks med felt navnet:
field_fakta_boks
- filen hedder:
field--field_fakta_boks.tpl.php

html.tpl.php

filnavn: html.tpl.php

<!DOCTYPE HTML>
<html lang="da" class="no-js">
<head>
<title><?php print $head_title; ?></title>
<meta name="viewport" content="width=device-width, height=device-height">
<script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
<?php print $head; ?>
<?php print $styles; ?>
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
<?php print $page_top; ?>
<?php print $page; ?>
<?php print $page_bottom; ?>
<?php print $scripts; ?>
</body>
</html>

Læg mærke til at jeg printer <?php print $scripts; ?> i bunden af html strukturen. I visse tilfælde er det nødvendigt at indlæse scripts i <head> ... </head> men for det meste giver det god mening, først at hente dem ind til sidst.

Sidst opdateret: 10/6/2014

node.tpl.php

<?php if ($title): ?>
<h1><?php print $title; ?></h1>
<?php endif; ?>
<?php print render($content); ?>

node.tpl.php er her i en meget simpel version, men samtidig giver den rigtig god mening i langt de fleste Drupal hjemmesider.
Denne version kan ikke bruges hvis man skal lave en blog!

Indsæt fields i node.tpl

Vil man indsætte et CCK field direkte i node.tpl.php

<?php print render($content['field_XXX']); ?>

Typisk vælger man at skjule feltet først ved hjælpe af

<?php
    hide
($content['field_del_overskrift']);
?>

Nu kan man frit placere feltet i HTML strukturen.

Dato

Her er datoformat ændret til: "Tirsdag 17/02 2015

<p class="date"><?php print format_date($created, 'custom', 'l d/m Y'); ?></p>

Sidst opdateret

Indsæt sidst opdateret information på siden ved at printe:

<div class="last-updated"><?php if ($submitted) { echo 'Sidst opdateret: ' . date( "j. F Y",$node->changed); } ; ?></div>

Vises kun når man er logget ind

Er der behov for at vise felter, kun for personer der er logget ind i Drupal, kan følgende php benyttes:

<?php
if (user_is_logged_in()) {
 
// Her printes felter til personer der ER logget ind
}
?>

Tjek om der findes indhold i Body feltet

<?php if(!empty($content['body'])) { ?>
<div class="content">
<?php print render($content['body']); ?>
</div>
<?php }?>

Navn på forfatter

// Navn med link
<?php print $name; ?>
// UDEN link
<?php print $node->name; ?>

Udskriv Summary direkte her i node.tpl.php kan gøres med:

<?php print $node->body['und'][0]['summary']; ?>

NB!
Virker det ikke lige i dit theme, kan du undersøge nærmere med:

<?php print_r($node); ?>

theme.js

Filnavn: theme.js

/*global jQuery*/
(function ($) {
    "use strict";
    $(document).ready(function () {

/* Din jQuery kode */

    });
}(jQuery));

page.tpl.php

filnavn: page.tpl.php

<div id="wrap">
<header>
<?php if ($logo): ?>
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo"><img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" /></a>
<?php endif; ?>
<?php if ($site_slogan): ?>
<p class="slogan"><?php echo $site_slogan ?></p>
<?php endif; ?>
<?php print render($page['header']); ?>
</header>
<?php if ($page['sidebar_first']): ?>
<aside class="first">
<?php if ($messages): ?><?php print $messages; ?><?php endif; ?>
<?php print render($page['sidebar_first']); ?>
</aside>
<?php endif; ?>
<article>
<?php print render($page['help']); ?>
<?php print render($page['highlighted']); ?>
<?php print render($page['content']); ?>
</article>
<?php if ($page['sidebar_second']): ?>
<aside class="last">
<?php print render($page['sidebar_second']); ?>
</aside>
<?php endif; ?>
<?php if ($page['footer']): ?>
<footer>
<?php print render($page['footer']); ?>
</footer>
<?php endif; ?>
<?php print render($tabs); ?>
</div>

Har man behov for kun at ramme forsiden, kan det gøres ved følgende php if sætning

<?php if ($is_front): ?>
Et eller andet der KUN vises på forsiden
<?php endif; ?>

Eller det modsatte. Her rammes alle sider undtagen forsiden. (Sjovt så meget et ! kan ændre!)

<?php if (!$is_front): ?>
Et eller andet der IKKE vises på forsiden - men alle andre
<?php endif; ?>

Her tjekkes for 2 ting. 1) Om 'sidebar_first' findes og 2) At det ikke er forsiden.

<?php if ($page['sidebar_first'] && !$is_front): ?>
...
<?php endif; ?>

En anden og mere drastisk metode er at lave en page.tpl, der kun virker på forsiden. page--front.tpl.php

Url (path) til theme folder kan skrives på følgende måde:

<?php echo path_to_theme() ?>

Hvis region "xxx" ELLER region "yyy"

<?php if ($page['xxx'] || $page['yyy']): ?>
....
<?php endif; ?>

Hvis region "xxx" OG region "yyy"

<?php if ($page['xxx'] && $page['yyy']): ?>
....
<?php endif; ?>

Sidst opdateret: 25/8/2014

region.tpl.php

filnavn: region.tpl.php

<?php print $content ?>

search-block-form.tp.php

<?php print $search_form; ?>

search-result.tpl.php

Har fjernet INFO delen!

<li>
<?php print render($title_prefix); ?>
<h3><a href="<?php print $url; ?>"><?php print $title; ?></a></h3>
<?php print render($title_suffix); ?>
<?php if ($snippet): ?>
<p><?php print $snippet; ?></p>
<?php endif; ?>
</li>

search-results.tpl.php

<?php if ($search_results): ?>
<h3><?php print t('Search results');?></h3>
<ol class="search__results <?php print $module; ?>-results">
<?php print $search_results; ?>
</ol>
<?php print $pager; ?>
<?php else : ?>
<h4><?php print t('Your search yielded no results');?></h4>
<?php print search_help('search#noresults', drupal_help_arg()); ?>
<?php endif; ?>

theme-navn.info

Filnavn: "THEME-NAVN".info

name = THEME-NAVN
description = INDSÆT KORT BESKRIVELSE
package = Core
version = VERSION
core = 7.x
engine = phptemplate

features[] = logo
features[] = name
features[] = slogan
features[] = node_user_picture
features[] = comment_user_picture
features[] = comment_user_verification
features[] = favicon
features[] = main_menu

regions[header] = Header
regions[help] = Help
regions[highlighted] = Highlighted
regions[content] = Content
regions[sidebar_first] = First sidebar
regions[sidebar_second] = Last sidebar
regions[footer] = Footer

regions[page_top] = Page top
regions[page_bottom] = Page bottom

stylesheets[all][] = css/override/kill/ctools.css
stylesheets[all][] = css/override/kill/aggregator.css
stylesheets[all][] = css/override/kill/field.css
stylesheets[all][] = css/override/kill/node.css
stylesheets[all][] = css/override/kill/system.messages.css
stylesheets[all][] = css/override/kill/system.menus.css
stylesheets[all][] = css/override/kill/user.css
stylesheets[all][] = css/override/kill/views.css
stylesheets[all][] = css/override/kill/book.css
stylesheets[all][] = css/override/kill/comment.css

stylesheets[all][] = css/override/keep/system.base.css
stylesheets[all][] = css/override/keep/system.theme.css
stylesheets[all][] = css/override/keep/search.css
stylesheets[all][] = css/override/keep/codefilter.css
stylesheets[all][] = css/override/keep/filter.css

stylesheets[all][] = css/normalize.css
stylesheets[all][] = css/site.css


scripts[] = js/onload.js

CSS

Normalize.css - http://necolas.github.io/normalize.css/

block-views.tpl.php

<section id="block-<?php print $block->module .'-'. $block->delta; ?>" class="block block-<?php print $block->module ?>">
<?php if ($block->subject): ?>
<h3><?php print $block->subject ?></h3>
<?php endif;?>
<?php print $content ?>
</section>

views-view-list.tpl.php

filnavn: views-view-list.tpl.php

<?php if (!empty($title)) : ?><h3><?php print $title; ?></h3><?php endif; ?>
<?php print $list_type_prefix; ?><?php print PHP_EOL; ?>
<?php foreach ($rows as $id => $row): ?>
<?php if ($classes_array[$id]) { ?>
<li class="<?php print $classes_array[$id]; ?>"><?php print $row; ?></li><?php print PHP_EOL; ?>
<?php } ?>
<?php if (!$classes_array[$id]) { ?>
<li><?php print $row; ?></li><?php print PHP_EOL; ?>
<?php } ?>
<?php endforeach; ?>
<?php print $list_type_suffix; ?>
<?php print PHP_EOL; ?>

views-view-unformatted.tpl.php

filnavn: views-view-unformatted.tpl.php

<?php foreach ($rows as $id => $row): ?>
<?php print $row; ?><?php print PHP_EOL; ?>
<?php endforeach; ?>

views-view.tpl.php

filnavn: views-view.tpl.php
De eneste ændringer jeg har lavet på views-view.tpl.php er, at slette tomme linjer og mellemrum for at få en pænere HTML struktur.

<?php print render($title_prefix); ?>
<?php if ($title): ?>
<?php print $title; ?>
<?php endif; ?>
<?php print render($title_suffix); ?>
<?php if ($header): ?>
<div class="view-header">
<?php print $header; ?>
</div>
<?php endif; ?>
<?php if ($exposed): ?>
<div class="view-filters">
<?php print $exposed; ?>
</div>
<?php endif; ?>
<?php if ($attachment_before): ?>
<div class="attachment attachment-before">
<?php print $attachment_before; ?>
</div>
<?php endif; ?>
<?php if ($rows): ?>
<?php print $rows; ?>
<?php elseif ($empty): ?>
<div class="view-empty">
<?php print $empty; ?>
</div>
<?php endif; ?>
<?php if ($pager): ?>
<?php print $pager; ?>
<?php endif; ?>
<?php if ($attachment_after): ?>
<div class="attachment attachment-after">
<?php print $attachment_after; ?>
</div>
<?php endif; ?>
<?php if ($more): ?>
<?php print $more; ?>
<?php endif; ?>
<?php if ($footer): ?>
<div class="view-footer">
<?php print $footer; ?>
</div>
<?php endif; ?>
<?php if ($feed_icon): ?>
<div class="feed-icon">
<?php print $feed_icon; ?>
</div>
<?php endif; ?>

NB!
Ajax virker IKKE ved brug af denne fil. Har du brug for et view, der skal bruge Ajax, skal du indsætte de normale classes <div class="<?php print $classes; ?>"> ... </div> rundt om hele denne fil.