Saturday, 10 October 2015
Regular Expressions ~ Hands On!
Sooner or later you’ll run across a regular expression. With their cryptic syntax, confusing documentation and massive learning curve, most developers settle for copying and pasting them from StackOverflow and hoping they work. But what if you could decode regular expressions and harness their power? In this article, I'll show you why you should take a second look at regular expressions, and how you can use them in the real world.
Why Regular Expressions?
Why bother with regular expressions at all? Why should you care?
- Matching: Regular expressions are great at determining if a string matches some format, such as a phone number, email or credit card number.
- Replacement: Regular expressions make it easy to find and replace patterns in a string. For example,
text.replace(/\s+/g, " ")replaces all chunks of whitespace intext, such as" \n\t ", with a single space. - Extraction: It's easy to extract pieces of information from a pattern with regular expressions. For example,
name.matches(/^(Mr|Ms|Mrs|Dr)\.?\s/i)[1]extracts a person's title from a string, such as"Mr"from"Mr. Schropp". - Portability: Almost every major language has a regular expression library. The syntax is mostly standardized, so you don't have to worry about relearning regexes when you switch languages.
- Coding: When writing code, you can use regular expressions to search through files with tools such as find and replace in Atom or ack in the command line.
- Clear and Concise: If you're comfortable with regular expressions, you can perform some pretty tricky operations with a very small amount of code.
- Fame and Glory: Regular expressions will give you superpowers.
How to Write Regular Expressions
The best way to learn regular expressions is by using an example. Let's say you're building a web page with a phone number input. Because you're a rockstar developer, you decide to display a checkmark when the phone number is valid and an X when it's invalid.
<input id="phone-number" type="text"> <label class="valid" for="phone-number"><img src="check.svg"></label> <label class="invalid" for="phone-number"><img src="x.svg"></label>
input:not([data-validation="valid"]) ~ label.valid, input:not([data-validation="invalid"]) ~ label.invalid { display: none; }
$("input").on("input blur", function(event) { if (isPhoneNumber($(this).val())) { $(this).attr({ "data-validation": "valid" }); return; } if (event.type == "blur") { $(this).attr({ "data-validation": "invalid" }); } else { $(this).removeAttr("data-validation"); } });
With the above code, whenever a person types or pastes a valid number into the input, the check image is displayed. When the user blurs the input and the value is invalid, the error X is displayed.
Since you know that phone numbers are made up of ten digits, your first pass at
isPhoneNumber looks like this:function isPhoneNumber(string) { return /\d\d\d\d\d\d\d\d\d\d/.test(string); }
This function contains a regular expression between the
/ characters with ten \d's, or digit characters. The test method returns true if the regex matches the string and false if it doesn't. If you run isPhoneNumber("5558675309"), it returns true! Woohoo!
However, writing ten
\d's is little redundant. Luckily, you can use the curly braces to accomplish the same thing.function isPhoneNumber(string) { return /\d{10}/.test(string); }
Sometimes, when people type in phone numbers, they start with a leading
1. Wouldn't it be nice if your regex could handle those cases? You can with the ? character!function isPhoneNumber(string) { return /1?\d{10}/.test(string); }
The
? symbol means zero or one, so now isPhoneNumber returns true for both"5558675309" and "15558675309"!
So far,
isPhoneNumber is pretty good, but you're missing one key thing: regexes are more than happy to match parts of a string. As it stands, isPhoneNumber("555555555555555555")returns true because that string contains ten numbers. You can fix this problem by using the^ and $ anchors.function isPhoneNumber(string) { return /^1?\d{10}$/.test(string); }
Roughly,
^ matches the beginning of the string and $ matches the end, so now your regex will match the whole phone number.Getting Serious
You released your page, and it's a smashing success, but there's one major problem. In the U.S., there are many common ways to write a phone number:
(234) 567-8901234-567-8901234.567.8901234/567-8901234 567 8901+1 (234) 567-89011-234-567-8901
While your users could leave out the punctuation, it's much easier for them to type out a formatted number.
While you could write a regular expression to handle all of those formats, it's probably a bad idea. Even if you nail every format in this list, it's very easy to miss one. Besides, you really only care about the data, not how it's formatted. So, instead of worrying about punctuation, why not strip it out?
function isPhoneNumber(string) { return /^1?\d{10}$/.test(string.replace(/\D/g, "")); }
The
replace function is replacing the \D character, which matches any non-digit characters, with an empty string. The g, or global flag, tells the function to replace all matches to the regular expression instead of just the first.Getting Even More Serious
Everybody loves your phone number page, and you're the king of the water cooler at work. However, being the pro that you are, you want to take things one step further.
The North American Numbering Plan is the phone number standard used in the U.S., Canada, and twenty-three other countries. This system has a few simple rules:
- A phone number (
(234) 567-8901) is broken up into three pieces: The area code (234), the exchange code (567) and the subscriber number (8901). - For the area code and exchange code, the first digit can be
2through9and the second and third digits can be0through9. - The exchange code cannot have
1as the third digit if1is also the second digit.
Your regex already works for the first rule, but it breaks the second and third. For now, let's only worry about the second rule. The new regular expression needs to look something like the following:
/^1?<AREA CODE><EXCHANGE CODE><SUBSCRIBER NUMBER>$/
The subscriber number is easy; it's four digits.
/^1?<AREA CODE><EXCHANGE CODE>\d{4}$/
The area code is a little tricker. You need a number between
2 and 9, followed by two digits. To accomplish that, you can use a character set! A character set lets you specify a group of characters to choose from./^1?[23456789]\d\d<EXCHANGE CODE>\d{4}$/
That's great, but it's annoying to type out all the characters between
2 and 9. Clean it up with a character range./^1?[2-9]\d\d<EXCHANGE CODE>\d{4}$/
That's better! Since the exchange code is the same as the area code, you could duplicate your regex to finish off the number.
/^1?[2-9]\d\d[2-9]\d\d\d{4}$/
But, wouldn't it be nice if you didn't have to copy and paste the area code section of your regex? You can simplify it up by using a group! Groups are formed by wrapping characters in parentheses.
/^1?([2-9]\d\d){2}\d{4}$/
Now,
[2-9]\d\d is contained in a group and {2} specifies that that group should occur twice.
That's it! Here's what the final
isPhoneNumber function looks like:function isPhoneNumber(string) { return /^1?([2-9]\d\d){2}\d{4}$/.test(string.replace(/\D/g, "")); }
When to Avoid Regular Expressions
Regular expressions are great, but there's some problems you just shouldn't tackle with them.
- Don't be too strict. There's little value in being too strict with regular expressions. For phone numbers, even if we did match all of the rules in NANP, there's still no way to know if a phone number is real. If I rattled off the number
(555) 555-5555, it matches the pattern but it's not a real phone number. - Don't write an HTML parser. While it's fine to use regexes to parse simple things, they're not useful for parsing entire languages. Without getting too technical, you're not going to have a good time parsing non-regular languages with regular expressions.
- Don't use them for really complicated strings. The full regex for emails is 6,318 characters long. A simple, imperfect one looks like this:
/^[^@]+@[^@]+\.[^@\.]+$/. As a general rule of thumb, if you regular expression is longer than a line of code, it might be time to look for another solution.
Wrapping Up
In this article, you've learned when to use regular expressions and when to avoid them, and you've experienced the process of writing one. Hopefully regular expressions seem a bit less ominous, and maybe even intriguing. If you use a regex to solve a tricky problem, let me know in the comments!
Clipboard.js makes it easy to copy and cut text from elements in a web page, without the need for Flash!
Why
Copying text to the clipboard shouldn't be hard. It shouldn't require dozens of steps to configure or hundreds of KBs to load. But most of all, it shouldn't depend on Flash or any bloated framework.
That's why clipboard.js exists.
Install
You can get it on npm.
npm install clipboard --save
Or bower, too.
bower install clipboard --save
If you're not into package management, just download a ZIP file.
Setup
First, include the script located on the
dist folder.<script src="dist/clipboard.min.js"></script>
Or load it from a CDN.
<script src="https://cdn.rawgit.com/zenorocha/clipboard.js/master/dist
Now, you need to instantiate it using a DOM selector. This selector corresponds to the trigger element(s), for example<button class="btn">.
new Clipboard('.btn');
Internally, we need to fetch all elements that matches with your selector and attach event listeners for each one. But guess what? If you have hundreds of matches, this operation can consume a lot of memory.
For this reason we use event delegation which replaces multiple event listeners with just a single listener. After all, #perfmatters.
Usage
We're living a declarative renaissance, that's why we decided to take advantage of HTML5 data attributes for better usability.
Copy text from another element
A pretty common use case is to copy content from another element. You can do that by adding a data-clipboard-targetattribute in your trigger element.
The value you include on this attribute needs to match another's element selector.
<!-- Target -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
<img src="assets/clippy.svg" alt="Copy to clipboard">
</button>
Cut text from another element
Additionally, you can define a data-clipboard-action attribute to specify if you want to either copy or cut content.
If you omit this attribute, copy will be used by default.
<!-- Target -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>
<!-- Trigger -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
Cut to clipboard
</button>
As you may expect, the cut action only works on <input> or<textarea> elements.
Copy text from attribute
Truth is, you don't even need another element to copy its content from. You can just include a data-clipboard-textattribute in your trigger element.
<!-- Trigger -->
<button class="btn" data-clipboard-text="Just because you can doesn't mean you should — clipboard.js">
Copy to clipboard
</button>
Events
There are cases where you'd like to show some user feedback or capture what has been selected after a copy/cut operation.
That's why we fire custom events such as success and error for you to listen and implement your custom logic.
var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
For a live demonstration, just open your console :)
Advanced Usage
If you don't want to modify your HTML, there's a pretty handy imperative API for you to use. All you need to do is declare a function, do your thing, and return a value.
For instance, if you want to dynamically set a target, you'll need to return a Node.
new Clipboard('.btn', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
If you want to dynamically set a text, you'll return a String.
new Clipboard('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
}
});
Also, with are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.
var clipboard = new Clipboard('.btn');
clipboard.destroy();
Browser Support
This library relies on both Selection and execCommand APIs. The second one is supported in the following browsers.
Chrome 42+
Firefox 41+
IE 9+
Opera 29+
Safari ✘
Although copy/cut operations with execCommand aren't supported on Safari yet (including mobile), it gracefully degrades because Selection is supported.
That means you can show a tooltip saying Copied! whensuccess event is called and Press Ctrl+C to copy when errorevent is called because the text is already selected.
For a live demonstration, open this site on Safari.
Unraveling the Secrets of WordPress' Comments.php File
WordPress seems to be everywhere these days, and it's no wonder with it's ease of use and ease of customization. In this tutorial, I'll be dissecting the default WordPress theme's comments.php structure and giving you various snippets of code to make your skinning easier.
1. The PHP Backend
<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?>
<?php endif; ?>
<?php if(!empty($post->post_password)) : ?>
<?php if($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) : ?>
<?php endif; ?>
<?php endif; ?>
<?php if($comments) : ?>
<?php foreach($comments as $comment) : ?>
<?php if ($comment->comment_approved == '0') : ?>
<?php endif; ?>
<?php endforeach; ?>
<?php else : ?>
<?php endif; ?>
<?php if(comments_open()) : ?>
<?php if(get_option('comment_registration') && !$user_ID) : ?>
<?php else : ?>
<?php if($user_ID) : ?>
<?php else : ?>
<?php endif; ?>
<?php endif; ?>
<?php else : ?>
<?php endif; ?>
This is the raw PHP code that makes your comments.php file function. To a novice, this might look intimidating. However, do not worry: with this tutorial everything in your comments file will become crystal clear!
2. General Code
Preventing direct access to comments.php
<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?> <?php endif; ?>
This line of code prevents users from viewing comments.php by accident. This page is meant to be included in a post page, not separately. You could consider this a security measure. Inside the statement, you could insert any message you'd want to be displayed to the person viewing the comments.php file, preferably a
diestatement.<?php if(!empty($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME'])) : ?>
<?php die('You can not access this page directly!'); ?>
<?php endif; ?>
Is a password required?
<?php if(!empty($post->post_password)) : ?> <?php if($_COOKIE['wp-postpass_' . COOKIEHASH] != $post->post_password) : ?> <?php endif; ?> <?php endif; ?>
This statement (well, 2 actually, but it makes more sense if you view them as one) checks whether a password is required to view the post. Obviously, if you don't have the password to view the post, you're also not allowed to view the comments.
The first
if checks whether there is a password set. The second if statement checks whether there is a cookie with a password in place and displays the according message when it's not there. You can customize the error message by placing whatever you choose inside the second if statement.3. Displaying The Comments
<?php if($comments): ?> <?php foreach ($comments as $comment) : ?> <?php if ($comment->comment_approved == '0') : ?> <?php endif; ?> <?php endforeach; ?> <?php else : ?> <?php endif; ?>
This first conditional statement (
if($comments)) checks if there are comments and then loops through them with a foreach statement. Inside the foreach statement, you'll notice the following conditional statement: if($comment->comment_approved == '0'). This checks if the comment has been approved, and shows a message if it's not yet approved.
An example of this would be the following piece of code.
<?php if($comments) : ?>
<ol>
<?php foreach($comments as $comment) : ?>
<li>
<?php if($comment->comment_approved == '0') : ?>
<p>Your comment is awaiting approval</p>
<?php endif; ?>
<p>Your comment</p>
</li>
<?php endforeach; ?>
</ol>
<?php else : ?>
<p>No comments</p>
<?php endif; ?>
Basic comment template tags
To make this a functional piece of code, you'll need to use the template tags WordPress provides.
| Template Tag | Description |
|---|---|
<?php comment_ID(); ?> | the ID of a comment |
<?php comment_author(); ?> | the author of a comment |
<?php comment_author_link(); ?> | the author of a comment, wrapped with a link to his website if he specified one |
<?php comment_type(); ?> | the type of comment; pingback, trackback or a comment |
<?php comment_text(); ?> | the actual comment |
<?php comment_date(); ?> | the date it was posted |
<?php comment_time(); ?> | the time it was posted |
The final result
<?php if($comments) : ?>
<ol>
<?php foreach($comments as $comment) : ?>
<li id="comment-<?php comment_ID(); ?>">
<?php if ($comment->comment_approved == '0') : ?>
<p>Your comment is awaiting approval</p>
<?php endif; ?>
<?php comment_text(); ?>
<cite><?php comment_type(); ?> by <?php comment_author_link(); ?> on <?php comment_date(); ?> at <?php comment_time(); ?></cite>
</li>
<?php endforeach; ?>
</ol>
<?php else : ?>
<p>No comments yet</p>
<?php endif; ?>
Inserting this into comments.php would give you a ordered list with the comments and the required information or display a message stating that there aren't any comments.
4. The Comment Form
Are you still following me? Good! We're almost there. We just need to process that comment form... Okay, maybe I lied about almost being there. The comment form is actually one of the harder parts of the entire comments.php skin file.
You'll be bombarded with several conditional statements (is a login required, are you logged in, ...). This part is where most starting skinners have the most trouble: misplacing form elements could prevent the form from working at all, without giving a specific PHP error.
To give you an insight into the conditional statements that are involved in the comment form, I'll first be explaining those statements, and include the HTML later on explaining why it should be where it is.
Conditional statement overview
<?php if(comments_open()) : ?>
<?php if(get_option('comment_registration') && !$user_ID) : ?>
<?php else : ?>
<?php if($user_ID) : ?>
<?php else : ?>
<?php endif; ?>
<?php endif; ?>
<?php else : ?>
<?php endif; ?>
The first conditional statement you encounter is
<?php if(comments_open()) : ?> . This basically checks if the comments are open. Obviously, if the comments are closed, you can't post a comment and the comment form is not needed. You can put the message you want to be displayed if the comments are closed between the last<?php else : ?> and<?php endif; ?>.
The second conditional statement (
<?php if(get_option('comment_registration') && !$user_ID) : ?>) checks whether you need to be registred to post a comment and if you are logged in. If the conditional statement is fulfilled, the script should display a link to a place where users can log in. If registration is not required or you are already logged in, the script will continue with the else part and display the form.
Our final conditional statement then checks if you are logged in or not. Obviously, if you're already logged in it's useless to make you fill in your name, email and website again.
Inserting the form
Congratulations, we've plowed through all of the conditional statements in thecomments.php file. Now, all that is left is to add the form in there.
The first thing I can hear you think is: where the hell is that form going to start? Well, you just have to follow common sense. The second conditional statement checks whether you have to be logged in or not, therefor you'd have to display no form until after this statement. Thus the entire form is located inside this conditional statement.
<?php if(comments_open()) : ?>
<?php if(get_option('comment_registration') && !$user_ID) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p><?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if($user_ID) : ?>
<?php else : ?>
<?php endif; ?>
</form>
<?php endif; ?>
<?php else : ?>
<p>The comments are closed.</p>
<?php endif; ?>
I've also thrown in the link to the login page, just as I found it in the defaultcomments.php. As I said before, the last conditional statement checks whether you're logged in or not. Obviously, the name, email and website input fields are only displayed if you're not logged in. Let's throw them in there!
<?php if(comments_open()) : ?>
<?php if(get_option('comment_registration') && !$user_ID) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p><?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if($user_ID) : ?>
<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Log out »</a></p>
<?php else : ?>
<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
<label for="author"><small>Name <?php if($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
<label for="email"><small>Mail (will not be published) <?php if($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
<label for="url"><small>Website</small></label></p>
<?php endif; ?>
</form>
<?php endif; ?>
<?php else : ?>
<p>The comments are closed.</p>
<?php endif; ?>
Alright! We're almost there! We just need to add in some simple lines of code such as a textarea and a submit button. These go after the last conditional statement, since it's irrelevant for these elements if you are logged in or not.
<?php if(comments_open()) : ?>
<?php if(get_option('comment_registration') && !$user_ID) : ?>
<p>You must be <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?redirect_to=<?php echo urlencode(get_permalink()); ?>">logged in</a> to post a comment.</p><?php else : ?>
<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
<?php if($user_ID) : ?>
<p>Logged in as <a href="<?php echo get_option('siteurl'); ?>/wp-admin/profile.php"><?php echo $user_identity; ?></a>. <a href="<?php echo get_option('siteurl'); ?>/wp-login.php?action=logout" title="Log out of this account">Log out »</a></p>
<?php else : ?>
<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
<label for="author"><small>Name <?php if($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
<label for="email"><small>Mail (will not be published) <?php if($req) echo "(required)"; ?></small></label></p>
<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
<label for="url"><small>Website</small></label></p>
<?php endif; ?>
<p><textarea name="comment" id="comment" cols="100%" rows="10" tabindex="4"></textarea></p>
<p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
<input type="hidden" name="comment_post_ID" value="<?php echo $id; ?>" /></p>
<?php do_action('comment_form', $post->ID); ?>
</form>
<?php endif; ?>
<?php else : ?>
<p>The comments are closed.</p>
<?php endif; ?>
This code should be pretty self-explanatory. A textarea field for the comment, a submit button, a hidden input field with the comments' future ID and a PHP snippet (
<?php do_action('comment_form', $post->ID); ?>) WordPress requires to make the comment form function.
Voila! That's all folks! You've now got your fully ready comments.php file. View this file to get all the PHP and HTML code that is required. You should end up with this (I simply replaced the default skin's comments.php file with ours and added some minor styling to it.)

5. Some Little Tricks
Of course, you now only have a basic comments.php file. There's tons of things you could do to further improve it. I'll list some little tips and tricks to help you on your way.
Gravatars
As of WordPress 2.5, there is a custom WordPress template tag to embed gravatars. It pulls the gravatar from the email the visitor entered. The code to do this is very simple.
<?php echo get_avatar($author_email, $size, $default_avatar ); ?>
You can replace
$author_email with the nifty get_comment_author_email();function, $size is the height (and width) of the avatar and $default_avatar is a link to the default avatar image (displayed when the commenter has no gravatar).
Insert this code inside the
foreach loop that displays the comments. The output is a image with the classes avatar and avatar-$size (where $size is the size you specified). With some minor CSS editing, you could end up with something like this:
Comment numbers
I purposely left out headers in the comments.php file we created later, since I believed they would make for excess code in a learning process that's difficult enough as it is. Obviously, I'm not forgetting them though.
Usually, people have a heading displaying something similar to "3 comments so far". This is really easy to achieve thanks to the template tags WordPress offers.
<?php comments_number($zero_comments, $one_comment, $more_comments); ?>
It's pretty self-explanatory:
$zero_comments is the text to display when there are no comments, $one_comment when there is one comment and $more_comments when there are multiple comments. A real life example would be like this:<?php comments_number('No comments', 'One comment', '% comments'); ?>
I used
% for multiple comments, since the comments_number function then replaces the % with the number of comments (2, 3, …)
Used in our comments.php file, you'll end up with something like this:

Comment links
To display a link to the comments part (with the number of comments displaying aswell), you simply use the following code.
<?php comments_popup_link($zero_comments, $one_comment, $more_comments, $css_class, $comments_closed); ?>
The first 3 parameters in this function are the same as the above
comments_numberfunction. $css_class is, obviously, the css class that you give to the <a> tag and$comments_closed is the text that should be displayed when the comments are closed. When applying this to a theme, this is a possible way to use it.<?php comments_popup_link('No comments', 'One comment', '% comments', 'comments-link', 'Comments are closed'); ?>
This would then give you a link with the class
comments-linkEditing comments
Sometimes you'll want to immediately edit a comment. Luckily, with the edit_comment_link function, you can easily go to the right page to edit it, instead of having to browse to your admin panel to finally reach that comment. Usage is as such:
<?php edit_comment_link($link_text, $before_link, $after_link); ?>
You have to put this inside the
foreach comment loop. Parameters are quite obvious: $link_text is the anchor text for the edit link, $before_link and$after_link respectively are the text or code to display before or after the link.
This really makes it easy to change a comment; you could simply add a small 'Edit' link to your comment meta information (only viewable by the admin). This is what it could look like:

Alternating colors for comments
It's possible that you'd want to have alternating row colors for your comments, to make a clearer separation. Doing this is relatively easy. First, add the following code to the top of the page:
function alternate_rows($i){
if($i % 2) {
echo ' class="alt"';
} else {
echo '';
}
}
Then add the following inside the
foreach loop (again). You could simply replace<li id="comment-<?php comment_ID(); ?>"> with this:<?php $i++; ?> <li<?php alternate_rows($i); ?> id="comment-<?php comment_ID(); ?>">
This will give every other comment the class
alt, thus making it possible to change their appearance through CSS.
I decided to make a function for it, to have less clutter in your actual theme file. You could add the function definition into your functions.php file if you'd like to, but it makes more sense, to me, to have it at the top of your page.
Alternating rows make it easier to distinguish different comments; once implemented you might have something like this:

Displaying the allowed tags
To display the code that visitors are allowed to use in their comments, simply use this little snippet.
Allowed tags: <?php echo allowed_tags(); ?>
Then you'll simply get a list of the tags that are allowed in your comments, like this:

Comments RSS link
To get a link to the RSS feed for the comments of a certain post, simply insert the code below into your comments.php file on the place where you want it to be.
<?php comments_rss_link($link_text); ?>
Then simply replace
$link_test with the anchor text for the RSS link.
This can come in handy if you want to give your visitors the opportunity to subscribe to the comment feed for a specific article or blog post. You could implement it like this:

6. Conclusion
I hope you've enjoyed this *ahem* little article about skinning your WordPresscomments.php file. You can get the full code here, with the tricks I showed included in it:
- gravatars,
- alternate row colors,
- edit link,
- comments rss link.
Obviously, the comments link isn't included since this has to be used inside of the loop.
Best of luck in your WordPress skinning adventures!
Subscribe to:
Posts
(
Atom
)
Blog Archive
-
2015
(11)
-
October
(11)
- How To Create A WordPress Plugin
- WordPress Custom Post Type Complete - Easy Way
- How to Create CSS Sliding Background Effect
- 10 PHP Tips Every W.Developer Should Know :)
- Flip Wall With jQuery & CSS
- 7 Essential, Most Important JavaScript Functions
- jQuery topLink Plugin
- Layers vs. Artboards: ADOBE ILLUSTRATOR
- Regular Expressions ~ Hands On!
- Clipboard.js makes it easy to copy and cut text fr...
- Unraveling the Secrets of WordPress' Comments.php ...
-
October
(11)
© Xe Blog 2013 . Powered by Bootstrap Blogger templates and RWD Testing Tool


