This XHTML header tags resource is a work in progress, perpetually expanding and evolving as new information is obtained, explored, and integrated. Hopefully, you will find it useful in some way. Even better, perhaps you will share any complimentary or critical information concerning the contents of this article.
If you think that nobody uses frames anymore, think again. I personally know of one person who threw down some tuf HTML frame action for a personal site. So, in the interest of prosperity, we are hereby establishing this post as our official dumping ground for all HTML frame-related garbage.
Break your pages out of someone else’s frames
We begin our journey with a totally sick JavaScript method for breaking pages out of the illegitimate frames of some ineffectually pathetic bastard:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
if ( window != top )
top.location.href = window.location.href;
//--><!]]>
</script>
This method works great at breaking out and redirecting the browser to the original page:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
var parent_location = new String(parent.location);
if ( ( top.location != location ) && parent_location.indexOf('http://domain.tld/path/to/page.html') != 0 )
top.location.href = document.location.href;
//--><!]]>
</script>
Optimize the content of an iframe
Moving right along, here is a helpful method for optimizing the content of an iframe. This code basically displays a link to the content that should be displayed if everything is working correctly. If for some reason the content is not displayed, the link will appear in its place, thereby enabling users to access the missing content via a new window:
<iframe src="page.html" width="333" height="333" scrolling="auto" frameborder="1">
<a href="page.html" target="_blank">
[Your browser does not support frames or is configured not to display frames. Click here to visit the related document.]
</a>
</iframe>
Control frameborder and scroll attributes for iframes via CSS
To control the frameborder=”value” and scroll=”yes/no” attributes for iframes using CSS, add the following styles to the document which is being displayed in the iframe:
When an accesskey attribute is present within a link tag, pressing alt+letter on the keyboard is equivalent to double-clicking that link. Generally speaking, the presence of an accesskey attribute within an element brings focus to that element. Thus, radio and check boxes are toggled, links are clicked, and form elements are navigated as the alt+letter combination is pressed.
It is also helpful to provide “skip-to” links that target specific areas of the site. For example, you may wish to enable users of screen readers to skip past or skip to navigational controls:
<div class="hide">
<ul id="top" class="access">
<li><a href="#content" title="Skip to Content" accesskey="c">Skip to Content</a></li>
<li><a href="#navigation" title="Skip to Menu" accesskey="m">Skip to Menu</a></li>
<li><a href="#search" title="Skip to Search" accesskey="s">Skip to Search</a></li>
</ul>
</div>
However, due to current lack of widespread browser support, explicit id-targeting may serve better:
<a href="#menu" title="Skip to navigation menu">Skip to navigation menu</a>
<a href="#content" title="Skip to main content">Skip to main content</a>
Another useful accessibility tool involving document meta-navigation is the tabindex, which is a numerical index that represents each element’s position in the tabbing order. By default, certain elements are ignored by the tabindex, while others retain a default order which may be overridden with explicitly stated tabindex values. Consider the following example, in which the tabbing order will be "red", "yellow", "blue", regardless of where the input elements appear on the page:
Let’s face it, spam sucks. Give spammers the figurative finger by using this nifty bit of JavaScript to hide your email address from the harvesters. Here is an easy “copy-&-paste” snippet for including a spam-proof email address in your web pages. Although there are a million ways of doing this, I am posting this for the record (and because I just can’t stand deleting usable code). This technique uses JavaScript, and therefore is not 100% ideal for all users. My advice would be to include a <noscript> element that contains an image of your email address. That way, users without JavaScript will still have access to your (spam-proof) email address. Of course, image-based text presents issues for text-only browsers, but hey, you gotta start somewhere! ;)
Spamless Email
Secure the function by adding this block of code to the document head, or by placing it within an external JavaScript file:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
function email(name, domain, extension) {
if (!document.write) return false;
if (document.write) {
var name; var domain; var extension;
document.write('<a href="' + 'mailto:' + name + '@' + domain + '.' + extension + '">' + name + '@' + domain + '.' + extension + '<\/a>');
}
}
//--><!]]>
</script>
Then, add this to the document body, replacing the three variables with real values:
Here is an example of how the function may be configured on an actual web page. This is the specific code that we use at Monzilla Media to hide email addresses from the spamholes:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
function email(m, o, n) {
if (!document.write) return false;
if (document.write) {
var m; var o; var n;
document.write('<p>Contact: <a href="' + 'mailto:' + m + '@' + o + '.' + n + '?subject=General%20Business" title="Contact">' + m + '@' + o + '.' + n + '<\/a><\/p>');
}
}
//--><!]]>
</script>
<script type="text/javascript">
<!--//--><![CDATA[//><!--
email("m0n", "monzilla", "biz");
//--><!]]>
</script>
<noscript><p>(enable javascript or view source to see the email link)</p></noscript>
Fix IE’s crazy box rendering. The first line limits to only IE. The second line
* html div#somediv { /* limits to all IE */
width: 300px; /* width for WinIE5.x */
w\idth: 333px; /* width for other IE */
}
div#somediv {
padding: 33px;
width: 377; /* width for all other browsers */
}
IE Double Float Bug
IE doubles the margin of any divs floated in the same direction. Great. To fix it, simply display the floated element as inline.
Clearing Divisions
Here are four relatively equally effective methods for clearing unruly divisions:
/* targets IE7 & below - valid CSS */
a:link:visited, a:visited:link {}
/* may be used to target any element */
#target:link:visited, #target:visited:link {}
Here are a few sIFR Notes for Perishable Press. Just what are we looking at here? Well, first it is important to understand the sIFR variables and the order in which they should appear:
The variable, sFlashVars consists of the following sub-variables (these should be seperated with an & sign:
# Align Flash text block textalign=center
# Moves text any number of pixels to the right offsetLeft=3
# Moves text any number of pixels down offsetTop=3
# Adds underline links when hovered underline=true
Then, inducing from the following code example, we should place a similar set of statements at the bottom of any pages requiring sIFR functionality:
Update: After upgrading Perishable Press in 2007, many of the hacks listed on this page are no longer applicable. Please refer to our new WordPress Core Edits for current information. Otherwise, this article remains online for reference purposes only.
The folks developing WordPress are continually rolling out “upgrades”. While it is generally a good idea to stay current, it can also be a bit of a pain if you have made any changes to the WordPress core files. Our recommendation? Keep a log such as this one that either includes all edits or links to posts describing them. That way, when it is time to upgrade to WP 3.0.1, WP 3.0.2, … WP 9.0.1, WP 9.0.2 … (you get the idea), it will simply be a matter of referring to your handy WP core file change log and then going thru the list, copying & pasting your way back to complete functionality. Just remember to add any subsequent changes to the list, though, or you may find yourself scratching your head after the next upgrade. Another good idea involves carefully comparing any code you are replacing, checking to make sure the wizards at WordPress haven’t changed any aspects of the original code (of which you are replacing).
So, without further ado, here are the WordPress core file edits currently operating here at Perishable Press:
Customize the_excerpt function
File: wp-includes/functions-formatting.php (~ lines #763 & 767): set to desired values:
$excerpt_length = 50;
...
array_pop($words);
array_push($words, '[...] ( click post title to read more )');
$text = implode(' ', $words);
Customize the wpautop function
File: wp-includes/functions-formatting.php (~ line #72, #83):
$pee = preg_replace('/\n?(.+?)(?:\n\s*\n|\z)/s', "<p>$1</p>\n\t\t\t\t\t\t", $pee); // make paragraphs, including one at the end
$string = '<a href="'.get_permalink($post->ID).'" title="Go to previous post">'.$previous;
...
$string = '<a href="'.get_permalink($post->ID).'" title="Go to next post">'.$next;
...
...
function next_posts_link($label='Next Page »', $max_page=0) {
...
echo '" title="Go backward in time">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&$1', $label) .'</a>';
...
function previous_posts_link($label='« Previous Page') {
...
echo '" title="Go forward in time">'. preg_replace('/&([^#])(?![a-z]{1,8};)/', '&$1', $label) .'</a>';
...
function posts_nav_link($sep=' — ', $prelabel='« Previous Page', $nxtlabel='Next Page »') {
Vars Tweak for htaccess Edits
File: wp-includes/vars.php (~ #35):
// Server detection
//the next line is used to allow WP to write htaccess rules during permalink creation (comment out the $is_apache line first)
//$is_apache = 1;
$is_apache = ( strstr($_SERVER['SERVER_SOFTWARE'], 'Apache') || strstr($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') ) ? 1 : 0;
Customize Password-Protected Posts
File: template-functions-post.php (~ line #3):
function get_the_password_form() {
$output = '<form action="' . get_settings('siteurl') . '/wp-pass.php" method="post">
<p>' . __("This post is password protected. To view it please enter your password below:") . '</p>
<p><small><label class="h">' . __("Password: ") . ' </label><input class="postpassword" name="post_password" type="password" size="11" /> <input class="passwordsubmit" type="submit" name="Submit" value="' . __("Submit »") . '" /></small></p>
</form>
<div class="clear vspace"> </div>
';
return $output;
}
File: wp-includes/functions.php (~ lines #1067): insert "@" before parse_url and praise the Lord!
Remove CSS Link to Print Stylesheet
File: press/wp-subscription-manager.php (~ line #100): delete the following line to eliminate unnecessary 404 errors when users subscribe/unsubscribe to comments (or when managing subscriptions):
File: wp-includes/feed-functions.php (line #84): edit according to current default theme requirements:
echo "<a href='$url'>$link_text</a>";
--- changed to --->
echo "<a class=\"feed-icon\" href='$url' title=\"Subscribe to comments for this article\" rel=\"nofollow\">$link_text</a>";
Customize Commentator Links
File: wp-includes/comment-functions.php (~lines #358-368): swap the following:
/* original */
function get_comment_author_link() {
global $comment;
$url = get_comment_author_url();
$author = get_comment_author();
if ( empty( $url ) || 'http://' == $url )
$return = $author;
else
$return = "<a href='$url' rel='external nofollow'>$author</a>";
return apply_filters('get_comment_author_link', $return);
}
Another neat trick is to include a default message if some condition is met. For example, here we are telling WordPress to display the text string, "Search Perishable Press", unless someone is actually searching for something:
Here is a core hack to get WordPress to search pages in addition to posts for older (1.5) versions of WordPress (I think newer versions do this automatically). Open the file wp-includes/classes.php and look around line #493 for the following code:
if ($this->is_page) {
$where .= ' AND (post_status = "static")';
} else {
$where .= ' AND (post_status = "publish")';
}
Replace (comment out) that entire chunk of code and replace it with this:
if ($this->is_page) {
$where .= ' AND (post_status = "static")';
} elseif ($this->is_search) {
$where .= ' AND (post_status = "publish" OR post_status = "static")';
} else {
$where .= ' AND (post_status = "publish")';
}
If you are running WordPress 2.0.2 and have enabled permalinks, you may have had problems creating a new category or page to your site. I recently encountered this dilemma and devised the following strategy for adding, editing, or even deleting WordPress categories and pages. Note: this tutorial assumes you are running Apache.
First, open wp-includes/vars.php and find (around line #39):
Next, check the file attributes of your htaccess file(s). Ensure that the file is writable with a setting of either 666 or even 777 (or whatever works best on your server).
Finally, create or edit the necessary category or categories, publish a post or two under the new/edited category, and then double-check that everything is working as expected.
Now that you are a big winner with your new category, be sure to change the htaccess file permissions back to 644 or equivalent. Also, comment out the new line in the vars.php file and uncomment out (i.e., comment in) the original line of code.
To customize WordPress-powered password-protected posts such as this one, follow these simple steps.
First open template-functions-post.php and find the function get_the_password_form, which is located near the top of the page.
There are several aspects of this function that you may wish to customize. For example, the Perishable Press website requires several CSS attributes for stylistic control. Thus we simply added the class postpassword to the form input field, as well as the class passwordsubmit to the form submit button. This enabled full stylistic control over password-protected posts. You may also wish to modify the size of the input text field, or even edit the submit-button text.
Finally, remember to check both the post comment view for proper “password message” display. If it is not, edit the local comments.php file (usually near the top) until the message displays correctly.
The overly dramatic process of transferring our Online Empire to a new server and then back again manifests several valuable lessons. Please look back your note and observe the following suggestions during any future server migration and/or domain propagation events…
About a year ago we signed up with a hosting provider that offered one of the best hosting deals around: lots of space, bandwidth, and transfer — plus all of the usual server software amenities that make life easier. Everything went smoothly at first…
In fact, the first six months of service were close to 100%. The few help-ticket items submitted were promptly resolved in a professional manner. We were ready to start some business and everything was going great. Then, about five months ago, we began noticing a serious increase in server downtime. Help tickets were also slow-going and the responses were like these cryptic one-liners that failed to address the actual problem, demonstrating a serious lack of concern and providing virtually no help. Further, multiple emails concerning account billing and renewal went (and remain) completely ignored. Indeed, email remains their only method of communication. At this point, we felt stranded, ignored, and utterly alone. Given this level of service, we were not comfortable hosting websites for our clients.
The robots exclusion standard or robots.txt protocol is a convention to prevent cooperating web spiders and other web robots from accessing all or part of a website. The information specifying the parts that should not be accessed is specified in a file called robots.txt in the top-level directory of the website.
Notes on the robots.txt Rules:
Rules of specificity apply, not inheritance. Always include a blank line between rules. Note also that not all robots obey the robots rules — even Google has been reported to ignore certain robots rules. Also, comments are allowed (and recommended) within any robots.txt file when written on a per-line basis. Simply begin each line of comments with a pound sign “#”.
Prevent Robots from Indexing the Entire Site:
User-agent: * Disallow: /
Prevent a Specific Robot from Indexing the Entire Site:
User-agent: Googlebot-Image Disallow: /
Prevent all Robots from Indexing Specific Pages/Directories:
In this example, no robots are allowed to index anything except for Google, which is allowed to index everything except the specified pages/directories. Note the required blank line between the rules.
In this example, no agents are allowed to index anything except for Alexa, which is allowed to index anything. Note that there is a blank space after the colon, which enables this rule to work.
User-agent: * Disallow: /
User-agent: ia_archiver Disallow:
Prevent all Agents Except for Google:
Here is Google’s preferred way to disallow all agents anything except Google, which is allowed everything. Note that “Allow” is not a standard parameter and therefore is not recommended.
User-agent: * Disallow: /
User-agent: Googlebot Allow: /
Notes on the “meta robots” Tag:
Certain robots rules may also be included in the head section of a web document. Examine the following examples:
Here is a general list of values available for the “content” attribute of the “meta robots” tag:
noindex, index — Determines indexing of site/pages. nofollow, follow — Determines following of links. nosnippet — Do not display excerpts or cached content. noarchive — Do not display or collect cached content.
Additionally, Altavista supports:
noimageindex — Index text but not images. noimageclick — Link to pages but not images.
Welcome to Perishable Press! This article covers a plethora of useful JavaScript tips and tricks. For more excellent JavaScript information, check out the JavaScript tag archive. If you like what you see, I encourage you to subscribe to Perishable Press for a periodic dose of online enlightenment ;)
Nifty JavaScript Design Tricks
Clickable divs
Standard design practice dictates that the site logo or banner located at the top of the page links to the home page of the site. There are several methods for including such functionality into a design, including this JavaScript trick that transforms an entire element (e.g., any div) into a link pointing to the site root:
<div id="banner" onclick="location.href='/';" style="cursor:pointer;">
[ content goes here ]
</div>
Hide/Validate JavaScript Code
JavaScript Comments
Commenting your scripts is an excellent and highly recommended practice. Here are two methods of commenting within a block of JavaScript.
<script type="text/javascript">
// Use two forward slashes for single line comments
/* Use this method for
multi-line comments */
</script>
Link to an External JavaScript File
This is the preferred method of including JavaScript files. It is invisible to non-JavaScript browsers, and keeps the document from breaking during validation. Use if possible.
Hiding JavaScript code from non-compliant browsers is rather easy, just employ the following lines of code:
<script type="text/javascript">
<!--
JavaScript goes here
JavaScript goes here
//-->
</script>
Unfortunately, JavaScript code does not validate as XHTML. Fortunately, it is possible to present your code as invisible to the validators by enveloping it with the following lines of code:
<script type="text/javascript">
<![CDATA[
JavaScript goes here
JavaScript goes here
]]>
</script>
Combining these two methods produces a deadly weapon in the hellish JavaScript battle:
<script type="text/javascript">
<!--//--><![CDATA[//><!--
JavaScript goes here
JavaScript goes here
//--><!]]>
</script>
And, an alternate method has been suggested, but sustains inconsistent consensus:
<script type="text/javascript">
/* <![CDATA[ */
JavaScript goes here
JavaScript goes here
/* ]]> */
</script>
Here is the same commenting method used for CSS:
<style type="text/css">
/* <![CDATA[ */
CSS goes here
CSS goes here
/* ]]> */
</style>
A slightly modified version of the previous method:
<style type="text/css">
/* //<![CDATA[ */
<!--
CSS goes here
CSS goes here
//-->
/* //]]> */
</style>
Here is yet another way to comment out CSS content:
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
CSS goes here
CSS goes here
/*]]>*/-->
</style>
Finally, although popular, avoiding this method has been recommended:
<script type="text/javascript">
//<![CDATA[
<!--
JavaScript goes here
JavaScript goes here
//-->
//]]>
</script>
Non-JavaScript Browser Support
Use the <noscript> tag to provide support for antiquated browsers and serve 'em some alternate content. The <noscript> tag operates according to the presence/absence of JavaScript. Consider the following:
<noscript>
<p>This will not be displayed if JavaScript is enabled.</p>
</noscript>
Here is a specific example that would provide a user with the option to continue browsing without JavaScript:
<noscript>
<p>
It appears your browser doesn't support JavaScript.
Please visit <a href="http://domain.tld/noscript.html">the no-script page</a>
to see a non-JavaScript version of this page.
</p>
</noscript>
Welcome to Perishable Press! This article covers many different aspects of WordPress functionality, including customizing quicktags, deleting the cache, numbering comments & posts, changing password text, and displaying archive menus. Note that this article was written for previous versions (i.e., less than 2.0) of WordPress. Discrepancies may exist between the code presented in this post and that of more recent versions of WordPress. Nonetheless, this information is presented for references purposes with the hope that it will prove useful for those working with everyone’s favorite blogging platform, WordPress!
Customize WordPress Quicktags
The more Quicktag:
The <!--more--> Quicktag breaks a post into “teaser” and content sections. Type a few paragraphs, insert this tag, then compose the rest of your post. On your blog’s home page you’ll see only those first paragraphs with a “(more…)” hyperlink, which when followed displays the rest of the post’s content.1
Customize the more Quicktag:
To customize the “(more…)” hyperlink, open the file “wp-includes/template-functions-post.php” and locate the following lines (around lines #54 & #62, respectively):
function the_content($more_link_text = '(more...)', $str... function get_the_content($more_link_text = '(more...)', $str...
For each line, carefully replace (more...) with whatever text you wish. Possibilities include Continued >> and [ Read on... ].
Modify the Target of the more Quicktag:
To modify the target of the “(more…)” hyperlink, replace the following statement (located within “wp-includes/template-functions-post.php” around line #92):
The <!--nextpage--> Quicktag is similar to the more tag, except it can be used any number of times in a post, and each insert will “break” and paginate the post at that location. Hyperlinks to the paginated sections of the post are then generated in combination with the wp_link_pages() or link_pages() template tag.2
Customize the_excerpt Function
Open the file “wp-includes/functions-formatting.php” and find the following line of code (located around line #732):
array_push($words, '[...]');
To customize the continuation notation for excerpts, simply replace [...] with the text of your choice. Something like “[...continued »]” or “[ click post title to read more ]” works just swell.
To change the default number of words included in excerpts, edit the 55 in the following line of code (located around line #728) to reflect the desired number of excerpt words:
$excerpt_length = 55;
Fix the WordPress "Remember Me" Option
If the WordPress admin seems to “forget” you even after following all of the proper protocols, try changing the actual link that takes you to your WP admin-login page. Change the link from /wp-login.php (the file) to /wp-admin/ (the directory).
Cache Notes
It is totally safe to delete everything in the /wp-content/cache/ folder!
Custom Number of Posts
Sometimes it is nice to customize the number of posts displayed for different loops. For example, if you have different themes, it is possible for one theme to show five posts while another theme only shows one post. To pull it off, simply place the following line of PHP before the loop:
<?php query_posts('showposts=n'); ?>
Where "n" represents the number of posts that the loop will display 3. Nice ;) Update: This method needs some work — seemed okay at first, but then links to posts always go to the first blog page..
Tweaking Comment Numbers
Instruct WordPress to begin each post’s comment numbers with the number "1" (or any number), and then proceed numerically thenceforth by adding this line at the top of comments.php..
<?php $commentcount=1; // number of first comment for each post ?>
..and then placing this line at the location where you would like the comment numbers to appear:
<?php echo $commentcount++; ?>
Another method for accomplishing the same thing involves replacing this code (located in comments.php)..
<?php if ( $comments ) : ?>
<?php foreach ($comments as $comment) : ?>
..with this..
<?php if ( $comments ) : ?>
<?php foreach ($comments as $comment) : $comment_count++;?>
..and then placing this line at the location where you would like the comment numbers to appear:
<?php echo $commentcount++; ?>
Customize Default Password Text
To change the default WordPress password text, open the file "wp-includes/comment-functions.php", and scroll to around line #309. Look for the password text and change it to whatever you prefer. Note: this default password text is different than the password text specified in the comments.php file.
Dropdown Archive Menus
To create dropdown archive menus (using get_archives4), simply emulate one of the following chunks of code and tweak to suit:
Welcome to Perishable Press! This article, Stupid htaccess Tricks, covers just about every htaccess “trick” in the book, and is easily the site’s most popular offering. In addition to this htaccess article, you may also want to explore the rapidly expanding htaccess tag archive. Along with all things htaccess, Perishable Press also focuses on (X)HTML, CSS, PHP, JavaScript, security, and just about every other aspect of web design, blogging, and online success. If these topics are of interest to you, I encourage you to subscribe to Perishable Press for a periodic dose of online enlightenment ;)