Author: Peter Knight

A Way To Easily Adjust Screen Brightness On A Multi-Monitor Windows Setup

If you work long hours at a computer, adjusting the brightness of the screen is a must to avoid eye strain and headaches. Especially during the winter when there is less natural light in the work space, continuous exposure to bright monitors can be a real problem. A solution, of course, is to lower the brightness of the monitor.

While most monitors have buttons and controls that let you adjust the screen settings, they tend to be clunky to use. If you have a multi-monitor setup, you don’t want to continually have to go through a slew of settings panels for each monitor. So the obvious solution would be to use some kind of software, ideally something with some keyboard shortcuts.

For Windows, there a dozens of programs that promise to do this and I have tried most of them. Sadly, most of them aren’t really that applicable to multi-monitor arrangements. One approach is to directly tap into the graphics settings, but software that tries to do this can sometimes screw with your monitor settings in ways that hard to revert. Other programs will do the trick but they don’t have easy to use controls (they lack keyboard shortcuts mainly) or they only work on a single monitor setup. I use virtual desktops on top of my dual monitor setup and finding a program that supports these variables has been fruitless search, that is, until today.

So I finally found a solution that fulfills my criteria:
– Easy to use keyboard/mouse shortcuts to adjust screen brightness
– Multi-monitor support
– No messing with graphics settings
– Virtual desktop support
– Compatible with Windows 7
– Low cost

And I’m pleased to say it works great and is free.

So here’s the setup:
You’ll need to install autohotkey and launch a user script called ‘SmartBright‘. To achieve multi-monitor support you just need to tweak a few settings. This script will let you control brightness with a buttery smooth mousewheel control (you hold down the left button mouse while scrolling up or down). All it does is add a transparent overlay over the screen, which is a very effective means to adjust the brightness without screwing with actual monitor settings.

For virtual desktop support you will want to set the SmartBright window to always on top (otherwise the overlay will only work from the desktop you launched the program from). I’m using mDesktop which has a settings panel (from settings select the windows tab) that let’s you pick windows that are always visible on every virtual desktop. I’m sure there is a way to do this purely with autohotkey but I haven’t needed to figure that out, since mDesktop does it perfectly.

Best of all, you won’t have to pay a cent for this setup. How good is that.

How To Specify Top Level Selectors Within Mixins With LESSphp

While creating mixins for cool snippets of reusable css, I had trouble figuring out a way to set styles for top level elements while inside a mixin. To illustrate, let’s look at this example from CSS tricks which uses pseudo elements to create a bar that breaks out a container to touch both sides of the screen.

section {
   width: 50%;
   margin: 0 auto;
}
h2 {
   position: relative;
   background: black;
}
h2:before, h2:after {
   content: '';
   position: absolute;
   background: black;  /* Match the background */
   top: 0;
   bottom: 0;
   width: 9999px;   /* some huge width */
}
h2:before {
   right: 100%;
}
h2:after {
   left: 100%;
}
html, body {
    overflow-x: hidden;
}

It’s a pretty neat effect. The question is, how would you turn this into a mixin, so you can use it on an element of your choice?

Most likely you’ll start out with something like this:

.extended-bar() {
     position: relative;
     background: black;
   &:before, &:after {
     content: '';
     position: absolute;
     background: black;  /* Match the background */
     top: 0;
     bottom: 0;
     width: 9999px;   /* some huge width */
   }
   &:before {
     right: 100%;
   }
   &:after {
     left: 100%;
   }
}

You could then drop this in where you like it. Let’s for example apply it to a h3 heading:

h3 {
   .extended-bar;
}

But we’re missing something. The effect relies on a parent container to have a width. In this example  it’s the section element. We can reasonably assume that this will be specified in the normal course of the stylesheet anyway.

The property applied to the html and body element though is really important (it prevents a horizontal scrollbar from displaying). How do we put that in there? We can’t just drop this into the mixin because it will be prefixed by whatever element the mixin is applied to, in this case the h3 selector. A problem.

So I looked at a different technique as a workaround and arrived at cool feature called selector expressions. This functionality allows you to dynamically create a selector based on a given parameter. With this we can create a mixin that we can call from the top level and let it generate our desired selector dynamically.

.extended-bar( @selector ) {
  html, body {
    overflow-x: hidden;
  }
 }
 (e (@selector ) {
   position: relative;
   background: black; 

 &:before, &:after {
   content: '';
   position: absolute;
   background: black;  /* Match the background */
   top: 0;
   bottom: 0;
   width: 9999px;   /* some huge width */
 }
 &:before {
   right: 100%;
 }
 &:after {
   left: 100%;
 }

}

To create our effect we just need to call it with the desired selector:

.extended-bar( h2 )

This solution will print out the styles like the original css example. This mixin is not the best piece of less to actually use in the wild. In the event that you call the mixin multiple times ugly style duplication issues arise.

I am working on a CSS post processing tool that remedies style duplication issues, if you’re interested, sign up to my newsletter list below and I’ll let you know when I release it.
[yks-mailchimp-list id=”85fd778c18″]

Here’s How To Improve (Social) Psychology’s Academic Reputation

The social sciences such as psychology and sociology have been getting hammered as questions arise over the validity of findings coming out of various studies. The most heinous of causes are incidences of fraud, which is a terrible blow to the field any time it happens, but it goes beyond even that. Research methods are being questioned and classic findings that had been assumed to be reliable are put in doubt when replications of studies fail to reproduce and support said findings

Rumblings in the social sciences are not new, an article about the subject by Jonah Lehrer back in 2010 created a lot of attention. Most recently Daniel Kahneman has attempted to get the attention of his colleagues in the social priming field, sounding the alarm as replication failures for classic priming studies have proven to be disappointing. His call to action involves greater collaboration between laboratories in order to check results in more transparent and trustworthy ways.

A snippet from conversations between Kahneman and Ed Yong, author of an article about this subject on Discover magazine caught my attention. To quote from the article:

Kahneman said that priming effects are very subtle, and could be undermined by small changes to experimental protocols at the hands of unskilled experimenters.

And this immediately reminded me of another controversy in the social sciences when Daryl Bem published a paper detailing a series of classical experiments that had been slightly modified to test for paranormal phenomena (with significantly positive results). Many skeptics in the field responded critically and it prompted to call into question some of the most basic research practices in psychology. You see, Daryl Bem mostly followed text book practices and so when results turn up that many skeptics will find incredulous, there must also be something wrong with the basic research protocols we have been teaching students for decades.

The scientific method was in full motion in response to Bem’s studies, as many labs were motivated to replicate the studies. As some (but not all) research groups were unable to reproduce his results, many thus concluded that Bem’s results could now be discarded. On paper it seemed like a win for the scientific method, especially if you are a critic. You have to understand that for many scientists, this fringe area is seen as detracting from the integrity and credibility of the entire field. It’s a sore in the eyes of hordes of many traditional scientists.

But those that are especially familiar with the parapsychology field know that ESP type studies are typically done with greater scrutiny and attention to detail than the average study. An obvious reason for this is that if you want to arrive at convincing results in such a controversial arena, you have to be extremely diligent about ruling out effects that  would otherwise explain results. Another reason has something in common with the priming field: when experimentally studied ESP effects can be notoriously subtle. The debate continues to whether the small, but positive effects obtained in studies are pointing to something real, or just noise.

In the wake of Bem’s paper, failed replications added weight to the notion that the original study must have been flawed in some way, or at the very least, that the results are meaningless with so much evidence to the contrary. You see, if you can’t replicate a study, it’s usefulness disintegrates. Kahneman implies that some replications regarding classic priming effects were done inaccurately. The same argument regarding replications of Bem’s studies would be regarded by many as wishful thinking on the part of people who want to believe in ESP. Since priming effects rely on less exotic grounds, it’s a different story.

Whichever way you cut it, there’s a serious problem when you have a field that has generated a lot of data and you can’t tell how reliable that data is. My solution to this problem would improve research methods as well as the reliability of important and influential findings. My proposal would be to make replicating classical studies part of the curriculum across universities around the world. By repeating replications of classical studies on a periodic basis and prioritizing the findings from papers that are being cited the most, the entire field will get a boost. Data will become more reliable and students will learn stricter research methods than those of previous generations.

Fear And Surprise: Improving A Widespread WordPress Pattern

A very common pattern used in WordPress core, plugins and themes is way of dealing with supplying arguments to functions and merging them with default values. This pattern is documented in the codex here and utilizes wp_parse_args() and extract().

What does it do? Well a look at the actual wp_parse_args function shows us that it’s a glorified version of array_merge. What array_merge does is combine two arrays into one, overwriting duplicate keys supplied by the first array. That’s exactly what you’d want right? You see if your function requires a value and none is set by the user, a default would be used. Merging the defaults with the user supplied arguments ensures that you always have your required values set.

As a matter of convenience extract() is often called straight after wp_parse_args(). Extract will take all the variables in an array and import them as individually named local variables based on the array key value. An example:

$my_array_of_settings = array( "my_setting" => "wonderful" );
extract($my_array_of_settings);
echo $my_setting; // prints "wonderful"

The problem with extract() is that it is also a potential vector for insecure behaviors since it will try to import every value that is contained in the supplied array. It also can result in unpredictable results. That’s not a good thing when you are not in full control of how arguments are passed to your functions (which is certainly the case for distributed plugins and themes). The alternative, and most advised practice is to avoid the use of extract altogether and just use other ways of accessing the values.

I’m not one to throw the baby out with the bathwater and what I really wanted was a stricter version of wp_parse_args(), one that will limit the variable set based on those defined in the defaults. Instead of importing all the variables in a supplied array, it will only import those that are also specified in the array of defaults. (This behaviour is actually what I was intuitively expecting from wp_parse_args in the first place.)

function custom_parse_args( $args, $defaults ){
	if ( is_object( $args ) ) {
		$r = get_object_vars( $args );
	} elseif ( is_array( $args ) ) {
		$r =& $args;
	} else {
		wp_parse_str( $args, $r );
	}

	if( is_array( $defaults ) ) {
		foreach( $defaults as $default_key => $default_var ) {
			$vars[ $default_key ] = ( $r[ $default_key ] ) ? $r[ $default_key ] : $default_var;
		}
	}
	return $vars;
}

So what does this do differently? Let’s compare this function with wp_parse_args. Let’s have an array with defaults and an array with our arguments, some of which the function is not expecting.

$defaults = array ( "title" => "parsing arguments test");
$args = array(
	"title" => "I was not expecting some kind of Spanish Inquisition",
	"unexpected_response" => "Nobody expects the Spanish Inquisition",
	"chief_weapon" => "fear and surprise",
	"three_weapons" => "fear, surprise and a ruthless efficiency",
	"ah_four_weapons" => "fear, surprise, a ruthless efficiency and an almost fanatical devotion to the pope",
);

$wp_parse_test = wp_parse_args( $args, $defaults );
$custom_parse_test = custom_parse_args( $args, $defaults );

If we now inspect the resulting variables, you’ll find that the wp_parse_args method leaves us with:

// var_dump( $wp_parse_test ); outputs:
array(5) {
  ["title"]=>
  string(52) "I was not expecting some kind of Spanish Inquisition"
  ["unexpected_response"]=>
  string(38) "Nobody expects the Spanish Inquisition"
  ["chief_weapon"]=>
  string(17) "fear and surprise"
  ["three_weapons"]=>
  string(40) "fear, surprise and a ruthless efficiency"
  ["ah_four_weapons"]=>
  string(82) "fear, surprise, a ruthless efficiency and an almost fanatical devotion to the pope"
}

But our custom function filters out the unwanted variables automatically:

// var_dump( $custom_parse_test ); outputs:
array(1) {
  ["title"]=>
  string(52) "I was not expecting some kind of Spanish Inquisition"
}

Because we better control what variables can be used inside the function, using extract() becomes a whole lot safer.

For even more control, you could even run data sanitization and validation checks on each variable before they are allowed to overwrite a default variable.

Organizing Your WordPress Theme’s CSS

Stylesheet files can get ridiculously long. The Twenty Eleven theme has over 2500 lines  of css (unminified). That can be a pain if you’re trying to make significant adjustments to a theme. Quite a few theme frameworks take a more modular approach to css and separate their CSS into different files. That is a big improvement, but it does come at a cost. The more files you import, the more requests you’re making to the server. Secondly, persons who have to work with the CSS now need to figure out what files contain what style specifications. Thirdly, the built-in editor in the administration screen is not that user-friendly when you have to hunt down specific files instead of editing the basic style.css file.

I use the LESS language these days which makes CSS management heaps easier. You can have multiple less files and you can generate a single css file from those files. The question now becomes: what’s a good way to organize the less files?

There are quite a few different ways to organize your CSS logically and the problem here is that you can easily run into overlap situations. Do you put your CSS targeted for small screens in a separate file, or do put them in the file that targets those specific elements? If we have a file dedicated to structure as well as for different content elements, from widgets, to post-formats, how do we make the separations? If you have CSS for your images, do you include them with the file that handles galleries, or do you put them in the file that addresses media elements. These are just a few examples.

So far, I haven’t come up with a system that has perfect clarity. I don’t think it’s possible. The conclusion I’ve come to is that you have to do what’s most in alignment with your workflow. If you have to figure out what file to make an adjustment, there should be no more than 2 obvious candidates to choose from, and they should be obvious. If I want to make an alignment adjustment to a widget area for tablet screens, I don’t want to have to check a widgets file, a structure file, an alignments file and a responsive file.

I’ve been taking advantage of the LESSphp library to get around some of these file organization dilemmas. You can drop in your media queries like you would do a mixin. That way you can keep all the CSS relating to a group of elements organized in one logical area. There is one downside at the moment: the output isn’t perfect yet since it can cause your CSS to contain a lot of redundant data (similar media query statements aren’t grouped automatically into a single media query). I’m working on a css post-processor (the Flawless Styles Compiler plugin) to fix this and make the output cleaner and lighter in general.

Here’s my current file organization setup for those that are interested:

  • variables.less
  • mixins.less
  • reset.less
  • structure.less
  • typography.less
  • general.less
  • navigation.less
  • header-area.less
  • footer-area.less
  • page-templates.less
  • post-formats.less
  • media-elements.less (images, video, audio etc)
  • form-elements.less (input elements, search box, contact forms etc)
  • ui-elements.less (button’s etc)
  • sliders.less
  • gallery.less
  • comments.less
  • states.less
  • print.less
  • widgets.less
  • misc.less

Potential tweaks to this organization? I’m thinking further separation of individual page templates and post formats. Post types can fall into either page template or post format category but it might make sense to have a dedicated file for post types as well.

LESS and convenient file organization make things a lot easier. But I want managing a site’s design to be even easier and this is why I’m building a plugin called ‘Flawless Styles Compiler’ which will take CSS development for WordPress to a whole new level.

Troubleshooting Auto-Formatting Issues In WordPress

Got a bunch of white lines in your post that you are sure you didn’t put there yourself? Is your content getting wrapped in paragraphs in all the wrong places? Are shortcodes messing up your text or coming all out of whack?

Welcome to auto-formatting hell. Let’s troubleshoot this.

WordPress allows your content to have filters applied to it. In fact, it has some default filters that are automatically applied. The most notorious of these is the wpautop filter. It’s a function that semi-intelligently cleans up your content by wrapping text in paragraphs and placing linebreaks and such. The concept is great because it means that the end-user doesn’t have to worry about applying the right HTML.

Content filters are also heavily used by plugins to modify the rendering of content. You can do all kinds of neat stuff with content filters, like appending or prepending snippets of text to your content, modifying words or stripping links.

The downside is that content filters can also get in the way, especially when you have content that the content filters don’t deal with properly. These issues are really common when you are working with shortcodes, or certain HTML code (for example, HTML5 brought several new elements that aren’t taken into account by most filter functions).

When you bump into issues with unwanted paragraph wrapping or unexpected amounts of line breaks, it is most likely the wpautop filter that is doing the evil work. For those that are technical at heart, checking out the source code to see what wpautop is actually doing is really helpful. For most people, they will look on the googles to find a solution to their formatting ailments. You will likely find advice to disable this filter. You can do that by placing this code in your plugin file or functions.php file of your theme:

remove_filter( "the_content", "wpautop" );

This line removes the default filter that is applied to the content. Since the wpautop filter is applied in other types of content as well, you would have to apply ‘remove_filter’ to those other contexts as well. To remove the filter from the excerpt output for example, you can copy the above line and replace ‘the_content’ with ‘the_excerpt’.

If you don’t like to code, there are a bunch of plugins that do this as well. But there a problems with this approach. The first problem is that we typically don’t want to have the filter removed site wide. Many users quickly find out that the rest the content on the site now looks condensed and ugly. Argh!

One solution some people use is to apply their own modified filter that does much of what wpautop accomplishes but also takes care of the undesirable behaviour. If all you want is to prevent linebreaks from being added you could call wpautop with an additional parameter that prevents this.

remove_filter( "the_content", "wpautop" );
add_filter( "the_content", "your_custom_wpautop", 10 );
function your_custom_wpautop ( $content ){
	$content = wpautop( $content, false ); // false parameter disables br insertion
	return $content;
}

If you’re dealing with shortcode issues specifically, you could try reordering the timing of the filter so that your shortcode content is processed before the wpautop filter is applied.

remove_filter( "the_content", "wpautop" );
/* shortcodes are processed with priority 11, the default for wpautop is 10, but we change that here to 30 so that it runs after the shortcode has finished processing */
add_filter( "the_content", "wpautop", 30 );

(You can also process your shortcode before wpautop)

These solutions however will do nothing if another plugin or theme function is running wpautop manually and applying its own filter. Removing the ‘wpautop’ filter won’t work in that case. To get around this you have to figure out what the best thing to do actually is. First of all, if you have tried above solutions and you still have extra paragraphs and/or linebreaks, determine whether it’s a theme or plugin adding their own filter. If you think it might be the theme, switch themes, if you think it might be a plugin, deactivate the most likely culprits one by one and check your results.

If you have determined that it is a plugin or theme function there might be an elegant way to disable their filter. You can run through the code to find out what the filter is called and then use the remove_filter function with that filter name (it’s important you match the same priority level that the filter was added with). You could flat out disable the conflicting plugin in question and use another plugin. You could adjust the theme or plugin code manually, but you’ll lose those fixes when you upgrade.

There are two alternative solutions you could apply if you don’t want to remove any existing functionality sitewide. First, you could disable the offending filter on a post by post basis. Or you could roll your own filter that corrects the formatting (which you could also run on a post by post basis).

Corrective Filter Example:

// filter to remove excess linebreaks from the content
 function kill_linebreaks( $content ){
	$content = str_replace( "<br>", "", $content);
 	$content = str_replace( "<br />", "", $content);
 	return $content;
 }
function no_linebreaks(){
 	add_filter("the_content", "kill_linebreaks", 100000); // removes linebreaks after every other filter has finished processing
 }
add_shortcode( "no_linebreaks", "no_linebreaks"); // insert this shortcode if you want linebreaks removed from the post in question

To use this solution, just add the shortcode [no_linebreaks] in the posts that need it. You can also run a shortcode that removes the offending filter.

Advanced Debugging Tips

Here are some tips for troubleshooting tricky situations. The filters that are run are stored in a global that you can access. The add_filter function can be found in wp-includes/plugin.php.

global $wp_filter;
var_dump( $wp_filter );

If you are trying to determine if it’s wpautop being run or some modified version with a different function name, a quick and dirty way to check is to edit wpautop (you can find it in /wp-includes/formatting.php) and insert a debugging statement or function. You can also use debug_backtrace() to pinpoint what files are calling wpautop. Just remember the remove your code or restore a saved backup of the file when you are done.

Three Great Browsers Not Named Chrome

Google Chrome is the most popular browser on the desktop at the moment, but is it the best? I was a reasonably early adopter of Chrome and fell in love with its speed. Nowadays I don’t use Chrome at all. What happened?

When I first started using Chrome, the things I loved that set it apart from the rest was a feeling of greater responsiveness, a fantastic web developer tool which felt quicker and lighter than firebug on firefox and last but not least: the ability to drag singular windows and create new tabs. Back in the day, there was an experimental feature called side tabs, which let you have your tabs in a vertical listing. This feature was dropped and has still yet to make its way back in (don’t hold your breath). That was and is a major annoyance, but not the biggest.

There are two main reasons I stopped using Chrome. For one, it’s too tightly integrated into Google. I consider that a bad thing. Over the years Google’s products have crept into almost everything I do online. With every new product it takes a bigger piece of the pie of my personal data (and of others). When Chrome started becoming a bit too integrated with Google’s other services I took it as the right timing to start reducing my footprint. Giving Chrome the boot was a good place to start, which brings me to reason number 2:

There are better browsers than Chrome. While Chrome once appeared to lead the pack in terms of speed, which is a huge factor, other vendors have caught up. Even Internet Explorer has decent performance in version 9 and 10. But, the real contenders that are on par with Chrome are Opera, Firefox and… drumroll please…Comodo Dragon. Comodo what you say? Comodo Dragon.

Most people have used Firefox at one point or another. It has a reputation for being a memory hog and updating the browser was a pain compared to Chrome. Right now, version 16 (now in Beta) has finally got a silent updates feature, which means there’s no more nagging for updates and users will be more likely to have the latest and best version running at all times. That’s fantastic. Firefox also closed a longstanding memory leak issue, which makes it a lot lighter to run. They have also introduced a nice set of unique web developer tools, such as the 3d view, a new command line interface and Responsive Design View. Of course, you get vertical tabs enabled with an addon, which is a huge productivity booster if you’re like me and are regularly running several dozens of tabs.

Opera is another interesting player. They have a small market share in terms of percentages, but it still equates to millions of desktop users using on the desktop (their mobile browser has a much greater share of the market though). Opera has always been one of the most innovating browsers that has been copied. Separate Tabs, sidebar tabs, sessions…these features all started life in Opera first. Opera Desktop still is a very good browser, it’s fast, and to my mind it is probably the stablest browser when running a gigantic number of tabs. It has a fast boot up time as well. There are a few issues working against Opera’s favor. Some websites don’t offer proper Opera support and you’ll often find that Firefox and Chrome support newly developing web standards earlier than Opera will. As a web developer, that is a bit of detractor.

Comodo Dragon is hardly known, but it runs the same stuff Chrome does: Chromium, which is the open source machinery driving Chrome. Comodo Dragon is essentially Chrome without Google’s hands in every corner. Comodo the company is a marketleader in internet security and it comes to no surprise that their browser offering offers a multitude of security and privacy perks. If those are things you value (and they should) and you like Chrome, Comodo Dragon is a significant upgrade. An upgrade with no downsides as far as I can see.

Right now Comodo Dragon is my main browser, but with FireFox 16 I find myself falling back in love with Mozilla’s product. What’s your favorite browser, and why?

Beautify Your LESS Stylesheets With Indentation Etc

After a couple of cut and paste jobs I had some LESS files with really ugly looking indentation. After a fruitless search for a tool to auto-format my LESS stylesheets, I decided to build a quick and dirty php script to do the job.

I’m a notepad++ user and while it comes with some nice auto-formatting functions that provide the proper indentation and such, it chokes on LESS stylesheets. I’ve tried other editors such as Crunch and SublimeText but they don’t provide auto-formatting for LESS either, not even through a plugin package.

There are quite a few online code beautifiers that do a fine job with formatting ordinary CSS, but present them with nested styles and parametric functions and they all turn to mush. What else is there to try? Well I decided it wouldn’t be that hard to code a php script and here it is:

[php]<?php

/* Quick and dirty way to clean up LESS stylesheets
* !Warning! don’t run this on a live webserver online, use it on localhost or adapt the code to make it safer
* This code doesn’t reflect perfect coding practices, it’s just a quick and dirty script to quickly format Less files.
* The clean_up_less function will sort out indentation, trim whitespaces and add whitespace
* If you have a missing or extra bracket somewhere, you will have bad results.
* The code only adds tabs for indentation and removes/adds whitespace so your Less won’t get borked
*/

?>
<form method=”post”>
<input type=”submit” value=”format less” />
<textarea name=”nonformatted” id=”nonformatted” style=”display: block; position:relative;float:left;width: 45%;min-height: 400px; height: 100%;”></textarea>
<textarea name=”formatted” id=”formatted” style=”display: block; width: 45%;position:relative;float:left;min-height: 400px; height: 100%;”><?php
if ( $_POST[“nonformatted”] ){
echo clean_up_less( $_POST[“nonformatted”] );
}
?></textarea>
</form>
<?php
function clean_up_less( $css ){
$lines = explode( “n”, $css );
$currentnest = 0;
foreach($lines as $line){
$newline = trim ( $line );
$newline = str_replace( ‘{‘, ‘ {‘, $newline); // make sure left bracket always is preceed by whitespace
$newline = preg_replace(‘/ss+/’, ‘ ‘, $newline); //remove extraneous whitespace
$pos = strpos ( $line, ‘}’ );
if ( $pos > -1 ){
$currentnest = $currentnest – 1;
}
$tabs = ”;
$i = 0;
while( $i < $currentnest ){
$tabs .= “t”;
$i++;
}
if( strpos( $line, ‘{‘ ) ){
$currentnest++;
}
if ($currentnest > 0 ){
$newcss .= $tabs.$newline.”n”;
} else {
$newcss .= $newline.”n”;
}
}
return $newcss;
}
?>[/php]

It’s not a world class script but it got the job done for me. If you’re running a local server setup you can quite easily plug in this script and beautify your LESS in the blink of an eye.

Got a better way to do it? Did you find a tool or plugin that can format LESS stylesheets? Please let it know in the comments because I’d love to know.

*update* http://www.prettyprinter.de/module.php?name=PrettyPrinter does a pretty good job at this too

How To Send Users To Different Welcome Pages Based On User Level In S2Member

A very common requirement for membership sites is the ability to send a user that is logging in to a specific home page. With S2Member there are a couple of ways to accomplish this. I came across some solutions involving javascript, which I think is a bad idea for a number of reasons. I’ll share one method here that is relies on some server side magic instead. To implement this you’ll need to write a little bit of code and insert it in your plugin file, your theme’s functions.php or your s2hacks.php file.

The first clue to redirecting users after logging is the UI S2Member provides under ‘General Options’. There is a section called ‘Login Welcome Page’, which is what we’re after. Here S2Member gives you the option to select an existing page from a dropdown. We don’t want that option because it will be the generic welcome page for all user levels/roles. To send users to different pages based on their membership level, we can make use of the field below the drop down.

 Or, you may configure a Special Redirection URL, if you prefer. You’ll need to type in the full URL, starting with: 

http://

A few Replacement Codes are also supported here.

It’s basically a text field that let’s you specify a url. The cool thing is that we can utilize dynamic variables in the url with replacement codes. The solution I’m using here involves using the %%current_user_role%% replacement code as a GET parameter in the url. What you get is a url that looks like

http://yourfabulousmembershipsite.com/?custom_welcome_page=%%current_user_role%%

The words custom_welcome_page can be replaced with a wording of your choosing (make it unique though) and the %%current_user_role%% will be dynamically replaced with the membership level of the user that is signing in.

For the next step, we are going to write the code that tells WordPress to interpret those parameters.

[php]function your_member_site_vars( $vars ){

$vars[] = “custom_welcome_page”;
return $vars;
}
add_filter( ‘query_vars’, ‘your_member_site_vars’ );[/php]

And now WordPress will interpret the parameter we’re using, we have to tell what to do when it is used next.

[php]

function my_login_redirect() {
if ( get_query_var( ‘custom_welcome_page’ ) ) {
$role = get_query_var( ‘custom_welcome_page’ );
// double check if user has that role
if( current_user_can( $role ) ){
wp_redirect( my_member_welcome_pages( $role ) );
exit;
}
}
}

add_action( ‘template_redirect’, ‘my_login_redirect’ );

[/php]

What the above code does is listen to the parameter custom_welcome_page in the url, if it  is found then it will try to redirect the user. To determine the page, we write another function that takes the membership level of the user and returns the appropriate url.

[php]function my_member_welcome_pages( $role ){

// Set the welcome pages in the following array

$welcome_pages = array(
‘subscriber’ => ‘http://www.yourfabulousmembershipsite.com/subscriber-welcome/’,
‘s2member_level1’ => ‘http://www.yourfabulousmembershipsite.com/level1-welcome/’,
‘s2member_level2’ => ‘http://www.yourfabulousmembershipsite.com/level2-welcome/’
);

if( $welcome_pages[$role] ){
return $welcome_pages[$role];
} else {
return ‘http://www.yourfabulousmembershipsite.com/your_default_welcome_page/’;
}
}
[/php]

These functions are the basic functionality needed to create your own custom welcome page redirects for your members.

Would you like to have a plugin with a simple user interface that does this for you? Drop me a line.

 

Check WordPress User Role By ID

While working on a membership site I wanted to retrieve a user’s role by their user id, but I couldn’t find a quick function to do this. WordPress does provide the WP_User object which gives us quick access to all user information, including user roles. To get the user role by a given ID we can do the following in php:

[php]

function get_user_roles( $id )  {
$user = new WP_User( $user_id ); // this gives us access to all the useful methods and properties for this user

if ( $user ) {
$roles = $user->roles; // returns an array of roles
return $roles;
}  else {
return false;
}

}

[/php]

It’s useful to note that it’s possible for a user to have multiple roles, even though most sites and plugins don’t utilize this possibility. What if you want to check if a user has a certain role? We can write a simple function for that as well. In my case I wanted to check if they have the custom role of teacher (a conditional function).

[php]
function user_has_role( $id, $role = ‘teacher’ ){
$roles = get_user_roles( $id ); // retrieves an array of roles
if ( $roles && in_array ( $role, $roles ) ) { // checks if specified role is listed
return true;
} else {
return false;
}
}
[/php]