WordPress Thesis Theme Customization - Adding a Custom XHTML Sitemap

The Thesis Theme for WordPress - One Powerful WordPress Framework

Lately I've been learning all I can on leveraging the functionality of the Thesis theme for WordPress. When I first heard about the versatility and power of Thesis in a blog post by Rae Hoffman, I was immediately interested in what benefits I could offer my customers that opted to have me design and build them a custom WordPress site. Having customized and hacked several of Chris Pearson's WordPress themes in the past, I figured I should just go for it and purchase the Thesis developer theme - Chris' greatest accomplishment thus far.

Wow Thesis is Sophisticated - There's a Lot to Learn

I have to admit, when I first took a look into the core of the Thesis framework, I was a bit intimidated - Thesis was nothing like I expected under the hood. First off, Thesis comes with lots of customization options right out of the box ... [Take a look here] So, getting to know what was available from the core install was quite an undertaking in itself. The good news is, when you purchase Thesis, you not only get a lifetime subscription to the theme, you also get the exceptional tech support of the Thesis designer / developer community. The support community is always available to help you along the way as you learn how to negotiate the Thesis framework.

Some Folks Just Can't Leave Well Enough Alone

I'm definitely not the kind of guy that is happy with being 'okay'. If there's a way to make something better, stronger or faster - then that's what I'm gonna' try to do next. So, when I saw that there wasn't a simple way of making custom page templates in Thesis - I knew that I needed to set out to tackle that issue. One of the first things I wanted to do in my own Thesis themes, was to create and XHTML sitemap like some other WordPress themes had. In the past, I would simply create a custom page template for my sitemap page and then rip out and modify the code from a theme that I admired. Simple. However, in Thesis things aren't so easy. First of all, the Thesis was of customizing pages is to make all your custom changes to pages that won't be affected in future upgrades. Thesis does so by offering customization through manipulating two files; styles.css, custom_functions.php, both of which are available under the theme's custom folder. However, most of the customization are actually 'hooked' in to the framework by creating your own custom functions. The old way of simply creating a new template and then assigning it to a page or post won't work with Thesis.

On With The Show - Classes - Object Oriented Customizations

So basically I had to answer the question ...

How Can I Create Sophisticated Customizations and Minimalize Negative Effects?

After searching online, I finally found an answer to my problem. Creating Custom Classes. In Gary Jones' tutorial in creating an XHTML sitemap for Thesis, I recognized the ultimate solution to customizations in Thesis - leveraging the Object Oriented nature of the Thesis framework. Gary basically makes all customizations in a custom classes file as in this example for an XHTML sitemap. Following Gary's example, we create a file for our new class entitled GT_Sitemap.php, and place it in a directory named classes which is located in under our Thesis custom directory.

view plain print about
1<?php
2/**
3* Allows XHTML sitemap to be added
4*
5* @package GT_Sitemap
6* @author Gary Jones 
7* @version 2010-05-19
8* @since 2010-03-20
9*/

10
11class GT_Sitemap  {
12 /**
13  * @var string
14  */

15  protected $_pagesText;
16 /**
17  * @var string
18  */

19  protected $_postsText;
20 /**
21  * @var string
22  */

23  protected $_archivesText;
24 /**
25  * @var int
26  */

27  protected $_headingLevel;
28 /**
29  * @var array
30  */

31  protected $_order = array();
32 /**
33  * @var bool
34  */

35  protected $_showPageDate;
36 /**
37  * @var string
38  */

39  protected $_showPostDate;
40 /**
41  * @var bool
42  */

43  protected $_showPostCount;
44 /**
45  * @var string
46  */

47  protected $_archivesType;
48 /**
49  * @var string
50  */

51  protected $_pagesDateFormat;
52 /**
53  * @var string
54  */

55  protected $_postsDateFormat;
56 /**
57  * @var string
58  */

59  protected $_customPagesQuery = '';
60 /**
61  * PHP4 compatible constructor
62  */

63  public function GT_Sitemap() {
64  if(version_compare(PHP_VERSION,"5.0.0","__construct")) {
65  register_shutdown_function(array($this,"__destruct"));
66  }
67  }
68 /**
69  * PHP5 constructor, setting defaults
70  */

71  public function __construct() {
72 $this->
_pagesText = 'Pages';
73  $this->
_postsText = 'Posts';
74  $this->_archivesText = 'Monthly Archives';
75  $this->_headingLevel = 3;
76  $this->_order = array('pages', 'posts', 'archives');
77  $this->_showPageDate = true;
78  $this->_showPostDate = 'published';
79  $this->_showPostCount = true;
80  $this->_archivesType = 'monthly';
81  $this->_pagesDateFormat = get_option('date_format');
82  $this->_postsDateFormat = get_option('date_format');
83  $this->_customPagesQuery = '';
84  }
85 /**
86  * @param string $id
87  */

88  public function setPagesText($id) {
89  $this->_pagesText = $id;
90  return $this;
91  }
92 /**
93  * @param string $id
94  */

95  public function setPostsText($id) {
96  $this->_postsText = $id;
97  return $this;
98  }
99 /**
100  * @param string $id
101  */

102  public function setArchivesText($id) {
103  $this->_archivesText = $id;
104  return $this;
105  }
106 /**
107  * @param array $id
108  */

109  public function setOrder($arg1, $arg2 = null, $arg3 = null) {
110  $this->_order = func_get_args();
111  return $this;
112  }
113 /**
114  * @param int $id
115  */

116  public function setHeadingLevel($id) {
117  $this->_headingLevel = $id;
118  return $this;
119  }
120 /**
121  * @param string $id
122  */

123  public function setPageDateFormat($id) {
124  if ( 0 === func_num_args() ) {
125  $this->_showPageDate = '';
126  } else {
127  $this->_pagesDateFormat = $id;
128  }
129  return $this;
130  }
131 /**
132  * @param string $id
133  */

134  public function setPostDateFormat($id) {
135  if ( 0 === func_num_args() ) {
136  $this->_showPostDate = '';
137  } else {
138  $this->_postsDateFormat = $id;
139  }
140  return $this;
141  }
142 /**
143  * @param string $id
144  */

145  public function setDateFormat($id) {
146  $this->setPageDateFormat($id);
147  $this->setPostDateFormat($id);
148  return $this;
149  }
150 /**
151  *
152  */

153  public function hidePostCount() {
154  $this->_showPostCount = false;
155  return $this;
156  }
157 /**
158  * @param string $id
159  */

160  public function setArchivesType($id) {
161  $archiveTypes = array('yearly', 'monthly', 'daily', 'weekly', 'postbypost', 'alpha');
162  if ( in_array($id, $archiveTypes) ) {
163  $this->_archivesType = $id;
164  $this->setArchivesText(substr_replace($id, strtoupper(substr($id, 0, 1)), 0, 1) . ' Archives');
165  }
166  return $this;
167  }
168 /**
169  * @param string $id
170  */

171  function setCustomPagesQuery($id) {
172  $this->_customPagesQuery = $id;
173  return $this;
174  }
175 /**
176  * @param string $shortcode The shortcode keyword that will be used to output the sitemap
177  */

178  public function shortcode($shortcode) {
179  add_shortcode( $shortcode, array(&$this, 'build') );
180  }
181 /**
182  * Does the main work of creating the output
183  */

184  public function build() {
185  foreach ($this->_order as $section) {
186 if ( 'pages' === $section ) {
187  $output .= '<h' . $this->_headingLevel . '>' . $this->_pagesText . '</h' . $this->_headingLevel . '>' . "\n"
188  . '<ul>' . "\n" . wp_list_pages('echo=0&show_date=' . $this->_showPageDate . '&date_format=' . $this->_pagesDateFormat . '&title_li=&' . $this->_customPagesQuery) . '</ul>' . "\n";
189  }
190 if ( 'posts' === $section ) {
191  $output .= '<h' . $this->_headingLevel . '>' . $this->_postsText . '</h'. $this->_headingLevel . '>'."\n"
192  . '<ul>' . "\n" . $this->_posts_by_category() . '</ul>' . "\n";
193  }
194 if ( 'archives' === $section ) {
195  $output .= '<h' . $this->_headingLevel . '>' . $this->_archivesText . '</h'. $this->_headingLevel . '>' . "\n"
196  . '<ul>' . "\n" . wp_get_archives('type=' . $this->_archivesType . '&echo=0&show_post_count=' . $this->_showPostCount). '</ul>' . "\n";
197  }
198  }
199  return $output;
200 }
201 protected function _posts_by_category() {
202  global $wpdb, $post;
203  $tp = $wpdb->prefix;
204  $sort_code = 'ORDER BY name ASC, post_date DESC';
205  $the_output = NULL;
206  $last_posts = (array)$wpdb->get_results("SELECT {$tp}terms.name, {$tp}terms.term_id, {$tp}term_taxonomy.term_taxonomy_id    FROM {$tp}terms, {$tp}term_taxonomy    WHERE {$tp}terms.term_id = {$tp}term_taxonomy.term_id AND {$tp}term_taxonomy.taxonomy = 'category'");
207  if (empty($last_posts)) {
208  return NULL;
209  }
210  $the_output .= '';
211  $used_cats = array();
212  $i = 0;
213 foreach ($last_posts as $posts) {
214  if (in_array($posts->name, $used_cats)) {
215  unset($last_posts[$i]);
216  } else {
217  $used_cats[] = $posts->name;
218  }
219  $i++;
220  }
221  $last_posts = array_values($last_posts);
222 foreach ($last_posts as $posts) {
223  $the_output .= '&lt;li&gt;&lt;a href="' . get_category_link($posts->term_id) .' "&lt;strong&gt;' . apply_filters('list_cats', $posts->name, $posts) . '&lt;/strong&gt;&lt;/a&gt;&lt;ul&gt;';
224  
225  $arcresults = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' AND ID IN (SELECT object_id FROM {$tp}term_relationships, {$tp}terms WHERE {$tp}term_relationships.term_taxonomy_id =" . $posts->term_taxonomy_id . ") ORDER BY post_date DESC");
226  
227  foreach ( $arcresults as $arcresult ) {
228  $the_output .= '&lt;li&gt;&lt;a href="' . get_permalink($arcresult->ID) . '"&gt;' . apply_filters('the_title', $arcresult->post_title) . '&lt;/a&gt; ';
229  if ($this->_showPostDate) {
230  $the_output .= date($this->_postsDateFormat,strtotime($arcresult->post_date));
231  }
232  $the_output .= '&lt;/li&gt;';
233  }
234  $the_output .= '&lt;/ul&gt;&lt;/li&gt;';
235  }
236  return $the_output;
237  }
238  }
239  ?>

Then, we simply add the next three lines of code in our custom_functions.php file:

view plain print about
1require_once 'classes/GT_Sitemap.php'; 
2  $sitemap = new GT_Sitemap;
3  
4  $sitemap->
shortcode('sitemap');

The first line simply includes our custom class file. The second line then instantiates a new sitemap object and third, we assign the variable $sitemap to the shortcode 'sitemap' so that all we need to do is to add the shortcode in the body of a new page or post and voila' - we have a new sitemap.

Note: If you wish to implement this code, I had to modify several lines from the code I found on Gary's site - In a comparison with Gary's code, you'll see there are several differences. Apparently Gary made some changes to the current code which were not updated. I modified the current code on his site with some of the older code I found here. In short, I had to debug several lines to come up with the code above. If it works for you great. If not - Hey, I got it to work but I can't guarantee it for you ...

That's it.

Flash Security Vulnerability? Not with Firefox & NoScript

Apparently there is a Flash Security Vulnerability deriving from the 'authplay.dll' in Adobe's Flash Player on Windows, Mac and Linux for both Adobe Reader and Acrobat v9.x. Basically, an unsuspecting victim may be lured to a site that contains malicious Flash code to either crash or compromise the integrity of the victims computer ... Hmmm.

A CERT spokesperson stated ...

The Adobe Flash browser plug-in is available for multiple Web browsers and operating systems, any of which could be affected ... An attacker could also create a PDF document that has an embedded SWF file to exploit the vulnerability. This vulnerability is being actively exploited.

According to Trusteer, Two weeks after the press release, approximately 80 percent of Trusteer's installed base of 2.5 million online banking users still haven't received the Flash update.

What To Do? Use Firefox with NoScript.

Here's just one more notch in the belt for Firefox, and a prime example of why using Giorgio Maone's NoScript plug-in for Firefox is a must have.

For more info on NoScript ... check out Maone's Rockin' Site, NoScript.net ...

If your still using I.E., That's a shame ...

That's it.

Managing ColdFusion and Database Services Through Batch Scripting

Managing ColdFusion Application Services » Does StartUp Need So Many Steps? No.

Some time last year I realized the need to manage the application development services running simultaneously on my dev box. On my main box I'm running ColdFusion 8 on IIS 7, MySQL, MSSQL, and a WAMP setup as well. So when the need arose to manage which services were running, I would previously had called up an MMC snap-in and manually cranked up the required ColdFusion services; the MySQL or MSSQL database services and finally the sites I needed running on IIS - ad hoc. A good portion of my daily work schedule was getting consumed going back and forth to my MMC console.

Managing StartUp Services with Batch Scripting

I created a simple batch script to either crank up or shut down ColdFusion as needed and then I put a shortcut in a directory under c:\ where the shortcut would be accessible to my computer's PATH variables. This way I can get even lazier by just running my batch script by typing Win Key + R - enter my batch script shortcut name which is uniquely named "CF" and hitting enter ... Having the shortcut has been really convenient. However, there were some issues with my batch script. Namely, if ColdFusion or a database service were already running and I tried to start them ... Windows would throw help message 1282 - The requested service has already been started. So, I needed to clean up my batch script by testing for the running services first. I also added a call to open a separate cmd window with the status the development services in question. Below is my new and improved batch script - Again, uniquely titled - Dev Cranker. Very Unique - Almost brandable.

TITLE --- Dev Cranker ---

@ECHO OFF

REM - THIS IS A FILE TO MANAGE DEVLOPMENT ... HI

SETLOCAL ENABLEDELAYEDEXPANSION

:BEGIN

IF EXIST CODE.TXT DEL CODE.TXT

SET MySQL=MySQL

SET CF1= "ColdFusion 8 .NET Service"

SET CF2= "ColdFusion 8 ODBC Agent"

SET CF3= "ColdFusion 8 ODBC Server"

SET CF4= "ColdFusion 8 Application Server"

SET SBR= "SQL Browser"

SET MSSQL= "MSSQL$SQLEXPRESS"

ECHO.

SC QUERY %CF1% |FINDSTR "SERVICE_NAME"> CODE.TXT

ECHO.

SC QUERY %CF1% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

SC QUERY %CF2% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %CF2% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

SC QUERY %CF3% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %CF3% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

SC QUERY %CF4% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %CF4% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT



SC QUERY %MySQL% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %MySQL% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

SC QUERY %SBR% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %SBR% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

SC QUERY %MSSQL% |FINDSTR "SERVICE_NAME" >> CODE.TXT

ECHO.

SC QUERY %MSSQL% |FINDSTR "DISPLAY_NAME STATE" >> CODE.TXT

ECHO.

START "DEV CRANKER II --- SERVICE STATE " TYPE CODE.TXT

:ZERO

CLS

ECHO.

ECHO ====================================================================================================

ECHO.

ECHO Dev Cranker ...

ECHO

ECHO ====================================================================================================

ECHO.

ECHO 1. Start ColdFusion

ECHO 2. Stop ColdFusion

ECHO 3. Start a Database

ECHO 4. Stop a Database

ECHO 5. Quit and Exit

ECHO.

ECHO What Do You Want To Do?

ECHO ====================================================================================================

CHOICE "/C:12345"

ECHO ====================================================================================================

IF ERRORLEVEL ==5 GOTO NINE

IF ERRORLEVEL ==4 GOTO SIX

IF ERRORLEVEL ==3 GOTO TWO

IF ERRORLEVEL ==2 GOTO FIVE

IF ERRORLEVEL ==1 GOTO ONE

:TEN

ECHO ====================================================================================================

ECHO Good Bye! ...

ECHO Dev Cranker ...

SLEEP 3

GOTO END

:NINE


ECHO ====================================================================================================

ECHO.

ECHO Finished?

ECHO.

ECHO ====================================================================================================

CHOICE "/C:YN"

ECHO ====================================================================================================

IF ERRORLEVEL ==2 GOTO ZERO

IF ERRORLEVEL ==1 GOTO TEN

:EIGHT

SC QUERY %Mysql% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %Mysql% >> code.txt

ECHO %Mysql% Is Winding Down ...

) ELSE (

ECHO %Mysql% Isn't Running ...

)GOTO NINE

:SEVEN

SC QUERY %SBR% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %SBR% >> code.txt

ECHO %SBR% Is Winding Down ...

) ELSE (

ECHO %SBR% Isn't Running ...

)SC QUERY %MSSQL% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %MSSQL% >> code.txt

ECHO %MSSQL% Is Winding Down ...

) ELSE (

ECHO %MSSQL% Isn't Running ...

)

GOTO NINE

:SIX

ECHO ====================================================================================================

ECHO.

ECHO 1. MSSQL (Exp)

ECHO 2. MySql

ECHO 3. Just Exit (N/A)

ECHO ====================================================================================================

ECHO Which Database Are You Stopping?


ECHO ====================================================================================================

CHOICE "/C:123"

IF ERRORLEVEL ==3 GOTO NINE

IF ERRORLEVEL ==2 GOTO EIGHT

IF ERRORLEVEL ==1 GOTO SEVEN

EXIT

:FIVE

SC QUERY %CF1% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %CF1% >> code.txt

ECHO %CF1% Is Winding Down ...

) ELSE (

ECHO %CF1% Isn't Running ...

)

SC QUERY %CF2% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %CF2% >> code.txt

ECHO %CF2% Is Winding Down ...

) ELSE (

ECHO %CF2% Isn't Running ...

)

SC QUERY %CF3% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %CF3% >> code.txt

ECHO %CF3% Is Winding Down ...

) ELSE (

ECHO %CF3% Isn't Running ...

)

SC QUERY %CF4% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 1 (

SC STOP %CF4% >> code.txt

ECHO %CF4% Is Winding Down ...

) ELSE (

ECHO %CF4% Isn't Running ...

)

GOTO NINE

ECHO ====================================================================================================

ECHO.

ECHO Need To Stop a DataBase?

ECHO.

ECHO ====================================================================================================

CHOICE "/C:YN"

IF ERRORLEVEL ==2 GOTO NINE

IF ERRORLEVEL ==1 GOTO SIX

:FOUR

SC QUERY %Mysql% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %Mysql% >> code.txt

ECHO %Mysql% Is Cranking Up ...

) ELSE (

ECHO %Mysql% Is Already Cranked Up ...

)

GOTO NINE

:THREE

SC QUERY %SBR% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %SBR% >> code.txt

ECHO %SBR% Is Cranking Up ...

) ELSE (

ECHO %SBR% Is Already Cranked Up ...

)

SC QUERY %MSSQL% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %MSSQL% >> code.txt

ECHO %MSSQL% Is Cranking Up ...

) ELSE (

ECHO %MSSQL% Is Already Cranked Up ...

)

GOTO NINE

:TWO


CHO ====================================================================================================

ECHO.

ECHO 1. MSSQL (Exp)

ECHO 2. MySql

ECHO 3. Just Exit (N/A)

ECHO.

ECHO Which Database Are You Cranking Up?

ECHO ====================================================================================================

CHOICE "/C:123"

IF ERRORLEVEL ==3 GOTO NINE

IF ERRORLEVEL ==2 GOTO FOUR

IF ERRORLEVEL ==1 GOTO THREE

:ONE

SC QUERY %CF1% |FIND /i "RUNNING" > code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %CF1% >> code.txt

ECHO %CF1% Is Firing Up ...

) ELSE (

ECHO %CF1% Is Already Cranked Up ...

)SC QUERY %CF2% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %CF2% >> code.txt

ECHO %CF2% Is Firing Up ...

) ELSE (

ECHO %CF2% Is Already Cranked Up ...

)

SC QUERY %CF3% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %CF3% >> code.txt

ECHO %CF3% Is Firing Up ...

) ELSE (

ECHO %CF3% Is Already Cranked Up ...

)

SC QUERY %CF4% |FIND /i "RUNNING" >> code.txt

IF !ERRORLEVEL! NEQ 0 (

SC START %CF4% >> code.txt

ECHO %CF4% Is Firing Up ...

) ELSE (

ECHO %CF4% Is Already Cranked Up ...

ECHO.

)

ECHO ====================================================================================================

ECHO.

ECHO Need Data?

ECHO.

ECHO ====================================================================================================

CHOICE "/C:YN"

IF ERRORLEVEL ==2 GOTO NINE

IF ERRORLEVEL ==1 GOTO TWO

:END

If any one has some suggestions here - Feel free to share your opinion - This is one of the first batch scripts I've created so I'm sure there could improvements ... That's it.

5 Great Examples of SEO Friendly JavaScript & CSS Menus

Florida SEO Says, "Dear JavaScript ... Will You Ever Forgive Me? "

In my last post ... I attempted to explain how pure JavaScript menus were not good for SEO. However, after reading how the message came across to some of my readers, I feel it's probably best if I add some clarification. Thanks to Dan Switzer at PengoWorks for pointing out that my post needed some explanation. What I mentioned regarded the usage of pure JavaScript menus -Not All- JavaScript menus. If my post confused anyone, I apologize. There are lot's of SEO friendly menus that incorporate both JavaScript and yet maintain good web design practices ... So, now let's take a look at a few that stuck out with me.

In my humble opinion, menus that use JavaScript to manipulate the DOM (Document Object Model) and CSS (Cascading Style Sheets) to handle styling, maintain a good balance between usability and provide a dynamically appealing experience.

Okay ... So Show Me Some Cool Stuff Now

Before I show the following examples I want to point out the main factor that make these menus search engine friendly is the accessibility of the links to the robots. These menus do not rely on JavaScript to display the content either.

The first example here is from one of the most respected names in design ... A List Apart. Here Dave Shea provides an excellent detail on creating a menu implementing CSS Sprites with JQuery.

1. CSS Sprites2 - It's JavaScript Time

A List Apart
by: Dave Shea

CSS Sprites - A List Apart

Next, one of my favorite designers, Collis Ta'eed provides in exhaustive detail, everything required to create a very attractive and effective tabbed content area using CSS & JQuery ...

2. Slick Tabbed Content Area using CSS & JQuery

NetTuts
by: Collis Ta'eed

Slick Tabbed Content Area using CSS & JQuery

Soh Tanaka offers a very clean and attractive JQuery & CSS menu. Aside from issues with IE6's non-support of the :hover psuedo-class for elements other than anchor tags, this is a very good menu and degrades gracefully with JavaScript disabled.

3. Sexy Drop Down Menu w JQuery & CSS

Noupe
by: Soh Tanaka

Sexy Drop Down Menu w JQuery & CSS

Clark gives a solid example of how to create an animated drop down menu that also degrades well with JavaScript disabled - The key here is that the animation on the list elements is acceptable regardless of whether the visitor has JavaScript enabled.

4. Animated Drop Down Menu with jQuery

ClarkLab

Animated Drop Down Menu with jQuery

Okay ... I'm not a great designer by any sense. But, when I created this site I decided I wanted a little DHTML action and of course promote good SEO techniques at the same time ... So, I used Adobe's Spry  Accordion Widget to build my right navigation ... It too degrades gracefully with JavaScript disabled - The menus tabs will simply open up if JavaScript is not activated.

5. SEO Compliant Spry Accordion Menu

SEO Compliant Spry Accordion Menu

by: Adobe Lab

There are many excellent examples out there ... I really just wanted to take a few minutes to clarify the difference between a pure JavaScript menu and a menu that uses JavaScript and CSS.

That's it.

Florida Search Engine Optimization » Apache MultiViews » Mod_Rewrite

Apache apparently has a server module call mod_negotiation which contains an option called MultiViews. MultiViews is a setting that gives the server the ability to decide the best representation for a requested file that doesn't exist. Furthermore, If MultiViews is enabled on the server, it will take operational precedence before any mod_rewrite directives that you provide in your .htaccess files. Had I been aware of this setting being turned on by default with my host, I would have requested for them to turn if off. However, I was completely oblivious that the setting even existed. The Apache documentation states ...

MultiViews » I should have known

My issue with MultiViews was discovered after a WordPress installation went south. I had installed WP 2.7 with a theme that I created and a group of plug-ins which I typically use. After creating a page for the HTML sitemap, I browsed the URL to make sure everything was working correctly. The destination URL was www.website.com/sitemap/, yet when I browsed to the page, the server was re-writing the URL as www.website.com/sitemap.xml/ which incidentally did not exist. Now, I also had Arne Brachold's Google Sitemap Generator for WordPress installed and I figured that there must be something wrong with either my .htaccess files or his sitemap plug-in on WP 2.7. After uninstalling his plug-in and several others in an attempt to solve the mysterious problem, checking and re-checking my .htaccess files, re-installing WordPress several times and arguing with my host that I have exhausted practically all efforts ... I became quite irritated. It was only when one of the tech support guys that had some experience with Apache realized the issue and sent me an e-mail informing me that the issue was due to MultiViews being enabled on the server. He suggested that I should have had requested to have it turned off ... I should have known.

Woe to you ... on shared hosting

If you are on shared hosting, you may not even know that some shared hosting accounts come equipped with the mod_negotiation module activated by default. If you are using the Apache2handler and want to find out yourself, just create a .php file with phpinfo(); in it and run that ... you should be able see if the mod_negotiation module is loaded ... If you are using the CGI/FastCGI such as I am, I don't know how you can tell ... phpinfo(); doesn't reveal those settings ... for the record contact your host.

SEO Side Effects » Duplicate Content with MutiViews

After doing some research and about MutiViews, I found a thread on WebMasterWorld stating that there may be duplicate content issues from using the MultiViews as well. Apparently MutiViews will allow for multiple URL's to point to the same content ... If you are having issues with duplicate content ... or if you can't seem to get your mod_rewrite directives to work as expected, you may want to take a look at the fantastic article in WebMasterWorld by: JDMorgan "A guide to fixing duplicate content & URL issues on Apache" ...

That's it.

Florida SEO » The ColdFusion Maniac Returns

So I recently installed Adobe CS4 Master Collection on my laptop ... I want to test it on there before I convert from CS3 on my main development box. So far it's pretty cool. However, it's going to take me a bit to get used to the new interface ... all of the apps seem a bit too "low profile" ... kind of two dimensional. I guess I'll get used to it.

Looking back on 08' I realize the one thing I would like to do most is improve my quality of life. That entails taking on several personal commitments and one of those commitments is to programming. I think I am going to dedicate part of my time this year to getting my CF certification ... yeah I know most of the uber coders out there are going to say it's not "really" necessary, but I have a strong belief in setting goals. So, this is one goal I think I'm going to take a concerted effort at. If anyone's got some advice about cert training, I'd really appreciate it.

A friend of mine and manager of the South Florida CFUG, was nice enough to honor me to the board of directors for the group ... I guess it's time to start getting serious about my love affair with CF and show my worth. CF cert training ... here I come ...

That's it.

Florida SEO » CFEclipse » Aptana Migration

I learned ColdFusion in DreamWeaver. For that matter, I've learned HTML, CSS, JavaScript and PHP in DreamWeaver too, so it's been fairly difficult for me to completely switch over to Eclipse even though I actually prefer working in Eclipse more than I do DreamWeaver. For some reason I just feel like I'm 'really' coding when I'm working in Eclipse. I don't feel like a 'serious' programmer when I'm working in DreamWeaver. So, I've decided to share some of the things I've done to make the migration a bit more tolerable.

First off I have Eclipse 3.3.1.1 Europa J2EE. I'm sticking with that platform for now because the latest Eclipse release, Ganymede, doesn't play to well with CFEclipse.

Then I installed CFEclipse, and added the ColdFusion extensions for Eclipse, the ColdFusion 8 help files for Eclipse, the ColdFusion 8 Syntax dictionaries, and finally plugged CFEclipse in to the CFLib and CFSnippets snippex servers.

After that, I installed Aptana. Except for the annoying 'upgrade to pro' messages they send, Aptana's really nice. What I really like about Aptana, is it's great HTML, CSS and JavaScript functionality. Coding web pages in Aptana is a snap, and since I'm a snippets freak, Aptana's snippets view helps me make the transition to Eclipse that much easier. The most important thing I needed from Aptana though, was remote FTP view. Being able to FTP from within the IDE was definitely keeping me tied to DreamWeaver, and by removing the key bindings in Eclipse for CTRL+Shift+U, and CTRL+Shift+D, I was then able to take advantage of the default GET and PUT FTP shortcuts that were so familiar to me from working in DreamWeaver. CTRL+Shift+U (PUT File via FTP ), CTRL+Shift+D (GET File via FTP). I live by these shortcuts.

Snippets are a way of life for me in DreamWeaver. Once I create something reusable, it goes in to a snippet folder, and I assign a keyboard shortcut to it. One thing that really sold me on CFEclipse, was the awesome job Mark Drew did on making snippet variable regions. That's too damned cool. For working with HTML, CSS and JavaScript snippets, I've just added the snippets view from Aptana to my CFEclipse perspective and the same with my Aptana view, I added the sniptree view to my Aptana perspective. That way, I can get the best of both worlds. For more customizations, I decided to install JSEclipse for my JavaScript work. JSEclipse is also really nice.

So, it may still take me a bit to get used to Eclipse, but I'm going to do my damndest to make it my primary IDE.

Google Chrome » Rocks

So my first impression about Google's new Chrome browser, is that it Rocks. It's quite apparent that the engineers at Google know exactly what the development community is looking for and they make no small feat in creating a web browser that is able to completely annihilate the competition. Moreover, I really like some of the features that are included by default like the Firebug style DOM inspector that you can invoke by a right click context menu (Nice).

Chrome Rocks

In my first shot at testing out the new browser's speed, I attempted to pull up a Google Map that I have on my site which makes a remote call to Google's GeoCoder object to retrieve coordinates for a city to update the map locations based on those coordinates. Though I should actually have the coordinates in a Google GeoCoder Cache to speed up the process, I don't » yet.

The results were amazing. while it took Firefox 2 approximately 4 seconds to fully display the map image, it took all of 500 milliseconds for Chrome to display. My results are just from personal experience though. Google claims that Chrome's new JavaScript engine, V8, shows remarkable performance levels and they provide a collection of benchmark test results to boast. [Chrome Test Results.]

According to the developers over Mozilla, the new browser is not as impressive as Google may claim and they also ran some tests on Chrome with a JavaScript testing engine named SunSpider. Mozilla claims that the new TraceMonkey JavaScript engine slated to be included in a future edition of Firefox, will perform even faster than V8. Things really start to get interesting though when JQuery's inventor, John Resig, decided to run some of his own performance tests on Chrome. In short » John agrees that Chrome's JavaScript engine is really fast.

Hey » I Want Your Regular Expressions » Now

I really like regular expressions (RegEx's) and I have this crazy fascination with learning and using them whenever and wherever I get a chance. If you don't know what a regular expressions is, the Sun Developer's Network's states:

"A regular expression is a pattern of characters that describes a set of strings." » Simple enough.

I picked up the bug for RegEx's after trying to "think my way through" a JavaScript form validation function without any experience in regular expressions or JavaScript for that matter.

That event led me to pick up Mastering Regular Expressions, III ed. By Jeffrey Friedl; OReilly's JavaScript, The Definitive Guide, By David Flanagan, and a fierce desire to learn more about the almost alien-looking esoteric characters that were here to take over my programming world.

The good news I found out later was not only that I am not the only RegEx fan that has been drawn in by their mysterious attraction. Many of the coders and developers that I've found to respect, have this crazy bug too.

So, what I want to do now, is put together a RegEx Library right here on this post for all of the coolest regular expressions you know. So, post me your regular expression(s), with a brief description.

CF 8 Image CAPTCHA » toScript JS Validation

I finally got to the point where I had seen just about as much spam that I could handle and being somewhat of a ColdFusion developer, I decided to take some action ...

My first shot at stopping the pesky spammers was by implementing a Lyla CAPTCHA. However, I had some problems getting the CFC working correctly, and after several failed attempts, I tried to use Rob Gonda's AjaxCFC with Lyla too ... Yet, I still wasn't able to get the CAPTCHA working ...

So, after talking with a friend, that is quite familiar with ColdFusion ... he asked me why I didn't just use CF8's native support for CAPTCHA's with the CF Image tag ...

I really hadn't even thought of it ... I found the answer ...

I learned quite a bit more CF code in order to get the image going along with some JS validation ... For starters, I got the base idea from Camden's example of using CF CAPTCHA ... but I didn't want to break the layout of my form page by expanding the form during validation error messages ... I had to find a way to convert Ray's form validation in to JavaScript validation ...

Well, I searched through hundreds of pages in order to find a solution to my problem ... How to turn ColdFusion variables ... in to JavaScript variables ... I didn't have a clue ... until I found another non-related tutorial example by ... (guess who ...) yep, it's Ray again ... that alluded to the toScript method ... almost everywhere else I had searched, returned answers which expresses that there was no way in converting a ColdFusion object in to a JavaScript object ...

So, I was one step closer to my goal ... then, I hit another obstacle ... the error strings all ended with a "<br />" in order to separate the error strings when returned to the page ... that would not convert in to a JavaScript variable ... New Problem ... how could I insert a line break » Carriage Return in to a ColdFusion variable ... and return it in JavaScript without throwing errors?

Thanks to the friendly Ben Nadel ... for his contributions to the CF community again ... where I found a post of his on converting CF characters to JS ...

So, with a bit of my own efforts some where in there ... I finally have a CF CAPTCHA on my site ... and can say good bye to the spammers ... bye spammers ... 

SEO Fort Lauderdale » Neo Hacked WP Theme

Okay, I recently got a little creative and decided to build a WordPress theme for my fledgling Florida Search Engine Optimization Dot Org ... I'm calling it Neo Hacked.

I got the initial idea to take a shot a customizing my own theme after I was researching an SEO article on the Google PageRank Algorithm by Ian Rogers.

Besides having a brain that will probably all the rage for the medial community once he dies ... Ian has a pretty good taste in design too ... I however, do not have the greatest taste in design ... and I'd be lucky to pass on the four and a half bucks worth of my dead minerals to the benefit of my family.

So, I attempted to develop a Hack out of the original theme that Ian used ... connections 1.0 ...  However, all I managed to do is log about 30 hours of coding practice only to realize that the theme was way too outdated to use as a base for the WordPress platform has sophisticated quite a bit since the initial release of the connections theme ... Take One = Scraped.

Except for the green, I really liked the look and feel of connections, but I needed a more powerful template to work with ... so, I tried to use a couple of Pearson's chops ... The second shot went up with the Cutline theme ... but that didn't work out too well either ... Then I tried to build out the theme with the SandBox ... But, that didn't work out either ... It could have but I honestly didn't want to invest the time that it would take to build an entirely original theme ... I'm a lazy programmer.

End Result? I used the Neo Classical theme as the base template ... and ripped out the CSS and layout styles that were native to connections ... The whole process took me about a week to get right ... but I am happy with it.

Florida SEO - CakePHP - Ruby on Rails - BarCamp Miami

I went down to Miami with my good friend Mark from A List SEO to BarCamp Miami ... I didn't have tickets to the show I really wanted to be at, the Future of Web Apps, So I figured that at least I could hang out and get to meet some people at BarCamp.

Well, meet people I did ... and a lot of them. I was lucky enough to hang out and eat dinner with Larry Masters, the master mind behind the CakePHP framework. From our talks, I am definitely going to be checking out how I can start reaping the rewards of CakePHP as a rapid application development Framework.

Some of the other great guys that I spoke with were Kevin Marks, a developer advocate from Google ... Edgar Caballero, the senior technology consultant from Altra-App ... Jason Baptiste, CEO of Publictivity ... David Di Cillo, web and print designer with ThirtyNine ... Gary Schulthesis, & Craig Agranoff from Vois ... Sunir Shah from FreshBooks ... Eamon O'Connor from Refraction Films ... Onajide Shabakaka from the Miami Art Exchange ... and many more ...

So, from what I thought was going to be a nice get away turned out to be a networking home run ... some of these guys are making really big moves in the development community ... most notably, is Larry ... if that guys team works on a web application ... you are almost guaranteed that it's going to be rock solid.

BlogCFC was created by Raymond Camden. This blog is running version 5.9.7. Contact Florida Search Engine Optimization L.L.C.
Search Engine Optimization Specialist || Web Designer || Web Developer || Edward J Beckett ||
Search Engine Optimization Company  || SEO Services || Internet Marketing Company || Search Engine Optimization Expert || Florida Search Engine Optimization LLC
Florida Search Engine Optimization || Search Engine Optimization || SEO Services || Florida SEO Blog
Florida Search Engine Optimization
Search Engine Optimization
SEO Services
Florida SEO Blog
February-04-2012
4:26 PM EST