Archive for June, 2008

PHP Regex Extract Filename from Full Path

There are times you may want to extract filenames from their full paths. This example code extracts what looks like a filename from a full path. It makes an assumption that anything after the last directory separator (in this case / ) is the name of a file.

<html>
<head><title></title></head>
<body>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="value" value="<? print $_POST ['value']; ?>"/><br/>
<input type="submit" value="Submit" /><br/><br/>
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" )
{
    $mystr = $_POST['value'];
    if ( ereg( '^\/.*\/([^\/]+)$', $mystr, $matches ) )
    {
        echo "The file is: $matches[1]";
    }
    else
    {
        echo "<b>No file found here.</b>";
    }
}
?>
</form>
</body>
</html>

Regular Expression Explanation:

^

the beginning of the line, followed by

\/

a slash, then

.

any character

+

found one or more times, up to

\/

a slash, followed by

(

the beginning of the group that will capture the filename and contains

[

a character class that contains

^

anything that isn't

\/

a slash

]

the end of the character class

+

found one or more times

)

the end of the group, which goes up to

$

the end of the line

6 Comments

PHP Regex Remove Whitespace from HTML

There are many ways to optimize a HTML page, and one of these way is to remove white space. Whitespace between tags in HTML pages is just for readability, so if you have a site that has a lot of visits, it’s a good idea to consider strip away things such as extra whitespace in HTML. For a small to medium size webite, you can easily save 500 megabytes (MB) to a few gigabytes (GB) transfers a month just by cleaning whitespace and newline characters out of their HTML.

<html>
<head><title>Removing whitespace from HTML</title></head>
<body>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="html"
value="<?php print $_POST['html'];?>" /><br />
<input type="submit" value="Remove whitespace" /><br /><br />
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" )
{
$html = $_POST['html'];
$newhtml = preg_replace( "/(?:(?<=\>)|(?<=\/\))(\s+)(?=\<\/?)/","", $html );
print "<b>Original text was: &amp;nbsp;'". htmlspecialchars($html) .
"'</b><br/>";
print "<b>New text is: &amp;nbsp;'". htmlspecialchars($newhtml) . "'</b><br />";
}
?>
</form>
</body>
</html>

Regular Expression Explanation:

The look-behind group (?:(?<=\>)|(?<=\/\>)) matches the end of an HTML tag. The reason (?<=\>|\/\>) doesn’t work in the expression is because neither Perl nor PHP permits variable-length look-behinds. Each look-behind needs to be broken up by itself and put inside a group, such as (?:(?<=\>)|(?<\/\>)).

(?:

a noncapturing group that contains

(?<=

a positive look-behind with

\>

a >

)

the end of the positive look-behind

|

or

(?<=

a positive look-behind with

\/

a slash, followed by

\>

a >

)

the end of the positive look-behind

)

the end of the noncapturing group

(

a capturing group that contains

\s

whitespace

+

one time or more

)

the end of the capturing group

(?=

a positive look-ahead

\<

a <, followed by

\/

a slash

?

that can occur at most once

)

the end of the positive look-ahead.

12 Comments

PHP Regex Validate IP address

Before we see the code, let’s first understand what an IP address is consist of. IP address is four groups of numbers between 0 and 255 separated by periods. The address 192.168.0.1 is a valid IP address, but 256.0.1.2 isn’t.

You can use the code to validate an IP address.

<html>
<head><title>Validating IP addresses</title></head>
<style>
          .err { color : red ; font-weight : bold }
</style>
<body>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="input" /><br/>
<input type="submit" value="Submit Form" /><br/><br/>
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" )
{
    $input = $_POST['input'];
	if (preg_match( "/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $input))
{
        print "valid!";
    }
    else
    {
        print "<span class=\"err\">Bad IP address. Please correct and " .
            "resubmit the form</span><br/>";
    }
}
?>
</form>
</body>
</html>


Regular Expression Explanation:
The bulk of this expression is a group that breaks down the numbers that range from 0 to 255. The expression would be a lot shorter if 002 or 015 were valid instead of 2 and 15, respectively, but for this expression you want to specify IP addresses without the leading zeros.

The range from 0 to 255 breaks down into other ranges: 0–99, 100–199, 200–249, and 250–255. The expression to match this is ([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]), which can be broken down into [1-9]?[0-9], which will match 0–99; 1[0-9]{2}, which will match 100–199; 2[0-4][0-9], which will match 200–249; and 25[0-5], which will match 250–255.

After taking out the IP address validation expression, the rest of it breaks down like this:

^

the beginning of the line

(

the beginning of a group that contains

( )

the IP address expression explained previously

\.

a literal dot

)

the end of the group

{3}

occurring exactly three times

( )

another occurrence of the IP address

$

the end of the line.

hope it helps!

7 Comments

PHP Regex Extract Username from Email Address

You can use the following PHP snippet to grab the username out of an e-mail address. Given coldwarkids@ussr.com, the result will be coldwarkids.

This expression works to extract a username from an e-mail address because it gets everything up to the @ in one group and holds everything including and after the @ to the end of the line in another group. In the expression, after separating the two groups, it simply drops the second group so everything after @ goes nowhere.

<html>
<head><title>Extracting usernames from email addresses</title></head>
<style>
    .err { color : red ; font-weight : bold }
</style>
<body>
<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
<input type="text" name="input" /><br/>
<input type="submit" value="Submit Form" /><br/><br/>
<?php
if ( $_SERVER['REQUEST_METHOD'] == "POST" )
{
    $input = $_POST['input'];
    if (preg_match ( "/^([^@]+)(@.*)$/", $input ) )
    {
        # Do some processing here - input if valid
        $username = preg_replace( "/^([^@]+)(@.*)$/", "$1", $input);
        print "<b>Found username \"$username\"</b>";
    }
    else
    {
        print "<span class=\"err\">No username found here:</span><br/>";
    }
}
?>
</form>
</body>
</html>

Regular Expression Explanation:

^

the beginning of the line

(

a capturing group containing

[^@]

everything that isn’t an at (@) sign

+

found one or more times, up to

(

another group containing

@

an at sign (@)

.

any character

*

found zero, one, or many times

)

the end of the group

$

the end of the line.

1 Comment

Create Textpattern meta description

This tutorial teaches you how to create custom dynamic meta description in Textpattern for each individual section and article. The instruction is a bit long, so if you got any problem, just ask by posting a comment.

1. Navigate to the Preferences -> Advanced Preferences tab.
2. Find the Custom Fields section, which is the fourth section down on the page.
3. You’ll notice that by default, custom fields 1 and 2 are set up and named custom1 and custom2, respectively. Change the custom1 to meta_desc.
4. Click the Save button at the bottom of the page to store the new custom field names to the database.
5. Navigate to Presentation -> Forms tab.
6. Click on Create new form link at the top of the right hand sidebar.
7. In the textarea, type:

<meta name="description" content="<txp:custom_field name="meta_desc" />" />

8. Add value meta_dynamic to the Name (required) field.
9. Select article from the Type (required) dropdown menu.
10. Click the Save button at the bottom of the page to store the new custom field names to the database.
11. Again click on the Create new form link at the top of the right hand sidebar.
12. At this point, you may make a choice between the following two options depend on the way you layout your site structure.
a) Now if you use the default section as front page, type:

<txp:if_section name="">
		<txp:article_custom section="default" status="sticky" form="meta_dynamic" />
	<txp:else />
		<txp:if_individual_article>
			<txp:article form="meta_dynamic" />
		<txp:else />
			<txp:article status="sticky" form="meta_dynamic" />
		</txp:if_individual_article>
	</txp:if_section>

b) Now if you have a front page belongs to a section other than default section page, for instance ‘homepage’ section is your front page, In the textarea, change the second line above:

<txp:article_custom section="default" status="sticky" form="meta_dynamic" />

to:

<txp:article_custom section="homepage" status="sticky" form="meta_dynamic" />

13. Add value meta to the Name (required) field.
14. Select misc from the Type (required) dropdown menu.
15. Click the Save button at the bottom of the page to store the new custom field names to the database.
16. Naviagte to Presentation -> Pages, insert the following line at the head section of all template pages.

<txp:output_form form="meta" />

17. Navigate to the Admin -> Content -> Write tab.
18. Click the Advanced Options link at left to expand the menu.
19, under meta_desc, put in the meta description
19. If the article is an individual article, just select the section and category it belongs to. Else if you are writing the meta_desc for a section page, under Status, choose sticky, and select the section it belongs to, you can leave the main content empty.
20. After adding in meta_desc for all section and individual pages, just go to the site, view source, and the meta description should be rendered.

I know the instruction is a bit long, so if you got any problem, just write a comment. I will be more than happy to help!

2 Comments

JavaScript Control Flash Replay

Embedded Flash Movie in HTML document can be manipulated by using JavaScript. There are default build-in JavaScript functions that can be used to communicate with Flash. But there is one function which is doesn’t come by default but requested by many – the replay function. There are times you may want to instruct Flash to replay the movie using a JavaScript function, this can be easily done if we combine two build-in functions: play() and rewind(). Assume that you have the Flash movie code like the one below:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="560" height="404" id="coreMovie" align="middle">
<param name="allowScriptAccess" value="sameDomain" /><param name="wmode" value="transparent" />
<param name="movie" value="files/core.swf'" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="files/core.swf" quality="high" bgcolor="#ffffff" width="560" height="404" name="coreMovie" align="middle" wmode="transparent"  allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

Two attributes from the above standard code are important: the id attribute within tag and the name attribute under tag. The value of these two attributes should be the same and it acts as the reference when communicate with JavaScript. The JavaScript below controls the movie above.

function getFlashMovieObject(movieName) {
	if (window.document[movieName]) {
		return window.document[movieName];
	}
	if (navigator.appName.indexOf("Microsoft Internet")==-1) {
		if (document.embeds &amp;amp;amp;&amp;amp;amp; document.embeds[movieName]) {
			return document.embeds[movieName];
		}
	} else {
		return document.getElementById(movieName);
	}
}
function ReplayFlashMovie(mname) {
	var flashMovie=getFlashMovieObject(mname);
	flashMovie.Rewind();
	flashMovie.Play();
}
ReplayFlashMovie('coreMovie');

,

No Comments

Textpattern Tagging

I am a big Textpattern fan, and to me, it’s more flexible than Wordpress, but for many who have used both Textpattern and Wordpress, Wordpress provides more functions, and one of the functions is tagging. The lack of tagging feature frustrates some blogging and web content writer.

There is an easy way around this:

Use Textpattern keywords: Tagging content is associating any word and phrase that fits the piece, not
picking from a predetermined list of possible categories. Textpattern enables traditional tagging functionality out of the box through the Keywords field on the Write tab. A list of articles with similar keyword values can be output via a standard

<txp:article_custom />

tag.

So there are three steps to make this happen:

1. Go to the tab Presentation->Forms, from the top of the right sidebar, click on the ‘Create new form’ link.

2. In the textarea, type:

<li><txp:permlink><txp:title /></txp:permlink> (<txp:posted />)</li>

Under ‘Name (required)’ input filed, type taglinks.

Under ‘Type (required)’ dropdown menu, choose article.

Save the form.

3. Now navigate to any articles you have(Content->Articles), at the end the article, you might plug this into your article body:

<txp:article_custom form="taglinks" keywords="Fiona Apple" />

In this case, any articles containing the keyword “Fiona Apple” will appear in the list.

1 Comment

Textpattern More than Two Categories

Different content management systems (CMSs) and blogging software have conflicting nomenclature when it comes to the back end. In Wordpress, for instance, an article can have unlimited categories; a review of a restaurant might fall into these categories: reviews, restaurants, New York City, Asian Fusion, and more. This type of taxonomy—in which a piece of text is referenced by a host of keywords instead of falling neatly into a single category—is often called tagging. Bloggers like having lots of categories at their disposal because posts’ topics can be all over the map, making traditional organization structures inadequate.

Textpattern has caught some flack for allowing only two category associations per article because people want to tag their content. There is an easy way around this:

Use a plugin for multiple categories: Rob Sable has developed a plugin called rss_unlimited_categories that enables unlimited category associations for articles. It replaces the dual drop-down menus with a multiselectable list, offering the same functionality as Wordpress. This plugin also enables the output of the categories as a list or tag cloud.

,

1 Comment

Linux chmod 777 Recursively

There are times that you want to set permission for a folder of files. It’s very tedious to change every single file, so you must ask: is there a way to chmod a folder recursively, so that all files in a folder or directory can be set to writable by one command? Well, the answer is: Yes. There is a way and it’s very simple. There is a recursive chmod

chmod -R 777 /home/shi/Desktop/Host/lab/txp

The above code will set permission for all files under /home/shi/Desktop/Host/lab/txp directory, you can change it to anything you may like to point to.

Hope this helps!

1 Comment

Install IE6 using IEs 4 Linux on Ubuntu

No matter how anal IE6 is, it is still quite an important browser. According to statistics from W3School, by April 2008, there are still about 28.9% of surfers using IE6. So on my Ubuntu, I have no choice but having it installed.

To install IE6 and below, you should first have cabextract and Wine installed, if not, read Install and Configure Wine on Ubuntu first.

After that, you need to install IEs4Linux (IEs 4 Linux), to install IEs4Linux, execute the following command one by one in your terminal:

wget http://www.tatanka.com.br/ies4linux/downloads/ies4linux-latest.tar.gz
tar zxvf ies4linux-latest.tar.gz
cd ies4linux-*
./ies4linux

The installation failed when I ran the last installer command:
./ies4linux

You may get error message like:

Gtk-ERROR **: file /build/buildd/gtk+2.0-2.12.0/gtk/gtktextview.c: line 3352 (gtk_text_view_validate_onscreen): assertion failed: (text_view->onscreen_validated)
aborting…
ui/pygtk/python-gtk.sh: line 6: 6431 Aborted (core dumped) python “$IES4LINUX”/ui/pygtk/ies4linux-gtk.py

There are many ways around:

1. Run ./ies4linux again and this time did not change any options (previously if you checked box to install menu icon and removed desktop icon).

2. Another fix, a rather bizarre one for this problem is to execute the following command a few more times until it’s installed.

./ies4linux

While repeat the installer command above, the error getting farther each time, and finally it completely installed!

Hope this helps, and if you got any better fix, feel free post it here!

1 Comment