If you are working in a collaborative environment, coding standards are important. When you are reading through code that you haven’t written, it helps if it follows a standard.
As I work with Automattic, the keepers of WordPress.com, I get the opportunity to work on the WordPress Platform. WordPress have their own standards that are sensible without being pedantic and are similar to the PEAR standard. The emphasis of the standard (in my opinion), is to present your code so collaboration is as easy as possible. It would prefer if you wrote code that is easier to read and understand, even if it is a little longer, than some compressed, ubersmart block of code that only you can follow.
Sometimes I look back at old code I did, like when I first wrote a WordPress plugin, and see places where it is not consistent with the WordPress standards… and I’d to get the itch to fix it, line by line, which is time consuming and dull work.
So I looked into ways to automate this in my text editor but alas no feature or option existed. While its not really possible to automate for all the standards, it should be possible to correct the formatting.
What can be automated?, well…
- Braces style. It should use K&R style.
- Indentation. Need to remove spacing and use tabs instead.
- Spacing. Add spacing to make code more readable.
- No shorthand PHP. So no
<?
allowed.
If you are using Coda, there is an excellent plugin called Coda PHP & Web Toolkit written by Mario Fischer. This is easy to install, and all you have to do to tidy your HTML, PHP, Javascript and CSS is right click on your code and select the plugin’s Tidy option.
The best thing about this, it meets WordPress PHP formatting standards with only a couple of exceptions. To fix them, you need to locate the phptidy-coda.php file, usually found here…
/Users/[your user name]/Library/Application Support/Coda/Plug-ins/PhpPlugin.codaplugin/Contents/Resources/phptidy-coda.php
If you can’t locate it, go to root and use the following search command.
sudo find . -name "*.php" -exec grep -H "phptidy" {} \;
The first exception is, that for functions and classes, it pushes the opening curly bracket, {, to the next line.
To fix this, open phptidy-coda.php in an editor and change the line
// from $curly_brace_newline = array(T_CLASS, T_FUNCTION); // to... $curly_brace_newline = false;
The other exception is, it does not add spacing after a start round bracket (, or before an end round bracket, ).
In phptidy-coda.php, find the phptidy function and add a default for this formatting with the other defaults…
// Enable the single cleanup functions $fix_token_case = true; $fix_builtin_functions_case = true; $replace_inline_tabs = true; $replace_phptags = true; $replace_shell_comments = true; $fix_statement_brackets = true; $fix_separation_whitespace = true; $fix_comma_space = true; //add new default in here $fix_round_bracket_space = true; $add_file_docblock = false; $add_function_docblocks = false; $add_doctags = false; $fix_docblock_format = true; $fix_docblock_space = false; $add_blank_lines = false; $indent = true;
Then look for the phptidy function and add a check for this default to format the spacing for round brackets.
// Simple formatting if ( $GLOBALS['fix_token_case'] ) fix_token_case( $tokens ); if ( $GLOBALS['fix_builtin_functions_case'] ) fix_builtin_functions_case( $tokens ); if ( $GLOBALS['replace_inline_tabs'] ) replace_inline_tabs( $tokens ); if ( $GLOBALS['replace_phptags'] ) replace_phptags( $tokens ); if ( $GLOBALS['replace_shell_comments'] ) replace_shell_comments( $tokens ); if ( $GLOBALS['fix_statement_brackets'] ) fix_statement_brackets( $tokens ); if ( $GLOBALS['fix_separation_whitespace'] ) fix_separation_whitespace( $tokens ); if ( $GLOBALS['fix_comma_space'] ) fix_comma_space( $tokens ); // Add in you call to new function here if ( $GLOBALS['fix_round_bracket_space'] ) fix_round_bracket_space( $tokens );
Lastly, add in the function to format the code to add in spacing after the start round bracket and before the end round bracket where appropriate.
/** * Adds one space after a start round bracket and before an end round bracket * * @param array $tokens (reference) */ function fix_round_bracket_space( &$tokens ) { foreach ( $tokens as $key => &$token ) { if ( !is_string( $token ) ) continue; if ( // If the current token is a start round bracket... $token === "(" and // ...and the next token is no whitespace !( isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE ) and // ...and the next token is not an end round bracket !( isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === ')' ) ) { // Insert one space array_splice( $tokens, $key+1, 0, array( array( T_WHITESPACE, " " ) ) ); } else if ( // If the current token is an end round bracket... $token === ")" and // ...and the previous token is no whitespace !( isset( $tokens[$key-1][0] ) and $tokens[$key-1][0] === T_WHITESPACE ) and // ...and the previous token is a start round bracket !( isset( $tokens[$key-1][0] ) and $tokens[$key-1][0] === '(' ) ) { // Insert one space array_splice( $tokens, $key, 0, array( array( T_WHITESPACE, " " ) ) ); } } }
Then save the file. You may need to edit this file using sudo in order to change it.
Restart Coda and tidy your PHP.
UPDATE:: Mario has told me that he will include these changes in a future update But in case it is not in the next update, you should make a backup of the phptidy-coda.php file, as the next plugin update may overwrite it.
UPDATE 2:: Mario has indeed included these changes into the lastest version of the plugin. He has also made the format configurable so if you don’t want your curly brackets on the same line, you can set it so.
Now that is all good and well if you have Coda, but what of the TextWrangler folk. Well the plugin for Coda uses an open sourced library called phptidy, written by Magnus Rosenbaum, which is impressive not least for the brevity of the documentation.
To get it to work with TextWrangler is fairly straightforward. Follow these steps and if I have left any out place highlight them in the comments below.
Note: I had to make some minor changes to the phptidy library to get it to work with TextWrangler. As well as the 2 changes above, I also had to suppress any text echo’d by the library.
- Download my phptidy library.
- Uncompress the zip file and copy the Tidy PHP.sh file to the Filters directory, you can find out how to do that here
- Open terminal and copy the phptidy.php file to your
/usr/bin
folder - Go to the
/usr/bin
folder and change the file permissions of the phptidy.php by typing,sudo chmod 755 phptidy.php
Now you should be ready to try out the filter in TextWrangler.
At a later date, I plan to use John Godley’s CodeSniffer code, to validate the code and get a detailed explanation of where the code does not follow the WordPress standard.
Love this, thanks so much for sharing,, would be great if you could supply your version of the phptidy file for comparison so we can check our changes are consistent…
best
jeff
nvm just saw that you do my bad
That’s just awesome and works like a charm. Thanks for taking the time to wrap this up.
about all my comments, truly genius is what you’ve done,
however I noticed 2 things,
1. Your function snippet above has `&` instead of `&` (html special char for the arguments) caused an error when running it for the first time 😀
2. I’m not 100% sure but I noticed require_once got its braces removed after running it, but searching through WordPress core I noticed they keep the braces in their code…
Thanks again, this will be tremendously helpful 🙂
@jGhazallly.
Fixed issue 1, thanks for highlighting it.
Wrt issue 2, having brackets around the require or includes are not part of the standard. I don’t like them personally but if you prefer to have them in, you’ll need to change the default $fix_statement_brackets from true to false.
Gag. I HATE K&R style braces. HATE HATE HATE. Why are the WP folks still trying to inflict K&R’s most blatant error on others?
Any particular reason why? I’m a big fan of K&R-style personally.
Yes, it slows reading comprehension of code by obfuscating the block structure & making you search for the matching braces.
A couple of comments –
1. You *really* shouldn’t put the phptidy.php file in /usr/bin, and *REALLY* shouldn’t change the permissions to 777. This places a file that is available *FOR WRITING* to every user of your system. The proper permissions are set by
sudo chmod 755 filename
which allows the owner to read, write, and execute, group and ‘other’ can only read and execute the file. Note, the command is ‘chmod’ not ‘chmode’.
2. A more self-contained location (and safe from system updates) would be to place the phptidy.php in the directory immediately above the Unix Filters directory
~/Library/Application Support/TextWrangler/Unix Support/
Change the ‘Tidy PHP.sh’ script to invoke the filter like this
../phptidy.php source "$1"
3. Some folks may use a different PHP (think MacPorts). In order to use the proper PHP change the first line of phptidy.php to this
#!/usr/bin/env php
This filter will also work just fine with BBEdit (TextWrangler’s big brother)
All that being said – a very handy tool. Thanks for sharing!
Thanks for your very helpful comment. I know the
sudo chmod 777
makes the file read-writable to all users, but since I am the only user on my laptop, I didn’t think it mattered… but I should have pointed this out all the same. I will update the post soon to include your changes.A small update here: The current (2.5)-version of my plugin now has a preferences setting for brace-style..
Hope that helps!
Very nice, have you seen any similar plugins for Textmate or Sublime Text 2 ?
Sorry Lukas I haven’t
phptidy.php works great, except it adds an extra level of indentation to array keys:
Instead of:
it outputs:
Actually, it happens only when you pass that array directly to a function:
can’t seem to get this to work. It blanks the entire code nothing (clears it).
Which editor are you using?
This is fantastic! Thank you so much!
I posted the modified phptidy script on github, for easy access:
https://github.com/scribu/wp-phptidy
Thanks for releasing it.
BBEdit 10 doesn’t seem to have the same Unix Script support that TextWrangler has. How would one use this in BBEdit 10? thanks.
This might be kind of a hack, but this is how I modified the script to work with BBEdit 10.1 (that uses STDIN instead of argv). Place wp-phptidy.sh in your “Text Filters” folder and then create the following script:
#!/bin/sh
cat /dev/stdin >orig
./wp-phptidy.php source orig > output
if [[ -s output ]]; then
cat output;
else
cat orig;
fi
rm orig;
rm output;
Its a bit complicated but I ran into a problem where the `wp-phptidy.php source file` command doesn’t actually output anything if there are no changes to be made. If you run it with -v, you will see “Processed without changes.” This is annoying since your text in BBEdit will then be replaced with nothing (the output of the script). To get around this, I simply cat the original text of the file back if the wp-phptidy.php script doesn’t output anything. Hope this saves somebody some frustration!
For BBEdit Users …
Since BBEdit 10.0, the “Unix Filters” directory is gone, so would put Tidy PHP.sh into ~/Library/(or Dropbox)Application Support/BBEdit/Text Filters.
Hi
With Textwrangler 4, text filters have changed so I had to follow the instructions here
https://groups.google.com/d/msg/bbedit/11VZPgz7beI/Cwy2fjBuTlwJ
#!/bin/sh
cat /dev/stdin >orig
../Unix\ Support/phptidy.php source orig > output
if [[ -s output ]]; then
cat output;
else
cat orig;
fi
rm orig;
rm output;
If you want Unix\ Support/phptidy.php you’ll have to create the “Unix\ Support” folder
I think there might be some confusion here. The TextWrangler 4 manual specifically states “TextWrangler 4 no longer uses the Text Factories or Unix Support folders”. It isn’t recommend to use these folders.
The proper method is to put the TextWrangler/BBEdit specific script in the “Text Filters” folder, and put any 3rd party scripts they might call (wp-phptidy.php in this case) into /usr/local/bin. That way you can just say:
wp-phptidy.php source orig > output
Without having to create new folders in strange places and have a specific path in the script. I’d update my original comment to say that, but can’t 🙂
Hi. Can you clarify what the phptidy.php file should be, if the phptidy.php file is place in /usr/local/bin ? (TextWrangler 4.0.1)
My “Tidy PHP.sh” file reads as:
#!/bin/sh
cat /dev/stdin >orig
phptidy.php source orig > output
if [[ -s output ]]; then
cat output;
else
cat orig;
fi
rm orig;
rm output;
but it doesn’t seem to be working. Tt creates a “Unix Support” folder with a an empty “Unix Script Output” file in the TextWrangler Application support folder.
Man this is great, can we turn it into javascript/jQuery?
Good post. I will be experiencing a few of
these issues as well..