Easy tab highlighting with included PHP menu

I recently reworked a simple PHP site that uses standalone PHP files containing only HTML. We needed to redesign the navigation bar, which was simple a series of clickable images. These files were not generated by a Dreamweaver template or anything like that, meaning that we would have had to manually change each file every time there was a change to the menu. That seemed very annoying to me, so I created a file called navbar.php and included it into all the pages, using the standard PHP include;

<?php include(‘navbar.php’);?>

The tabs are highlighted for the current page, so if you are on “About Us”, the About Us tab should be highlighted. To accomplish this, I wrote a simple function;

<?php
function isactive($filename){
$urlfilename = basename($_SERVER['SCRIPT_FILENAME']);
if($filename == $urlfilename){
echo “-hover”;
}
}
?>

A sample navigation tab would then look like this;

<a href=”consulting.php”><img src=”images/navbar-consulting<?php isactive(‘consulting.php’);?>.gif” name=”consulting” width=”104″ height=”35″ border=”0″ id=”consulting” onmouseover=”MM_swapImage(‘consulting’,”,’images/navbar-consulting-hover.gif’,1)” onmouseout=”MM_swapImgRestore()” /></a>

That simply uses the function to tell it which file name to match to the current page’s file name:

isactive(‘consulting.php’);

The end result is that on consulting.php, the HTML output for that tab would look like this:

<a href=”consulting.php”><img src=”images/navbar-consulting-hover.gif” name=”consulting” width=”104″ height=”35″ border=”0″ id=”consulting” onmouseover=”MM_swapImage(‘consulting’,”,’images/navbar-consulting-hover.gif’,1)” onmouseout=”MM_swapImgRestore()” /></a>

.. and that is done automatically using a single included file.


Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
1 Comment

please vote for EXIHT in Afric…

please vote for EXIHT in Africa.. an anti human trafficking nonprofit. Your vote will help with their funding: http://bit.ly/d3p5Ip

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
No Comments

Email Links vs. web-based e-mail clients

Take a look at http://www.lunarpages.com/sales-questions/. Their “Send us your question” button is nice … but they really ought to list the email address on the page too. Clicking it will launch your default e-mail program, even if you don’t use one. For many people that means it will try to open Windows Mail, Outlook, or Thunderbird, even if they only use Gmail or Hotmail.

Not everyone uses Outlook, Thunderbird, etc (e-mail clients), and assuming that can cost you potential leads and business.

Someone who uses only web-based e-mail will want to be able to quickly copy and paste the e-mail address. Now, you can of course right-click and copy the link address, but then you still have to remove the “mailto:” part. Why put your visitors through so much unnecessary trouble if you really want them to contact you?

There are some valid concerns about attracting spam, but those can be mostly overcome using JavaScript cloaking. I think it would be preferable to receive some spam AND more e-mails from your site visitors, than it would be to receive less spam and fewer e-mails from your site visitors, but maybe it’s just me.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter

Tags: , , ,

No Comments

Using MySQL to insert missing text depending on field length

Suppose you have a MySQL database table containing US 5-digit zip codes, except some of them are just three or four digits long because they had leading zeros, and those sometimes get dropped. Here’s how to add them back in;

For 3-digit zip codes:

UPDATE zipcodes SET zip = CONCAT(’00′, zip) WHERE LENGTH(zip) = 3

This will turn ’123′ into ’00123′.

For 4-digit zip codes:

UPDATE zipcodes SET zip = CONCAT(’0′, zip) WHERE LENGTH(zip) = 4

This will turn ’1234′ into ’01234′.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
No Comments

Impressions of Joomla 1.6 Beta 3

Well, Joomla came out with another 1.6 beta, and it has certainly come a long way. I remember testing a 1.6 beta two years ago. Here are some highlights;

Access Level Control (ACL)

It now features a robust ACL system, though some of the inheritance rules will take some getting used to. This is often cited as a feature Drupal has and Joomla lacks, but soon enough that will be a moot point. From my understanding there will be just one more beta in about two weeks, and then it should be time for 1.6!

Nested categories

Joomla always suffered from a rigid approach to categorization, with Sections and Categories. A section could contain categories, but there could be no sub-categories. This long-running annoyance has finally been been vanquished with Joomla 1.6. It uses only categories (no more sections!), and they can be nested as deeply as you want. I’m sure at some point someone will nest a category 666 levels down, and run into a terrible bug there … but in theory it should be fine, because a category would simply be assigned to a parent category .. the number of sub-levels should have no bearing on it.

Drupal has of course supported nested categories for a long time, where they are called Taxonomy. I think Drupal’s Taxonomy is still more advanced than Joomla 1.6′s category system, but for many, perhaps most users, just having nested categories is en0ugh. Those who want to do more advance PHP magic will naturally be more inclined towards Drupal anyway, and to words like Taxonomy.

The elimination of Joomla’s sections does mean that template code that relies on section IDs will have to be changed to be 1.6-compatible. It will have to check for category IDs instead. It also opens up an interesting possibility of (for example) using a database query to select only those categories that are nested within the current category. That could come in handy in displaying category ‘blogs’ or headlines in a more automated fashion than creating menu links. And speaking of menu links;

Menu Management

Joomla’s menu management has gotten very slick;

  • Changing the menu type is now faster.
  • Much more control over the menu items: meta data, page titles, robot rules, page class styling,  menu link title & CSS attributes.
  • Module assignment from a menu item. You can still assign modules to menu items, but now you can also do this from the menu item itself, rather than having to edit the module separately.
  • Batch processing multiple menu items
  • Language filtering; show your menu item only for certain languages, or for all of them. Would be nice if you could select several languages and hide it on others, but that may be coming.
  • Set template style

Redirect manager

Joomla 1.6 has a new component for managing URL redirects. Presumably this writes to the .htaccess file and created a 301 redirect.

Banner Manager

This is not too different from the 1.5 version, but features “Tracks”, which tracks clicks and impressions in date-filterable and CSV-exportable fashion. Finally we will be able to do some more robust reporting.

I am however baffled that banner clients still have no way to log in and view their banner’s statistics. I think most clients would want that, and offering that ability will help site owners gain more advertisers.

I wrote a Joomla 1.5 hack that got around this by using the “alias” field of the banner client to hold a username. That allows us to associate a banner client with a username, and then we can use that to display banner statistics to a given Joomla user (and only that user). Looks like I will have to port that hack to 1.6. Sigh.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter

Tags: , , ,

2 Comments

loving @freshbooks for my invo…

loving @freshbooks for my invoicing. http://bit.ly/aGjNTp

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
1 Comment

Client login for Joomla 1.5 banner component

For the longest time I have been frustrated that the standard banner component doesn’t let banner clients login and view theirbanner statistics. I had been using OpenX but it is a resource hog and is really overkill when all I want is to be able to show a client how many clicks they’ve had so far. I don’t want them to just take my word for it.

Well, after trying out various solutions besides OpenX, I thought to myself 2 hours ago, “why can’t I just use Contact field in thebanner client area and enter a Joomla username, and then write a custom model for com_banners to display the statistics if the current Joomla user is the same as the one listed as the contact for a client?”

So that’s what I did. It is actually two queries. #1 checks the current username and selects all clients with that username (should be just one .. I limited it to one in the query), and selects the correct cid (client id). #2 selects all active banners for a given cid and spits them out, showing the banner, clicks, impressions, and CTR. I also added in some custom HTML to display a PayPal button … ideally this should be done in a View, not a Model, but the Banners component doesn’t seem to follow the MVC structure 100% so I didn’t either.

I did have to modify a few other files. Here are my modifications – this is on Joomla 1.5.18 but should work for any 1.5 release.

It’s as easy as 1-2-3;

1.

/components/com_banners/controller.php:

Add this after the end of function click():

function bannerstats(){

$model = &$this->getModel( ‘Bannerstats’ );

$model->bannerstats();

}

2.

/components/com_banners/bannerstats.php
This is a new file – containing this code:

<?php

// Create the controller

$controller = new BannersController( array(‘default_task’ => ‘bannerstats’) );

// Perform the Request task

$controller->execute(JRequest::getVar(‘task’, null, ‘bannerstats’, ‘cmd’));

// Redirect if set by the controller

$controller->redirect();

3.

/components/com_banners/models/bannerstats.php

This is a new file containing this code:

<?php

// Check to ensure this file is included in Joomla!

defined(‘_JEXEC’) or die( ‘Restricted access’ );

$document = &JFactory::getDocument();

jimport( ‘joomla.application.component.model’ );

jimport( ‘joomla.application.component.helper’ );

/**

* @package      Joomla

* @subpackage   Banners

*/

class BannersModelBannerstats extends JModel

{

function bannerstats(){

$banneruser = & JFactory::getUser();

$dbgetclient = &$this->getDBO();

echo “<h2>”.$banneruser->name.”‘s Ads</h2>”;

echo “<p>Already a customer? If your ad is about to reach the paid for number of clicks, you can make another payment using this button:</p>”;

echo ‘<form action=”https://www.paypal.com/cgi-bin/webscr” method=”post” target=”_blank”>

<input name=”cmd” value=”_xclick” type=”hidden”>

<input name=”lc” value=”US” type=”hidden”>

<input name=”business” value=”youremail@yourdomain.com” type=”hidden”>

<input name=”pal” value=”4UXZK24C297M6″>

<input name=”item_name” value=”The name for this transaction” type=”hidden”>

<input src=”/images/x-click-but01.gif” name=”submit” alt=”Make payments with PayPal – it\’s fast, free and secure!” border=”0″ type=”image” width=”62″ height=”31″>

<br>

‘;

$dbgetclient = &$this->getDBO();

echo “<h2>Active ads for: “.$banneruser->username.”: </h2>”;

$getclient = “SELECT cid FROM #__bannerclient WHERE contact=’”.$banneruser->username.”‘ LIMIT 1″;

$dbgetclient->setQuery( $getclient );

$getclientresult = $dbgetclient->loadObjectList();

for($i = 0; $i < count($getclientresult); $i++) {

$cid = $getclientresult[$i]->cid;

//echo “cid: “.$cid.”<br />”;

}


$dbgetbanner = &$this->getDBO();

$getbanner = “SELECT * FROM #__banner WHERE cid=”.$cid.”";

$dbgetbanner->setQuery( $getbanner );

$getbannerresult = $dbgetbanner->loadObjectList();

for($i = 0; $i < count($getbannerresult); $i++) {

echo “<img src=’”.JURI::root().”images/banners/”.$getbannerresult[$i]->imageurl.”‘ border=’0′><br />”;

echo ‘URL: ‘.$getbannerresult[$i]->clickurl.’<br />’;

echo ‘Clicks: ‘.$getbannerresult[$i]->clicks.’<br />’;

echo ‘Views: ‘.$getbannerresult[$i]->impmade.’<br />’;

echo ‘CTR (clickthrough rate): ‘.number_format((100*($getbannerresult[$i]->clicks)/($getbannerresult[$i]->impmade)),2).’ %<hr />’;

}

}

}

?>

You can then create a link in the User Menu pointing to index.php?option=com_banners&amp;task=bannerstats.

It will detect the current logged-in user’s username, check the “contact” field of the banner clients, and select the active banners for that client. Needless to say, the contact field should contain that person’s username and nothing else, or it will not work.

In the future maybe there can be a special field allowing us to choose a username or enter one, instead of using the Contact field which is not really meant for that. I had considered making this a separate component, but it is really something I would like to see become part of the regular com_banners component.

Feedback is welcome – as far as I can tell this is secure and works, but others may have a better idea about that.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
No Comments

Freshbooks and time management

FreshBooks is a great tool for managing and monitoring time spent on projects. That helps make you more efficient and profitable. We have been using it for nearly two months, and it has worked wonders for us in terms of time tracking and invoicing. We highly recommend it.

It’s a wonderful invoicing tool, offering smooth integration with Basecamp, online payment for your customers, and even snail mail for those times you need to mail an invoice the old-fashioned way. Using Authorize.net you can also set up recurring payments.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter

Tags: , , , , , ,

No Comments

Monitoring Joomla for file changes

It is often desirable to monitor a site for file changes, so that you can be alerted to unwanted file changes. Those could indicate hacker activity. There is server-side software that can do this for sites, but since our focus is Joomla, we wanted to take a moment to recommend the Eyesite component: http://extensions.lesarbresdesign.info/eyesite. To get the most out of this, you will need to set up a cron job so that it will email you whenever there are outstanding file changes.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
No Comments

Find Joomla section ID for article or category

Sometimes when coding a Joomla template it may be handy to know the section ID of the article or category the user is viewing.

Here is some PHP code you could insert in your template to achieve this (for Joomla 1.5);

$db =& JFactory::getDBO();
if(JRequest::getVar(‘view’)==’article’){
$query = “SELECT sectionid FROM #__content WHERE id=’”.JRequest::getVar(‘id’).”‘”;
$db->setQuery($query);
$sectionid = $db->loadResult();
}
if(JRequest::getVar(‘view’)==’category’){
$query = “SELECT sectionid FROM #__content WHERE catid=’”.JRequest::getVar(‘id’).”‘”;
$db->setQuery($query);
$sectionid = $db->loadResult();
}

Using this, you could for example control which graphics or CSS file are loaded depending on the section of the article/category.

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • LinkedIn
  • MySpace
  • RSS
  • Slashdot
  • StumbleUpon
  • Technorati
  • Yahoo! Bookmarks
  • Twitter
4 Comments