A Little Conversation with Christopher Lee

A little conversation with Christopher Lee

A little conversation with Christopher Lee

Some weeks ago, we featured some projects from Christopher Lee on our blog. I got really hooked on his style and ideas, so I decided to invite him to make this interview. Chris was kind enough to accept this new model of interview that the ABDZ team is proposing, we decided to focus more on the person on less on the professional, hope you dig it.

Just in case you haven’t seen Chris work, please take a look on the post we did about him and at his Official Website.

 

 

1) First of all I would like to thank you for doing this interview, it’s an honor for us to present more about you to our readers. I would like to start asking you about how was the beginning of your career?

I started working in the graphic design industry when I was 18. I got my first internship at a small non-profit design company in Sacramento where I did everything from brochure layouts to simple spot illustrations for local businesses. They weren’t great (they were horrible in retrospect), but it’s where I began. The “portfolio” I had at the time consisted of a bunch of random Photoshop projects I had done in my senior year of high school but it was enough for them to see my potential. They definitely took a gamble on me. That internship turned into a job and I ended up staying at that company for five years. The jobs weren’t glamorous, but during my stay, I learned all the skills that I needed to move on to the next chapter of my career.

 

2) Please share a picture of your workplace and tells us more about your daily routine.

I work from home so my schedule is extremely flexible. I don’t really have a daily routine. I usually work most of the day (and into the evening when I’m working on larger projects) and I take breaks to run errands and take care of our dog. As long as I get my work done, then my day-to-day business doesn’t really matter too much.

Chris’s workplace.

3) Beside your daily work, do you have any hobbies? Please share it with us. (Send us a picture of you while doing your hobby).

When I find the time, I like painting miniatures from Warhammer 40k as well as building/painting Gundam models.

 

 

I also enjoy playing air soft.

 

 

4) What you think are the next steps for you as a professional and as a person? And how do you see your creative area on the next 5 years?

I think I’m already on the right path. I always want to try new things and introduce new techniques into my work. I’m never satisfied with one particular style. That said, I’m not sure what my work will look like next year or in ten years. That’s the exciting part for me.

In the next five years I hope to be more involved with the design community and maybe do some teaching via online tutorials or guest speaking at local colleges. I would like to give back in some form.

 

5) Please share five golden lessons you learned to this point.

1) You don’t get better by doing work at “work”. You get better when you experiment and work on your own projects on the side.

2) Always charge what your time is worth.

3) Never work for free or for favors.

4) In the beginning, no job is a small or inconsequential. They are all stepping stones to learn and move forward from.

5) Always love what you do.

 

6)What’s the best thing about working on you business and what is the worst? Why?

The best thing may be the flexibility in my hours and that I am my own boss. My output is directly related to the effort I put in. That itself is a great motivator. Knowing my livelihood is dependent on how hard I work is very humbling and it always keeps the drive to do new things high. I also get to work and collaborate with some extremely talented people and creative minds. There is always something to learn.

The worst thing is probably thinking about the future. With design, you always have to fight to stay relevant. Which is one reason why I never want to stop evolving. There are a thousand people out there competing in the same industry for the same types of jobs and it’s up to me to stick out enough to keep those jobs coming in.

 

7) Do you have any heroes? What make them your heroes? (please send us pics just in case they’re not popular persons)

It might be weird, but I honestly don’t have any personal heroes.

 

8) Tell us in one picture how you’re feeling about your life right now (please send us the picture).

 

9) Now for some quick and short answers:

– Food: Spicy tuna on crispy rice.

– Animal: Boston Terrier. We have one so I’m biased 🙂

– Color: I’m a big fan of coral/salmon type reds right now.

– Tool: In the office, my Wacom Cintiq. In the garage, my Ryobi impact driver haha.

– Person: My girlfriend

– Place: Kyoto, Japan

– Song: “Dakota” by the Stereophonics

– Movie: Aliens

– Book: The Art of Pixar’s Monsters, Inc

– Quote: “Draw to live. Live to Draw” – Invisible Creature

 

10) Thanks again for your time, please leave a final message for the ones who are starting out on this kind of business, tell us something we should expect.

Take the initiative to really find your individual voice in this industry and never lose the love for what you’re doing. Being successful in the design/illustration field is a combination of raw talent and a little luck so expect to pay your dues early on, work hard, and know that you may not land your dream client right away.

Posted in Blog | Comments Off on A Little Conversation with Christopher Lee

Building your first WordPress plugin (part 2)

ThumbnailIn the previous part of our series we created the base for a WordPress plugin recognisible by the core. Today we are going to learn how to actually alter the default functionality of the core.

The concept of hooks, actions, and filters is responsible for that; being the real heart of the whole WordPress plugins system.

Everything starts from the “hooks” provided by the core itself.

What is a “hook”? It is a specially marked place in the code (of any script), where some deliberately registered – “hooked into” – functions can be executed in the order defined upon registration.

WordPress has two types of hooks that differ in their purpose:

  • Action hook: marks the place to perform an action, for example, process input and store results in a database
  • Filter hook: marks the place to apply a modification to a value (normally provided as variable), so that the following code will use the adjusted value

Let’s dive into the details…

Working with actions

The common logic of WordPress actions is very simple:

  1. Mark the place, where the custom code should go, with an “action hook” and its parameters
  2. Create the action function that executes the new code using (if needed) parameters provided by the hook
  3. Register the action (#2) to be performed when the hook (#1) is fired with some priority
  4. When WordPress loads the requested page and finds the hook, it will look for all functions “hooked into” it and execute them one by one in accordance with their priority

To perform task #1 we have the ‘do_action’ function:

do_action($tag, $arg_1, $arg_2, ... , $arg_n);

It accepts following parameters: $tag – the hook “name” that helps to identify the certain hook and distinguish it among others; $arg_1, $arg_2, … , $arg_n – values for actions to accept as parameters. There could be as many arguments as needed – from zero up to any reasonable amount.

WordPress itself has a lot of predefined hooks to use:

do_action( 'init' );

This is very straightforward case with no additional parameters. This hook is fired when the most of WordPress is set up and time has come to register custom objects, like custom post type, for example.

do_action('save_post', $post_id, $post);

In this example the hook is fired when post is saved and gives two additional parameters to operate with – post_id and post object containing all the data from the saved post.

But creating hooks is not only a privilege of the core team; every developer can make a custom hook for the plugin (or theme). Thanks to this we have a lot of power, for example, theme frameworks allow child themes to alter not only styles but even the markup of parents without overwriting whole files.

do_action( 'my_truly_custom_hook' );

When we have found (or created) a proper hook and created a custom function for it we should register the latest for the execution with ‘add_action’.

add_action($tag, $function_to_add, $priority, $accepted_args_number);

As it could be expected the ‘add_action’ method accepts two obligatory parameters: $tag: the name of the appropriate hook and $function_to_add: the name of the function that should be executed. The other two parameters are optional: $priority: an integer to specify the order in which the registered functions are executed (by default, 10), $accepted_args_number: number of arguments that the registered function is going to accept (by default, 1).

Let’s look at an example to illustrate the whole process. Suppose we’d like to add a small notice at the bottom of our site. We could use the ‘wp_footer’ hook for this because it’s a part of obligatory footer code that every theme should include.

function msp_helloworld_footer_notice(){        
      echo "<div id='msp-helloworld-notice'>Hello, I'm your custom notice</div>";
}
add_action('wp_footer', 'msp_helloworld_footer_notice');

In this example we create a prefixed function that simply outputs the notice’s markup (the importance of the prefixes we have discussed in the previous article, so please refer to it for details) and then hooked it into the ‘wp_footer’. Once we include this code in the our plugin file (also discussed in the previous article), we’ll see the result on the site.

cnotice

 

Working with filters

Filters operate with the same logic as actions. The only difference is that they do not just execute some piece of code in a certain place. They execute this code TO MODIFY some value given to them by the hook. This means that every filter hook has the associated value (in most cases carried by a variable).

The function performing filtering should take this value, alter it somehow and then return it for further usage. So that the syntax of functions responsible for hooks and filters is a bit different.

apply_filters($tag, $value_to_filter, $arg_1, $arg_2, ... , $arg_n);

The function ‘apply_filter’ creates a filter hook with $tag name and the obligatory parameter $value_to_filter (it could be empty, but should be present for best practice). Other arguments are optional and work the same way as for actions.

filter_function($value_to_filter, $arg_1, $arg_2, ... , $arg_n){
       //filtering code goes here
       return $value_to_filter; //value has to be returned back
}

This is a skeleton of filter function demonstrating that is should a) accept at least one argument, the value for modification; and b) return the value at the end.

add_filter($tag, $function_to_add, $priority, $accepted_args);

The function ‘add_filter’ registers a function with a name given as the $function_to_add argument for the $tag filter hook. The optional arguments — $priority and $accepted_args — work in the same way as for action hooks.

Let us demonstrate the whole process in action: a common plugin task is to add some content at end of a post. If we look closer at the ‘the_content’ template tag (queryposts.com/function/the_content), which is normally used to output a post’s content in a theme, we will find that it contains following filter hook:

$content = apply_filters('the_content', $content);

Using this hook we can easily add something to the end of the post in the following way:

function msp_helloworld_post_footer($content) {         
        $content .= "<div class='msp-helloworld-post-footer'><p>Hello, I'm your custom post footer</p></div>";
        return $content;
}
add_filter('the_content', 'msp_helloworld_post_footer', 100);

Please notice that we use quite large number for priority here to ensure that all default filters have been applied before our ‘msp_helloworld_post_footer’. After including the code in the plugin’s file we should see the result on the site:

pfooter

 

How to find hooks

It should be obvious by now that for implementing action and filter functionality we need to know what hooks are available.

The WordPress Codex provides an Action Reference with most of action hooks fired on typical page load and a Filter Reference with a list of commonly used filters. These references are useful to understand the order of actions and the logic of filters so that you’ll be able to choose where and when functionality can and should be injected.

After that you are ready for the trip into the source code. You can just perform a search through the WordPress files for the ‘do_action’ and ‘apply_filters’ keywords to find the hook you need.

Understanding WordPress query logic could also help you work out where some hooks can be looked for.

Finally, you can refer to the WordPress Hooks Database that contains full information about the hooks in the core files.

 

Advanced operations with hooks

As well as being added to your plugin, actions and filters can also be removed with a similar syntax.

Actions can be removed in the following manner:

remove_action($tag, $function_to_remove, $priority, $accepted_args);
remove_all_actions($tag, $priority);

As you have probably guessed ‘remove_action’ removes a particular action registered for a particular hook (you have to state correctly the priority and number of arguments as they were used on registration), and ‘remove_all_actions’ helps to remove all actions registered with a certain hook with a given priority (if the priority argument is omitted the function will remove all actions).

You have probably heard about a popular security recommendation to hide the WordPress version from the head section of the site. This is a job for ‘remove_action’.

First of all let’s find the code that hooks the ‘wp_generator’ function to print the version information by browsing /wp-includes/default-filters.php. The code doing this looks as follows:

add_action('wp_head', 'wp_generator');

To eliminate the effect of this code we should somewhere in our plugin, include the opposite function:

remove_action('wp_head', 'wp_generator');

Filters can be removed in a similar way:

remove_filter($tag, $function_to_remove, $priority, $accepted_args);
remove_all_filters($tag, $priority);

The Plugin API also provides developers with a way to detect whether the particular hook has registered functions to execute:

has_action($tag, $function_to_check);
has_filter($tag, $function_to_check);

Both functions check whether a particular action or filter is registered for a hook and returns: true on success, false on failure. Inside the hooked function we have an ability to check what hook has triggered its execution in the following way:

if('hook_to_check_name' === current_filter()){
    //do stuff related to 'hook_to_check_name' hook
}

Despite the name, the ‘current_filter’ works not only with filters but with actions as well. For the full set of Plugin API functions refer to the Codex.

 

Real-world case

Let us dig up the plugin skeleton that we prepared in the previous part of the series, and breath some life into it.

We are going to fill-in the ‘core.php’ file (the central part of our plugin intended to carry the most of functionality) with the code that solves a real-world task with the help of actions and filters.

What we are going to do? Suppose your WordPress site accepts guest posts from different authors, but does not give them permission to create their own accounts for posting. It means that the user, who has published the article, and the real author of it (the guest) are different people. You’ll need to ensure that the actual author receives credit. This can be done with custom taxonomy.

Let us create a custom taxonomy to handle the guest author’s name (as a term) and short author’s bio (as a description). We would be able to assign author’s names as any other taxonomy’s terms (as tags) to posts. After that it becomes possible to output an author’s box right after the post’s text. Here is the code:

/** Hook plugin's action and filters **/
function msp_helloworld_init(){
    
    add_action('init', 'msp_helloworld_taxonomies');
    add_filter('the_content', 'msp_helloworld_author_block_filter');
    add_filter('post_class', 'msp_helloworld_post_class');
    
}
add_action('plugins_loaded', 'msp_helloworld_init');

/** Register custom taxonomy **/
function msp_helloworld_taxonomies(){
    
    $args = array(
        'labels' => array(
            'name'          => 'Guest authors',
            'singular_name' => 'Guest author'
        ),        
        'show_in_nav_menus' => false        
    );
    
    register_taxonomy('gauthor', array('post'), $args);
    
}

/** Create author's box markup **/
function msp_helloworld_author_block(){
    global $post;
    
    $author_terms = wp_get_object_terms($post->ID, 'gauthor');
    if(empty($author_terms))
        return;
    
    $name = stripslashes($author_terms[0]->name);
    $url = esc_url(get_term_link($author_terms[0]));
    $desc = wp_filter_post_kses($author_terms[0]->description);
    
    $out = "<div class='gauthor-info'>";
    $out .= "<h5>This is a guest post by <a href='{$url}'>{$name}</a></h5>";
    $out .= "<div class='gauthor-desc'>{$desc}</div></div>";

    return $out;
}

/** Add author's box to the end of the post **/
function msp_helloworld_author_block_filter($content){
    
    if(is_single())
        $content .= msp_helloworld_author_block();
        
    return $content;
}

/** Add custom CSS class to the post's container **/
function msp_helloworld_post_class($post_class){
    global $post;
    
    $author_terms = wp_get_object_terms($post->ID, 'gauthor');
    if(!empty($author_terms)){
        $post_class[] = 'gauthor';
    }
    
    return $post_class;
}

As you can see, we have created an action to register a custom taxonomy and applied it to the ‘init’ hook — this is a recommended practice. After that we have created the template tag responsible for the author box’s markup using native WordPress functions like ‘wp_get_object_terms’. After that we attached this box to the end of post content using the ‘the_content’ filter hook. And finally we have added the custom CSS class for the guest posts’ container for styling flexibility in the theme. After applying some styles we can see the result:

gauthor

 

Conclusion

Actions and filters are the most important part of any WordPress development. Now that you understand their logic and behaviour, you’re prepared for your own experiments.

 

Click here to download our extended “Hello World” plugin example to use as skeleton for your own development.

 

What uses have you found for WordPress actions and filters? What would you like to see covered in the next part of this series? Let us know in the comments.

Featured image, Module image via Shutterstock

The Photography eBook Bundle – only $29!

Source


Posted in Blog | Comments Off on Building your first WordPress plugin (part 2)