code
Inserting a span element into an anchor via Drupal’s $primary_links
Feb 22nd
I previously wrote about how to insert a span into a link, but after testing this method quickly failed when coupled with the Views module. When a Page view is created and assigned to a node url, everything is fine and dandy. The issues arise when you want a link to use an alias. Luckily, I’ve devised a really simple work around:
use the same code to generate your menu:
<?php if (!empty($primary_links)): ?>
<?php print theme('links', $primary_links, array('id' => 'nav')); ?>
<?php endif; ?>
this calls the links() function inside of includes/theme.inc, which triggers the l() function in the includes/common.inc to write the primary links menu. We can’t override the l() entirely because other code uses it, so we’ll copy the code from theme.inc and override the l() function with a site template specific one. Here’s my code:
theme.inc
function mytheme_links($links, $attributes = array('class' => 'links')) {
global $language;
$output = '';
$options = array(
'class' => '',
'html' => FALSE,
);
if (count($links) > 0) {
$output = '<ul' . drupal_attributes($attributes) .'>';
$num_links = count($links);
$i = 1;
foreach ($links as $key => $link) {
$class = $key;
$links['attributes']['title'] = $link['title'];
// Add first, last and active classes to the list of links to help out themers.
if ($i == 1) {
$class .= ' first';
}
if ($i == $num_links) {
$class .= ' signup last';
$links['attributes']['class'] .= $class;
}
if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
&& (empty($link['language']) || $link['language']->language == $language->language)) {
$class .= ' active';
}
$output .= '<li' . drupal_attributes(array('class' => $class)) .'>';
if (isset($link['href'])) {
// Pass in $link as $options, they share the same keys.
//here's my call to the overridden function
$output .= mytheme_l($link['title'], $link['href'], $links);
}
else if (!empty($link['title'])) {
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
$span_attributes = '';
if (isset($link['attributes'])) {
$span_attributes = drupal_attributes($link['attributes']);
}
$output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>';
}
$i++;
$output .= "</li>\n";
}
$output .= '</ul>';
}
return $output;
}
and now the l() function in common.inc gets changed to mytheme_l():
function mytheme_l($text, $path, $options = array()) {
global $language;
// Merge in defaults.
$options += array(
'attributes' => array(),
'html' => FALSE,
);
// Append active class.
if (($path == $_GET['q'] || ($path == '<front>' && drupal_is_front_page())) &&
(empty($options['language']) || $options['language']->language == $language->language)) {
if (isset($options['attributes']['class'])) {
$options['attributes']['class'] .= ' active';
}
else {
$options['attributes']['class'] = 'active';
}
}
// Remove all HTML and PHP tags from a tooltip. For best performance, we act only
// if a quick strpos() pre-check gave a suspicion (because strip_tags() is expensive).
if (isset($options['attributes']['title']) && strpos($options['attributes']['title'], '<') !== FALSE) {
$options['attributes']['title'] = strip_tags($options['attributes']['title']);
}
// Inject a span inside the anchor tag for the purposes of this theme - NOTE - May have to remove check_plain() around
// the $text variable
return '<a href="'. check_url(url($path, $options)) .'"'. drupal_attributes($options['attributes']) .'><span>'. ($options['html'] ? $text : check_plain($text)) .'</span></a>';
}
You can see that all I did was include the span element inside the anchor tag using simple php string concatenation. Until I can find a better solution, this does the trick. Don’t ask me about benchmarking, though…
Returning an Alias from primary_links’s links['href'] – or – How I became a Drupal Wizard
Feb 18th
I’m building a custom template in Drupal for the farm, and needed a way to spit out a custom implementation of primary_links navigation unordered list. I needed something like this:
<ul id="nav"> <li class="first"><a href="link-goes-here" title="wow, how descriptive"><span>link 1 copy</span></a></li> <li><a href="link-goes-here2" title="round 2, FIGHT!"><span>link 2 copy</span></a></li> </ul>
The spans inside the anchor tag are valid xhtml strict, and necessary for the nested/floating backgrounds. The l() function in drupal does a fine job of spitting out valid code, but I also haven’t found anything to delimit the angle brackets in the span element.
Here’s how I solved the problem.
First, I added a preprocess function in template.php and copied this chunk of code from root/includes/theme.inc:
function theme_links($links, $attributes = array('class' => 'links')) {
global $language;
$output = '';
if (count($links) > 0) {
$output = '<ul'. drupal_attributes($attributes) .'>';
$num_links = count($links);
$i = 1;
foreach ($links as $key => $link) {
$class = $key;
// Add first, last and active classes to the list of links to help out themers.
if ($i == 1) {
$class .= ' first';
}
if ($i == $num_links) {
$class .= ' last';
}
if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
&& (empty($link['language']) || $link['language']->language == $language->language)) {
$class .= ' active';
}
$output .= '<li'. drupal_attributes(array('class' => $class)) .'>';
if (isset($link['href'])) {
// Pass in $link as $options, they share the same keys.
$output .= l($link['title'], $link['href'], $link);
}
else if (!empty($link['title'])) {
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
$span_attributes = '';
if (isset($link['attributes'])) {
$span_attributes = drupal_attributes($link['attributes']);
}
$output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>';
}
$i++;
$output .= "</li>\n";
}
$output .= '</ul>';
}
return $output;
}
I then modified the code as follows:
function stoneyacresfarm_links($links, $attributes = array('class' => 'links')) {
global $language;
$output = '';
if (count($links) > 0) {
$output = '<ul'. drupal_attributes($attributes) .'>';
$num_links = count($links);
$i = 1;
foreach ($links as $key => $link) {
$class = $key;
// Add first, last and active classes to the list of links to help out themers.
if ($i == 1) {
$class .= ' first';
}
if ($i == $num_links) {
$class .= ' last';
}
if (isset($link['href']) && ($link['href'] == $_GET['q'] || ($link['href'] == '<front>' && drupal_is_front_page()))
&& (empty($link['language']) || $link['language']->language == $language->language)) {
$class .= ' active';
}
$output .= '<li'. drupal_attributes(array('class' => $class)) .'>';
if (isset($link['href'])) {
// Pass in $link as $options, they share the same keys.
// here are the modifications
$temphref = drupal_lookup_path('alias', $link['href'], '');
$output .= '<a href="' . $temphref . '" title="' . $link['title'] . '"> <span>' . $link['title'] . '</span></a>';
}
else if (!empty($link['title'])) {
// Some links are actually not links, but we wrap these in <span> for adding title and class attributes
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
$span_attributes = '';
if (isset($link['attributes'])) {
$span_attributes = drupal_attributes($link['attributes']);
}
$output .= '<span'. $span_attributes .'>'. $link['title'] .'</span>';
}
$i++;
$output .= "</li>\n";
}
$output .= '</ul>';
}
return $output;
}
Lines 29 & 30 are the brilliant bits. I scoured api.drupal.org till I found the drupal_lookup_path function. Follow the link for the arguments that can be passed in. I specified that I wanted an alias, gave it the path ( links['href'] ), and passed in a blank character for language.
This is all rendered out in my page-front.tpl.php and page.tpl.php files in the standard fashion:
<?php if (!empty($primary_links)): ?>
<?php print theme('links', $primary_links, array('id' => 'nav')); ?>
<?php endif; ?>
I hope this helps!
Fix IE 6 Floating Element Double Margin Bug
Feb 4th
If you read my last post, you know that I develop for IE6 and why. As is the case, IE6 throws annoying little gems at us, like its non-compliant box model, and the subject of today’s blog: the ever persistent double margin bug.
As the title alludes to, IE6 doubles the right and/or left margin on a floated element unless you declare:
display: inline;
Don’t worry about block-level items losing their width or height: they won’t. This isn’t a comprehensive explanation of the fix; it works for the conditions specified.
Links on How to Fill a Concave Polygon
Nov 18th
I’m working on a project in Max/Jitter and have run into a problem: dynamically filling a complex (concave, crossed, or holed) polygon. Here are some resources that explain the math behind find the area of and or filling such shapes:
- http://www.songho.ca/opengl/gl_tessellation.html
- http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
- http://www.freepatentsonline.com/EP0425189.html
- http://mathopenref.com/coordpolygonarea.html
- http://www.flipcode.com/archives/Polygon_Tessellation_In_OpenGL.shtml
- http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
- http://glprogramming.com%Proxy-Connection: keep-alive
Cache-Control: max-age=0red/chapter02.html
- http://glprogramming.com/red/chapter11.html
Drupal Fatal error: Allowed memory size of 33554432 bytes exhausted
Jan 17th
While installing the Calendar module for a Drupal site, I ran into the following error:
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 71 bytes) in /home/milwaul0/public_html/drupal/includes/theme.inc on line 729
Confounded, I searched the internet and found this:
http://drupal.org/node/283579
The first option (making a php.ini file in the root) appears to need a restart of the webserver, so I tried the second option, allocating more memory to php via drupal using:
ini_set(‘memory_limit’, ‘64M’); in the sites/default/settings.php file
But before that, I had to change the permissions of the file, which had been set to 555 (default, by the site admin I assume).
I initially set the memory to 64M to make sure it would work, since 33554432 bytes is 32MB. After it worked, I noticed that the permissions for the file had been reset to 555, so I changed that again and allocated 32MB for php. It worked. If ever any problems arise, I’ll know what to do.
What’s weird is that this error was triggered while allocating 71 bytes. I don’t know why there was even an issue… anyone?
Choosing Drupal
Dec 28th
While designing and developing websites, I’ve run into a lot of repetitive tasks. From client survey and project proposal, to information architecture issues, requisite files (jQuery, mootools, reset.css, etc.), standard grid templates in XHTML/CSS, to grid layers and naming conventions in Illustrator® documents, and client invoicing, there are a lot of processes that get repeated.