Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Mobile WordPress Theming: Day 3

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

This post is part of a series called Mobile WordPress Theming.
Mobile WordPress Theming: Day 2
Mobile WordPress Theming: Day 4

Welcome to the latest installment of Mobile WordPress Theming. Last week, we created the HTML version of the WordPress theme that we will be creating in this tutorial. By the end of this tutorial, we will have a basic WordPress theme that can be applied to any existing WordPress site. Next week, we will package and finish it. Let's get right down to it!

WordPress Theming Mindset

For those readers not familiar with creating WordPress themes, before you start theming you need to understand some fundamental principles of how WordPress works. WordPress is a blogging framework. It is designed to serve content to the user in the most flexible way possible. WordPress stores your content and gives you the tools to serve it how you wish. By "skinning" the data WordPress serves, a process also known as "theming," you can distinguish the look and feel of your blog. Whenever you want to change or enhance a WordPress site, you should either write a plugin or create a theme. Plugins are appropriate if you're changing or adding basic WordPress functionality. However, if you want to modify the style of WordPresss, then either edit or create a theme. Do not just edit core WordPress code directly. This will likely mess up WordPress, especially when you need to update versions later.

Starting Naked

Unless you're being extremely innovative and unique, almost all WordPress themes share the same foundation. They all need a header, a body, a footer, basic styling, etc. That being said, instead of reinventing the wheel, we will use a 'naked theme.' As the name suggests, a naked theme is the most barebones possible. Generally, there is very litle styling besides resets and the occasional useful snippet that you'll likely use in your project. There are plenty of varieties of naked themes on the net. So depending on the project, you might decide on a different one. There is no best naked theme. For this project, I decided to use WordPress-naked. You can grab a copy over at their Google Code page. For a great collection of naked themes, you can also visit speckboy.com's article.

 

wp-naked

Installing WordPress

Now we need a WordPress installation to theme. You can either install one on your server if you have one, or install it locally.

Server

If installing locally, make sure you have a local testing server. For Windows, WAMP or EasyPHP are good choices. If on linux, check out XAMP. If on a Mac, check out MAMP. For this tutorial, we will be running MAMP.

mamp

WordPress

Just go to WordPress.org to download the latest version of WordPress.

download wp

Install WordPress on Server

Copy the WordPress directory into your server directory and install. This isn't a tutorial about installing WordPress. There are plenty of tutorials that do that already like this one.

After you have WordPress installed, copy the naked theme directory into the wp-content/themes directory. Then log into WordPress, go to Appearance > Themes and select the naked them.

"Clothe the Theme"

Now that we have the theme active, we can make changes to it and see them right away. First, change the theme information which is located in the top of style.css. This is where you declare the theme name, author, etc. In this case, I modified it as follows:

/**
  Theme Name: MyTouch
  Theme URI: http://www.connorzwick.com
  Version: .9
  Author: Connor Zwick
  Author URI: http://www.connorzwick.com
  Tags: simple, mobile, jqtouch, ajax
  Licence: GPL
  
  Description: A theme created with felixibility in mind. Allows anyone to choose as mobile theme.

*/

Header

WordPress first looks at the index.php file in the theme directory. This file is how the rest of the theme files are incorporated. If you look at it, you'll see it first grabs all of the content from the header. That is where we need to start. Start by deleting everything from the Doctype down to the </head> tag, and pasting in the following:

<!doctype html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title><?php if(is_home()) bloginfo('name'); else wp_title(''); ?></title>

	
		
        <style type="text/css" media="screen">@import "<?php bloginfo('template_url'); ?>/jqtouch/jqtouch.min.css";</style>
        <style type="text/css" media="screen">@import "<?php bloginfo('template_url'); ?>/themes/jqt/theme.min.css";</style>
        <script src="<?php bloginfo('template_url'); ?>/jqtouch/jquery.1.3.2.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="<?php bloginfo('template_url'); ?>/jqtouch/jqtouch.min.js" type="application/x-javascript" charset="utf-8"></script>
        <script type="text/javascript" charset="utf-8">
            var jQT = new $.jQTouch({
                icon: '<?php bloginfo('template_url'); ?>/logo.png',
                addGlossToIcon: false,
                startupScreen: 'startup.png',
                statusBar: 'black',
                preloadImages: [
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/back_button.png',
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/back_button_clicked.png',
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/button_clicked.png',
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/grayButton.png',
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/whiteButton.png',
                    '<?php bloginfo('template_url'); ?>/themes/jqt/img/loading.gif'
                    ]
            });
            // Some sample Javascript functions:
            $(function(){
                // Show a swipe event on swipe test
                $('#swipeme').swipe(function(evt, data) {                
                    $(this).html('You swiped <strong>' + data.direction + '</strong>!');
                });
                $('a[target="_blank"]').click(function() {
                    if (confirm('This link opens in a new window.')) {
                        return true;
                    } else {
                        $(this).removeClass('active');
                        return false;
                    }
                });
                // Page animation callback events
                $('#pageevents').
                    bind('pageAnimationStart', function(e, info){ 
                        $(this).find('.info').append('Started animating ' + info.direction + '… ');
                    }).
                    bind('pageAnimationEnd', function(e, info){
                        $(this).find('.info').append(' finished animating ' + info.direction + '.<br /><br />');
                    });
                // Page animations end with AJAX callback event, example 1 (load remote HTML only first time)
                $('#callback').bind('pageAnimationEnd', function(e, info){
                    if (!$(this).data('loaded')) {                      // Make sure the data hasn't already been loaded (we'll set 'loaded' to true a couple lines further down)
                        $(this).append($('<div>Loading</div>').         // Append a placeholder in case the remote HTML takes its sweet time making it back
                            load('ajax.html .info', function() {        // Overwrite the "Loading" placeholder text with the remote HTML
                                $(this).parent().data('loaded', true);  // Set the 'loaded' var to true so we know not to re-load the HTML next time the #callback div animation ends
                            }));
                    }
                });
                // Orientation callback event
                $('body').bind('turn', function(e, data){
                    $('#orient').html('Orientation: ' + data.orientation);
                });
            });
        </script>
		<style type="text/css" media="screen">
				@import url( <?php bloginfo('stylesheet_url'); ?> );
			</style>
       
    </head>

This is copied straight from the head of what we did last week, except for two things. You'll notice that any links to JS, CSS, or Image files have been prepended by the template url PHP snippet. This is a WordPress function that will echo out the URL of the template file. This will help fix any problems we would have with linking to static files, because now we have dynamically linked to them. Secondly, you'll notice that we linked to a stylesheet instead of putting all of our styling directly into our header. This is just for neatness' sake. That being said, if you are following along with files of your own, make sure that you copy and paste the styling into style.css

first look

As you can see, just by adding the header links, jQTouch is already working its magic.

Styling

As mentioned earlier, we dumped all of the styling into a stylesheet. We can also remove the presets that the naked theme came with. When all is said and done, the stylesheet should look something like this:

/**
  Theme Name: MyTouch
  Theme URI: http://www.connorzwick.com
  Version: .9
  Author: Connor Zwick
  Author URI: http://www.connorzwick.com
  Tags: simple, mobile, jqtouch, ajax
  Licence: GPL
  
  Description: A theme created with felixibility in mind. Allows anyone to choose as mobile theme.

*/

 body.fullscreen #home .info {
        display: none;
    }
    #about {
        padding: 100px 10px 40px;
        text-shadow: rgba(255, 255, 255, 0.3) 0px -1px 0;
        font-size: 13px;
        text-align: center;
        background: #161618;
    }
    #about p {
        margin-bottom: 8px;
    }
    #about a {
        color: #fff;
        font-weight: bold;
        text-decoration: none;
    }
	/*Begin Customization Here*/
	.blog-title{
		border-bottom: 1px solid #333333;
	}
	span.blog-title{
		color: #fff;
		width: 100%;
		display: block;
		padding-bottom: 10px;
	}
	.post-description, .post-author{
		font-size: 12px;
		margin-left: 75px;
	}
	.post-description{
		min-height: 75px;
	}
	.post-author{
		margin-bottom: 3px;
	}
	.post, .page-author{
		font-size: 13px;
		color: #fff;
		margin-bottom: 5px;
	}
	#blog .rounded li{
		position: relative;
	}
	.month{
		position: absolute;
		width: 70px;
		text-align: center;
		background: #aa3939;
		color: #f5f2f2;
		line-height: 28px;
		padding-bottom: 5px;
		border-top-left-radius: 4px;
		border-top-right-radius: 4px;
	}
	.date{
		position: absolute;
		width: 70px;
		margin-top: 25px;
		font-size: 40px;
		text-align: center;
		background: #f5f2f2;
		border-bottom-left-radius: 4px;
		border-bottom-right-radius: 4px;
	}

This is almost exactly what we created last week. We will add styling here if we need any further customizations.

Index.php

Again, index.php is the file that incorporates the rest of the theme files. So first, we need to call the header.php file. It's pretty simple:

<?php
   get_header();
?>

Now we can start pasting in from last week's snippets again. We will begin with the body:

<body>
	<div id="home" class="current">
        <div class="toolbar">
            <h1>WordPress Site</h1>
            <a class="button slideup" id="infoButton" href="#about">About</a>
        </div>
	<!--	<ul class="rounded">
			<form>
				<li><input type="text" name="search" placeholder="Search" id="some_name" /></li>					
			</form>
		</ul>-->
		
        <ul class="rounded">

We stopped before the blog menu item for a reason. We don't want the blog item to be an option if we do not have any posts, so we'll need to introduce some more WordPress PHP here:


<?php
  if (have_posts()):
?>

    <li class="arrow"><a href="#blog">Blog Articles</a> <small class="counter">12</small></li>

<?php
  else:
?>

    <!-- Alternative HTML here -->
  

<?php
  endif;
?>

Basically, we are checking if we have posts with the have_posts() function, and if we do we are displaying the menu item. If we don't, we do not display anything. We probably could get away with just leaving out the else tag as well, but I want to show that if you wanted to put something there like "No blog posts right now" you could. Then we just end the IF statement

Now we can paste in more of last week's content:



	 <li class="arrow"><a href="#pages">Pages</a> <small class="counter">2</small></li>	
  </ul>
	<h2>External Links</h2>
  <ul class="rounded">
      <li class="forward"><a href="http://feedproxy.com" target="_blank">Subscribe</a></li>
      <li class="forward"><a href="http://twitter.com/connorzwick" target="_blank">Twitter</a></li>
      <li class="forward"><a href="http://WordPress.com" target="_blank">Desktop Page</a></li>
  </ul>

  <ul class="individual">
      <li><a href="mailto:dk@morfunk.com" target="_blank">Email</a></li>
      <li><a href="http://tinyurl.com/supportcz" target="_blank">Donate</a></li>
  </ul>
  <div class="info">
      <p>Add this page to your home screen to view the custom icon, startup screen, and full screen mode.</p>
  </div>
</div>

<!-- End home -->

<div id="about" class="selectable">
      <p><img src="jqtouch.png" /></p>
      <p><strong>Mobile Theme</strong><br />Version 0.1 beta<br />
          <a href="http://www.connorzwick.com">By Connor Zwick</a></p>
      <p><em>Push your content across more boundaries to all internet connected mobile devices<br /> using the world famous WordPress CMS and JQTouch.</em></p>
      <p>
          <a href="http://twitter.com/connorzwick" target="_blank">@connorzwick on Twitter</a>
      </p>
      <p><br /><br /><a href="#" class="grayButton goback">Close</a></p>
</div>

<!-- end about -->



<div id="pages">
  <div class="toolbar">
      <h1>Site Pages</h1>
      <a class="back" href="#">Home</a>
  </div>

  <h2>Pages</h2>
  <ul class="rounded">
      <li class="arrow"><a href="#about">About</a></li>
      <li class="arrow"><a href="#history">History</a></li>
  </ul>
</div><!-- End #pages -->

We stopped again because we are adding something else this week too. Last week, we demonstrated the AJAX capabilities of jQTouch by grabbing the blog.html and loading it. Now that we are integrating with WordPress however, it is much simpler to just use a same page anchor tag. So we integrated the blog portion into the index.php page.

What we are going to do is first, check to see that we have posts again. Then, we will initiate a while loop and will create an unordered list item for every blog item. Inside this loop, you can see we used some more WordPress template functions. They are all pretty self-explanatory. For the time, M is a shortcut for a three letter abbreviation of the month, and j represents the day number without the leading 0 (i.e. 9 not 09).

<div id="blog">
    <div class="toolbar">
        <h1>Blog</h1>
        <a class="back" href="#">Home</a>
    </div>
 	<div class="info">
        This is a short description of blog. Here you describe the purpose.
    </div>
<?php

  if (have_posts()):  ?>




<section id="posts">
	<?php

	    while (have_posts()) : the_post(); ?>

		<ul class="rounded">
	      <li><a class="blog-title" href="<?php the_permalink() ?>"><?php the_title(); ?></a><br />
		<div class="month"><?php the_time('M') ?></div>
		<div class="date"><?php the_time('j') ?></div>
		<p class="post-author">By: <i><?php the_author(); ?></i></p>
		<p class="post-description"><?php the_content(__('<span class="readmore">Read More</span>')); ?></p></li>
		</ul>

	   

	    <?php endwhile; ?>
		
</section>	

<?php else: ?>

  <p><?php _e('Sorry, no posts matched your criteria.'); ?></p>

<?php

  endif;
  ?>


	

</div><!-- End blog-->

Then the rest of the page:


<div id="about">
      <div class="toolbar">
          <h1>Site Pages</h1>
          <a class="back" href="#">Home</a>
      </div>

      <h2>Pages</h2>
      <ul class="rounded">
          <li class="arrow"><a href="#edge">About</a></li>
          <li class="arrow"><a href="#plastic">History</a></li>
      </ul>
</div><!-- End #about -->


<div id="history">
      <div class="toolbar">
          <h1>Site Pages</h1>
          <a class="back" href="#">Home</a>
      </div>

      <ul class="rounded">
	        <li><span class="blog-title">Post Title</span><br />
		
		<p class="page-author">By: <i>Connor Zwick</i></p>
		<p class="post">This is a short description. Here will be a short excerpt of the post, for the viewer to judge if he or she wants to read more.This is a short description. Here will be a short excerpt of the post, for the viewer to judge if he or she wants to read more.This is a short description. Here will be a short excerpt of the post, for the viewer to judge if he or she wants to read more.</p></li>
		</ul>
</div><!-- End #history -->

</body>


  <?php
  get_footer();
?>

At the end we include a footer file. For this theme, the footer file isn't used, so we really don't need it. But I'm leaving the theme open ended so we'll include it anyway. For this theme, we will only want the <html> tag in there.

index

blog

PHP Remove P From Content

As you might have noticed. The excerpt text for the blog articles is larger than it should be. The reason is because we used the_content() function, which wraps the excerpt in an additional p tag. How do we fix this? We need to add one line to the top of the index.php file:

<?php remove_filter ('the_content', 'wpautop'); ?>
blog again

Wrap Up

Now everything looks right. But there's still a lot more things to cover like individual posts, search, pagination, and comments before this is a complete and useful theme! I hope you learned a lot, and make sure you check out the final post in this series next week!


Advertisement