Developing a WordPress Theme from Scratch Part 2: Pagination, Comments, Single Post, Functions, & Custom Posts

In part one of the tutorial series Developing a WordPress Theme From Scratch, we learned what WordPress is, what it can do, and how to do the following:

  • Set up a local Apache, MySQL, PHP (*AMP) environment
  • Install WordPress on your local server
  • Take an existing static HTML & CSS site and make it into a custom WordPress theme
  • Divide your theme into sections (index.php, header.php, footer.php, sidebar.php, and content.php)
  • Use The Loop to make posts and pages
  • Migrate local WordPress site to a live server

We created this theme using Bootstrap, and more specifically the official generic blog template. While the theme could use custom CSS or any framework, I went with Bootstrap so that we can focus on creating the theme’s function without worrying about the style.

Here is what the theme looked like at the end of the last article:

Very simple, but it effectively demonstrates how to use the WordPress Loop to display content dynamically.

In this article, we’re going to go through more essential WordPress theming techniques.

Prerequisites

  • Basic knowledge of HTML and CSS
  • Ability set up WordPress and make a basic theme (covered in part one)

Goals

  • Create individual post pages – single.php
  • Add pagination
  • Include comments
  • Learn how to use functions.php
  • Properly enqueue stylesheets and scripts
  • Create global custom fields
  • Create custom post types

First, I’m going to start off by adding individual blog posts and pagination.

Individual Post Pages

In the last article, we made header, footer, sidebar, content, and page files. Now we’re going to make single.php, which is an individual post page. It’s going to be an exact duplicate ofpage.php, except I’m going to change 'content' to 'content-single'.

<?php get_header(); ?>

	<div class="row">
		<div class="col-sm-12">

			<?php 
				if ( have_posts() ) : while ( have_posts() ) : the_post();
					get_template_part( 'content-single', get_post_format() );
				endwhile; endif; 
			?>

		</div> <!-- /.col -->
	</div> <!-- /.row -->

<?php get_footer(); ?>

Now you’ll create content-single.php, which is a duplicate of content.php.

<div class="blog-post">
	<h2 class="blog-post-title"><?php the_title(); ?></h2>
	<p class="blog-post-meta"><?php the_date(); ?> by <a href="#"><?php the_author(); ?></a></p>
 <?php the_content(); ?>
</div><!-- /.blog-post -->

So now you can see that index.php is pulling in content.php, and single.php is pulling incontent-single.php.

Going back to the original content.php, we have the title of each article.

<h2 class="blog-post-title"><?php the_title(); ?</h2>

Using the_permalink(), we’re going to link to the single page.

<h2 class="blog-post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>

Now you have a blog posts on the main page that are linking individual blog post page.

Finally, we’ll want to change the_content() to the_excerpt() on content.php. The excerpt will only show the first 55 words of your post, instead of the entire contents.

<?php the_excerpt(); ?>

Pagination

In the original Bootstrap blog example, there is pagination to be able to click through multiple pages if you have many blog posts.

Currently, your index.php file looks like this.

<?php get_header(); ?>

	<div class="row">
		<div class="col-sm-8 blog-main">

			<?php 
			if ( have_posts() ) : while ( have_posts() ) : the_post();
				get_template_part( 'content', get_post_format() );
			endwhile; endif; ?>

		</div>	<!-- /.blog-main -->
		<?php get_sidebar(); ?>
	</div> 	<!-- /.row -->

<?php get_footer(); ?>

If you’ll notice, the loop has if and while, then later endif and endwhile. To insert pagination, we’ll have to put it after the endwhile but before the endif. This means that it won’t repeat for each loop, but will only show up once based on posts.

Pagination links are called like this:

<?php next_posts_link( 'Older posts' ); ?>
<?php previous_posts_link( 'Newer posts' ); ?>

In index.php, between endwhile; and endif;, I’m going to place this code.

<nav>
	<ul class="pager">
		<li><?php next_posts_link( 'Previous' ); ?></li>
		<li><?php previous_posts_link( 'Next' ); ?></li>
	</ul>
</nav>

By default, 10 posts will show up on a page before it will link to another page. For testing purposes, I’m going to go to Settings > Reading and change Blog pages show at most to 1.

Now we have functioning pagination.

Comments

One of the biggest advantages WordPress and server based content management systems have over static site generators is the ability to include comments without using a third party. (However, static site generators have many more advantages – I have an article on setting up Jekyll if you’re interested in learning how to use them.)

Comments seem complicated to set up, but it doesn’t have to be hard at all. First, we’re going to go back to single.php and enable the comments.

Right now, the code looks like this.

if ( have_posts() ) : while ( have_posts() ) : the_post();
	get_template_part( 'content-single', get_post_format() );
endwhile; endif; 

We’re going to change it to look like this.

if ( have_posts() ) : while ( have_posts() ) : the_post();
	get_template_part( 'content-single', get_post_format() );

	if ( comments_open() || get_comments_number() ) :
	  comments_template();
	endif;

endwhile; endif; 

This is just telling the single post to display the comments template. Now we’ll createcomments.php.

<?php if ( post_password_required() ) {
	return;
} ?>
	<div id="comments" class="comments-area">
		<?php if ( have_comments() ) : ?>
			<h3 class="comments-title">
				<?php
				printf( _nx( 'One comment on “%2$s”', '%1$s comments on “%2$s”', get_comments_number(), 'comments title'),
					number_format_i18n( get_comments_number() ), get_the_title() );
				?>
			</h3>
			<ul class="comment-list">
				<?php 
				wp_list_comments( array(
					'short_ping'  => true,
					'avatar_size' => 50,
				) );
				?>
			</ul>
		<?php endif; ?>
		<?php if ( ! comments_open() && get_comments_number() && post_type_supports( get_post_type(), 'comments' ) ) : ?>
			<p class="no-comments">
				<?php _e( 'Comments are closed.' ); ?>
			</p>
		<?php endif; ?>
		<?php comment_form(); ?>
	</div>

Comments are not the simplest part of WordPress theming, but I’ve managed to reduce it down to a small enough code block.

First, we’re setting functionality to prevent users from posting comments if you’ve set your settings to password protected comments (post_password_required()). Then we’re creating a comments div, and if there are comments (have_comments()), it will display how many comments there are on the post (get_comments_number()), followed by the list of comments (wp_list_comments()). If the comments are closed (! comments_open()), it will let you know; at the end will be the form to submit a comment (comment_form()).

Without adding any styles, here is how the functioning single blog post looks.

Obviously the styles aren’t quite there yet, but I don’t want to focus on that in this article. Remove the list-style on the uls, add some padding and margins and possibly some borders and background colors, and you’ll have a much prettier comment setup.

Of course, you might want to show how many comments there are or link to the comments from the main page. You can do that with this code inserted into content.php.

<a href="<?php comments_link(); ?>">
	<?php
	printf( _nx( 'One Comment', '%1$s Comments', get_comments_number(), 'comments title', 'textdomain' ), number_format_i18n( 						get_comments_number() ) ); ?>
</a>

Now that we have pagination, blog posts, and comments set up, we can move on to functions.

Using and Understanding the WordPress Functions File

Located in your theme directory, you can create a file called functions.php. You can usefunctions.php to add functionality and change defaults throughout WordPress. Plugins and custom functions are basically the same – any code you create can be made into a plugin, and vice versa. The only difference is that anything you place in your theme’s functions is only applied while that theme is actively selected.

I have a README on GitHub of useful WordPress functions, which might come in handy the more you use them.

functions.php seems complicated, but it’s mostly made up of a bunch of code blocks that, simplified, look like this:

function custom_function() {
	//code
}
add_action( 'action', 'custom_function');

So, we’re creating our custom function, and adding it in based on action references. Within this file, you can pretty much change or override anything in WordPress.

Let’s go ahead and make functions.php and place it in our theme directory.

Since it’s a PHP file, it needs to be begin with the opening PHP tag. It doesn’t need a closing tag; pure PHP files don’t need closing tags.

<?php

Eventually, you can insert these types of functions into your own custom plugin that can be used across many themes, but for now we’ll learn how to do it in the theme specific file.

Enqueue Scripts and Stylesheets

By the end of the last article, I was incorrectly linking to my CSS and JavaScript in the header and footer, respectively. This should be done through the functions file.

I’m going to make css, js and images directories in the root of my theme. So here’s what I have:

  • css
    • bootstrap.min.css
    • blog.css
  • js
    • bootstrap.min.js

Now here’s the first code block we’re going to put in functions.php:

// Add scripts and stylesheets
function startwordpress_scripts() {
	wp_enqueue_style( 'bootstrap', get_template_directory_uri() . '/css/bootstrap.min.css', array(), '3.3.6' );
	wp_enqueue_style( 'blog', get_template_directory_uri() . '/css/blog.css' );
	wp_enqueue_script( 'bootstrap', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), '3.3.6', true );
}

add_action( 'wp_enqueue_scripts', 'startwordpress_scripts' );

In order for these to properly be inserted into your theme, <?php wp_head(); ?> needs to be placed before the closing </head> tag, and before the closing </body> tag.

By common WordPress convention, I’m naming my script after my theme (startwordpress_scripts()). wp_enqueue_style is for inserting CSS, andwp_enqueue_script for JS. After that, the array contains the ID, location of the file, an additional array with required depenedencies (such as jQuery), and the version number.

Now we have jQuery, Bootstrap CSS, Bootstrap JS, and custom CSS being properly loaded into the website.

Enqueue Google Fonts

The function to include the Google Fonts stylesheets is slightly different, based on the dynamic nature of the URL. Here is an example using Open Sans.

// Add Google Fonts
function startwordpress_google_fonts() {
				wp_register_style('OpenSans', 'http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800');
				wp_enqueue_style( 'OpenSans');
		}

add_action('wp_print_styles', 'startwordpress_google_fonts');

Now I have Open Sans by Google Fonts linked in my page.

Fix the WordPress Title

If you’ll notice, we’re currently pulling in the title for the website with this code.

<title><?php echo get_bloginfo( 'name' ); ?></title>

This is not very intuitive – it means that whatever you have set as your website’s title will be the title tag for every page. However, we’re going to want each individual page to show the title of the article first, and also include a reference to the main site title.

We can change the title tag to this.

<title><?php wp_title( '|', true, 'right' ); ?></title>

And in functions.php, add this code block.

// WordPress Title
function startwordpress_wp_title( $title, $sep ) {
	global $paged, $page;
	if ( is_feed() ) {
		return $title;
	} 
	// Add the site name.
	$title .= get_bloginfo( 'name' );
	// Add the site description for the home/front page.
	$site_description = get_bloginfo( 'description', 'display' );
	if ( $site_description && ( is_home() || is_front_page() ) ) {
		$title = "$title $sep $site_description";
	}
	return $title;
} 
add_filter( 'wp_title', 'startwordpress_wp_title', 10, 2 );

The original source of this code can be found on Tom McFarlin’s blog.

Create Global Custom Fields

Sometimes, you might have custom settings that you want to be able to set globally. An easy example on this page is the social media links on the sidebar.

Right now these links aren’t leading anywhere, but we want to be able to edit it through the admin panel. The source of this code is modified from this Settings API tutorial.

First, we’re going to add a section on the left hand menu called Custom Settings.

// Custom settings
function custom_settings_add_menu() {
  add_menu_page( 'Custom Settings', 'Custom Settings', 'manage_options', 'custom-settings', 'custom_settings_page', null, 99);
}
add_action( 'admin_menu', 'custom_settings_add_menu' );

Then we’re going to create a basic page.

// Create Custom Global Settings
function custom_settings_page() { ?>
  <div class="wrap">
    <h1>Custom Settings</h1>
    <form method="post" action="options.php">
       <?php
           settings_fields('section');
           do_settings_sections('theme-options');      
           submit_button(); 
       ?>          
    </form>
  </div>
<?php }

The code contains a form posting to options.php, a section and theme-options, and a submit button.

Now we’re going to create an input field for Twitter.

// Twitter
function setting_twitter() { ?>
  <input type="text" name="twitter" id="twitter" value="<?php echo get_option('twitter'); ?>" />
<?php }

Finally, we’re going to set up the page to show, accept and save the option fields.

function custom_settings_page_setup() {
  add_settings_section('section', 'All Settings', null, 'theme-options');
  add_settings_field('twitter', 'Twitter URL', 'setting_twitter', 'theme-options', 'section');

  register_setting('section', 'twitter');
}
add_action( 'admin_init', 'custom_settings_page_setup' );

Now I’ve saved my Twitter URL in the field.

For good measure, I’m going to add another example, this time for GitHub.

function setting_github() { ?>
  <input type="text" name="github" id="github" value="<?php echo get_option('github'); ?>" />
<?php }

Now you’ll just duplicate the fields in custom_settings_page_setup.

  add_settings_field('twitter', 'Twitter URL', 'setting_twitter', 'theme-options', 'section');
  add_settings_field('github', 'GitHub URL', 'setting_github', 'theme-options', 'section');
  
	register_setting('section', 'twitter');
  register_setting('section', 'github');

Now back in sidebar.php, I’m going to change the links from this:

<li><a href="#">GitHub</a></li>
<li><a href="#">Twitter</a></li>

To this:

<li><a href="<?php echo get_option('github'); ?>">GitHub</a></li>
<li><a href="<?php echo get_option('twitter'); ?>">Twitter</a></li>

And now the URLs are being dynamically generated from the custom settings panel!

Featured Image

You might want to have a featured image for each blog post. This functionality is not built into the WordPress core, but is extremely easy to implement. Place this code in yourfunctions.php.

// Support Featured Images
add_theme_support( 'post-thumbnails' );

Now you’ll see an area where you can upload an image on each blog post.

I’m just going to upload something I drew in there for an example. Now, display the image in content-single.php.

<?php if ( has_post_thumbnail() ) {
  the_post_thumbnail();
} ?>

Now you have an image on your individual post pages! If you wanted the thumbnail to show up on on the main blog page as well, you could do something like this on content.phpto split the page if a thumbnail is present:

<?php if ( has_post_thumbnail() ) {?>
	<div class="row">
		<div class="col-md-4">
			<?php	the_post_thumbnail('thumbnail'); ?>
		</div>
		<div class="col-md-6">
			<?php the_excerpt(); ?>
		</div>
	</div>
	<?php } else { ?>
	<?php the_excerpt(); ?>
	<?php } ?>

Custom Post Types

One of the most versatile way to extend your WordPress site as a full blown content management system is with custom post types. A custom post type is the same as Posts, except you can add as many of them as you want, and with as much custom functionality as you want.

If you’re interested in using plugins, you can download the Advanced Custom Fields plugin, which will add a great deal of customizability to your theme with little effort.

For now, I’m going to show you how to set up a simple custom post type, and call the post in it’s own loop. There is much more that can be done with custom post types, but that’s a bit more complicated and deserves an article all of its own.

Custom Post Types on the WordPress codex will also give you more insight on some of the possibilities available.

In functions.php, I’m going to create the custom post type called My Custom Post.

// Custom Post Type
function create_my_custom_post() {
	register_post_type('my-custom-post',
			array(
			'labels' => array(
					'name' => __('My Custom Post'),
					'singular_name' => __('My Custom Post'),
			),
			'public' => true,
			'has_archive' => true,
			'supports' => array(
					'title',
					'editor',
					'thumbnail',
				  'custom-fields'
			)
	));
}
add_action('init', 'create_my_custom_post');

In the create_my_custom_post(), I’ve created a post called My Custom Post with a slug ofmy-custom-post. If my original URL was example.com, the custom post type would appear at example.com/my-custom-post.

In supports, you can see what I’m adding – title, editor, thumbnail, and custom fields. These translate to the fields on the back end that will be available.

  • title is the title field that I call with <?php the_title(); ?>.
  • editor is the content editing area that I call with <?php the_content(); ?>.
  • thumbnail is the featured image that I call with <?php the_post_thumbnail(); ?>.
  • custom-fields are custom fields that I can add in and call later.

I’ve decided I’m going to make a new page for the custom post to loop in. I created a page called Custom, which will appear at example.com/custom. Right now, my page is pulling from page.php, like all the other pages.

I’m going to create page-custom.php, and copy the code over from page.php. According to the WordPress template hierarchy, a page-name.php will override page.php.

The original loop we used looked like this:

if ( have_posts() ) : while ( have_posts() ) : the_post();
	// Contents of the Loop
endwhile; endif; 

A custom post type loop will look like this:

$custom_query = new WP_Query( $args );
while ($custom_query->have_posts()) : $custom_query->the_post();
  // Contents of the custom Loop
endwhile;

Note that this only a while, and does not have an if or endif.

I’ll have to define the $args or arguments, before the loop.

$args =  array( 
	'post_type' => 'my-custom-post',
	'orderby' => 'menu_order',
	'order' => 'ASC'
);

Here I’m defining the post type as my-custom-post, and ordering the posts in ascending order.

So here’s the entire code for page-custom.php.

<?php get_header(); ?>

	<div class="row">
		<div class="col-sm-12">

			<?php 
				$args =  array( 
					'post_type' => 'my-custom-post',
					'orderby' => 'menu_order',
					'order' => 'ASC'
				);
				 $custom_query = new WP_Query( $args );
            while ($custom_query->have_posts()) : $custom_query->the_post(); ?>

				<div class="blog-post">
					<h2 class="blog-post-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
					<?php the_excerpt(); ?>
				</div>

				<?php endwhile; ?>
		</div> <!-- /.col -->
	</div> <!-- /.row -->

	<?php get_footer(); ?>

Now example.com/custom will only pull in posts from the custom post type we created. Right now, the custom post type is set up to only do things that the normal posts can do, but the more you fall down the rabbit hole, the more possibilities you discover.

Conclusion

We covered a lot of ground in this article; you should now be able to…

  • Create individual pages for blog posts
  • Add pagination to a blog
  • Add comments to a blog
  • Add WordPress functions
  • Enqueue scripts and stylesheets properly
  • Have a proper page title
  • Create custom global settings
  • Create a custom post type

All the source code is on GitHub as always. You can download the code and upload it into your themes folder and see it in action. I might set up a demo if there’s any interest in that.

There is much more that custom post types can do – and much more that WordPress can do, as well. I haven’t touched on the theme customizer, which is the most current way of creating themes.

Fonte: Developing a WordPress Theme from Scratch Part 2: Pagination, Comments, Single Post, Functions, & Custom Posts | Tania Rascia

Make Any WordPress Theme Responsive (Mobile-Friendly)

Here is the scenario: You’ve searched high and low and found the perfect WordPress theme for yourself or your client. But, there’s one big problem: it’s not mobile-friendly. With mobile web traffic soon expected to exceed desktop web traffic, being mobile-friendly is critical.

I often have to go through the exercise of converting a non mobile-friendly WordPress theme to be mobile-friendly, or “responsive” (the term used to describe a site that uses the size of the browser to reconfigure itself for optimum viewing). In this article, I’ll guide you through the process I use.

Note, I am assuming you are familiar with HTML and CSS here. I’ll give you some broad strokes, along with some detailed code, but of course much of the work will depend on the inner workings of your theme. Hopefully, you can use some of the principles I talk about for your project.

Let’s look at one of the most common layouts for a WordPress theme, namely, one with a header, menu bar, main content section, sidebar, and footer. Here is a graphic depiction of this structure:

Making the Header Fluid

The first thing to do is make all of the elements “fluid” or variable-width.  Ironically, in the early days of web development, everyone made containers fluid.  When we discovered that this made things hard to control, we went to fixed size containers.  And now we’re back to making everything fluid again!

Anyway, you need to find the main containers (divs) for the major sections of your site, as indicated in my diagram above.  An easy way to do this is to use the Firebug Firefox plugin or Google Chrome.  If you install it, you can hit F12 or CTRL-SHIFT-I (or ALT-CMD-I on a Mac) and it will tell you the name of all of the containers surrounding any element you click on.  It’s super-useful for this type of work.

For example, your header might be contained in a div like this:

Next, look at the CSS for that div.  It might look something like this:

To make this element fluid, remove the fixed with and change it to look like this:

Your header should now be fluid.  The magic is accomplished by defining the width using a percentage instead of fixed pixels.  The “max-width” property prevents it from getting too big.  If you want, you can add a “min-width” if you want to prevent the window from getting too small.  I generally use a value of 300px for my min width.

Re-size the browser to see if it worked!  If not, there might be elements inside the header that are keeping it from shrinking.  Search for any fixed-width CSS definitions.  You’ll have to change them to be variable using percentage-based widths.  I’ll describe how to do that by showing you how to resize the main content block and sidebar.  Other problems in the header, like the text being too big, will be fixed later with media queries.

As elements wrap, the containers will need to get taller.  Remove any heights that are set in pixels so they can expand as needed.

If your header still isn’t fluid, it might be inside a container that has fixed width.  Use the tools to search for those, and make them fluid.

Content Block and Sidebar

Let’s assume your main content and sidebar containers look like this:

Let’s say the corresponding CSS looks like this:

Now, the numbers might not exactly add up to 900 due to padding and so forth, but for simplicity, let’s say they do.

As we re-size the browser, we want to maintain the ratio of the container and sidebar widths.  Here’s how we accomplish that:

Basically, you need to work out the ratio of the contained elements to the width of the containing element, and set your width equal to that percentage.

If you want to add padding or margin, express those as percentages as well, and adjust the other widths accordingly so the total is always 100% or less. This is really key. The widths of all of the elements that take up horizontal space need to be expressed in percentages. Note that you can use max-width to prevent things from getting too big.

If the elements are not re-sizing, look for absolutely-sized elements within those divs.  Convert those widths, margins, and padding to percentages as well.

Let’s say there is a div within #content called #single-post with width 550px and 25px margins on either side.  The CSS for that would look like

Since this div is contained in another div, the horizontal widths should total 100%, not 66.7%.

Use this technique if your header is not re-sizing.  Repeat the same process that you used on the header with your footer.  If anything isn’t re-sizing, check for any fixed-width contained elements.

The Menu Bar

OK, now all of the elements on the site should be resizing nicely as you adjust the width of the browser window… except for the menu bar.  The menu bar can be tricky, since it can be implemented in a variety of ways.

The easiest way to deal with the shrinking window is to simply have the menu “double-back” on itself and wrap.  We’re not going to hide the main menu with a button in this case.  Here are some screen shots to show what I’m talking about.  First we have the desktop version.

Here is the mobile version.  Notice how the menu bar just folds back on itself.  We are not doing a fancy menu button here, but it’s still very usable, and less work.

Mobile configuration

Okay, since the structure of menu bars can vary widely, I’m going to do some hand-waving and give you some broad brush strokes here.  It’s impossible to give a step-by-step method that will work in all cases, unfortunately.  Here’s the general idea though.

First, replace any widths defined in pixels using the techniques above.  That alone is probably not enough.  Menu bars often have fixed height, so you’ll have to replace any heights defined in pixels with “min-height” along with “height: 100%”, or something to that effect.

In my case, this only partially worked.  The menu wrapped in a weird way until I added “display: inline-block” to the div containing the menu items.  After I did that, the menu was no longer centered, so I had to wrap it in a new div which was centered.

After all of the hoopla, my menu was centered and wrapped when I made the browser narrow, but it took me over an hour of experimentation to figure out.  More fancy solutions, like a menu that collapses into a Menu Button (sometimes known as a “hamburger”) require JavaScript or jQuery… I reserve that for a future article.

Resizing Images

Okay, hopefully your containers are now resizing, but what about the images? Chances are they were hard coded with dimensions like this:

To make them resize properly, the technique is similar to resizing divs.  Remove the hard-coded width and height from the images and replace them with “width:100%;” and “max-width:” set to whatever you want the normal desktop size to be.  The result is this:

Images set up this way will shrink down when you resize the browser window.

Media Queries

OK, now we have a completely fluid layout that resizes as you make the browser window narrow.  But, it still looks terrible on a thin mobile device screen because the elements are too scrunched up.  We need to separate them so that only one column of content is visible at a time.  In addition, your header probably looks bad, and we’ll have to fix that too.

These problems can be fixed through the use of media queries in your CSS file.  Let’s fix the main content container and sidebar first.  Play with the browser size and determine roughly at what point you want the sidebar to hop below (or above) your main content.  Estimate or measure in pixels how wide the browser window is at that point.  For me, it was at 540 pixels.

Next, we have to “undo” the widths we defined for the content and sidebar to make them fill the whole width of the screen as follows:

The key is making the widths 100% (or 94% in my case, with 3% margin on each side).  Experiment with these settings until  you get what you want.

The Header

We are almost there.  The header probably still looks bad when you make the browser really thin.  For example, the font size might be too big and it might wrap or do other unpleasant things.  This is simple to fix.  Let’s say the original font size was 36px, which is too big when the screen is narrow.  Pick a point where you want to resize it, and add the code below.  For me, the break point was at 400px wide, where I resized the header text to 28 pixels as follows:

The Final Bit

I’ve undoubtedly glossed over many of the little details in your theme that you will need to fix to make it completely responsive. But hopefully with the broad strokes I’ve given you, you’ll be able to fill in the details.

But even after you get your site fully responsive, you might be surprised to still see a shruk-down version of the non-responsive site when you view it on a phone!  What gives?

You have to add one last line of code to tell the phone not to “zoom out” when viewing your site.  It’s easy.  Just add this line to the head section of your HTML code:

This tells the phone’s browser not to zoom out when viewing your page.  Everything should be kosher now.

If you want to see a real example of a non-responsive WordPress theme that I made responsive, check out http://disablemycable.com/blog. The CSS file shows these techniques.

Hope this has helped!!  Let me know how it works for you. – Brian

I am a freelance web developer and consultant based in Santa Monica, CA who uses WordPress, PHP, and JavaScript to create web applications for small businesses and organizations.

Fonte: Make Any WordPress Theme Responsive (Mobile-Friendly)

Developing WordPress Themes Using Responsive Frameworks

It used to be you only had to worry about website consistency across multiple browsers, but now we have to look at the bigger picture – consistency across multiple devices. The computer used to be our only gateway to the Internet, but now we jump online from our phones, TVs, tablets and who knows what else will come down the pipe. Having your website appropriately render and perform on any device should be a top priority this year.

Responsive design is all about making things fluid and adjusting according to screen size. Although WordPress doesn’t always play nice with responsive design methods, there are ways it can be achieved. How responsive you decide to make your website is really about how much time you want to spend doing it.

There are several responsive frameworks out there to choose from. You might want to spend some time investigating each one to determine which has the included features your project might require. If you aren’t sure where to start, here are a few to consider:

Bootstrap from Twitter is built on a responsive 12 column grid. It has included fixed- and fluid-width layouts based on that system. It also comes with support for optional JavaScript plug-ins such as an image carousel, Typeahead, togglable tabs, and many more.

Less Framework is based on 4 layouts and 3 sets of typographic presets. Less Framework uses a default layout as a starting point and then uses CSS3 media queries to code ‘child layouts’.

Foundation is a grid system based on 12-columns that do not have a fixed width; they can vary based on the resolution of the screen or size of the window. Foundation comes pre-packaged with buttons and built in form styles, alerts, and more.

YAML is a multi-column layout based on a grid system with percentage widths. It comes with several built in features and supports several jQuery plugins such as Accessible Tabs and SyncHeight.

This list of frameworks is hardly complete, but for the sake of this tutorial, I’m going to show you how to incorporate Foundation into your next WordPress theme.

To get started, go download Foundation and add the files to your css and js folders in your theme’s directory. The easiest way to add the required files to your theme would be to use wp_enqueue_script and wp_enqueue_style.

For this tutorial I’m going to show you what you place in your functions.php file to make Foundation work right off the bat, but for more details on adding files this way, check out the tutorial on how to include JavaScript and CSS in your theme.

To add the needed JavaScript for Foundation to work properly in your theme, you need to create a function that calls the wp_enqueue_script to serve them up.

Next, add the Foundation stylesheets to make the grid flexible. Paste this function after the one you just created.

Once saved, go back and check your source code to make sure your files were added correctly. It should look something like this:

Everyone loves to go that extra mile to make things work in Internet Explorer right? To make sure your Foundation framework stays responsive in Internet Explorer, you need to add a few conditional statements. These should go in your header.php file before the closing head tag.

Now that your theme has Foundation setup, to make use of all its responsive features you need to design using the Foundation grid system. Like other responsive frameworks, it’s a system made up of 12 columns. Other included features are pre-set button styles, tabs, tables and much more. Check out the Foundation documentation to view all bells and whistles and instructions on how to work with the grid.

There are plenty of free and premium WordPress themes available that make use of responsive design. If you would rather start with something out of the box, you can try out these themes:

WordPress Bootstrap is a theme developed on Twitter’s Bootstrap v.2.0.1. It’s fully responsive with four different page templates to choose from, shortcodes, and multiple sidebar options. Once installed, you can check out bootswatch.com to download different color versions of the theme.

Based on the Themify framework, iTheme2 uses media queries to target different displays, comes with a customizable feature slider, a social media widget, two different theme skins and you can have up to four footer widgets.

The Responsive Twenty Ten theme supports flexible images, margins, and mobile images. It was created as a child theme for the included Twenty Ten theme.

Good Minimal is a clean, minimalist responsive layout that adapts to a multitude of displays and devices. Good Minimal comes with two different styles, supports unlimited custom sidebars, shortcodes, multiple drop down menus, and several other features.

Responsive design is continuing to grow in popularity and knowing how to utilize it within your future theme construction will be crucial for success. Whether you are adding a framework to your theme or using a pre-built theme supporting responsive design, your clients are going to expect multiple device support as a basic service.

Fonte: Developing WordPress Themes Using Responsive Frameworks – Tuts+ Code Tutorial

Trackbacks e pingbacks WordPress

Trackbacks

Quando fazemos referência a um artigo de outro blogue, num artigo do nosso próprio blogue.

Quando utilizamos o “Press This” bookmark do WordPress sobre um artigo que queremos republicar, o WordPress automaticamente adiciona um URL seguido do texto “Fonte: …”. Isto é um trackback. Ou seja, o autor do blogue irá receber um trackback do meu artigo, indicando que fiz referência a um artigo dele.

No entanto, se retirarmos o URL, não existirá nenhum trackback, mas o próprio mecanismo do WordPress irá verificar automaticamente os links de outros posts no nosso artigo e alerta automaticamente a fonte de origem. Isso é chamado de pingback. Uma das vantagens de ser um processo automático é a redução de adulterar o conteúdo, que é perfeitamente possível num trackback.

Por norma, os trackbacks e pingbacks estão ativos quando criamos um post, mas podemos desativá-los a qualquer altura.

Os trackbacks e pingbacks de blogues externos só serão exibidos se o blogue de origem aprovar a solicitação.

Prós e Contras

Como vantagem, ajuda na otimização de SEO. Como desvantagem, por vezes pode originar problemas de copyright ou propriedade inteletual, como resultado da “confusão” que se pode instalar para o utilizador descobrir qual é o artigo original. E a pior, no caso de trackback, pode ser utilizado para envio de SPAM.

How to create wordpress shortcode? – Darko Gjorgjijoski

This article is about creating WordPress shortcode. If you want to get started you need to have at least some PHP knowledge

This is my first post and from now and so on i will use the blog for simple tutorials to teach you about web development, web design. In this post i will show you how to make your own custom shortcodes.

Shortcodes are some kind of code in wordpress that allow you to display something in easier way without custom fields, editing the template or adding bunch of html. Today i will show you what how to develop your wordpress shortcodes. So, let’s say you want to show your five recent posts with shortocde like this [recentposts number=”5″].

1. You need to create function that will be your shortcode. In the function you need to specify the attributes of the shortocde in this case they are like this

PHP functions have names and attributes(not the same as below, this is php function attributes and below are shortcode attributes.). The function take two attributes $atts and $content.

Realized what is the function name? Now we continue to develop the function. First we create array for the shrotcode attributes and the array have one attribute called number. The default value of number is 3. You can set it or leave like ”.

Then we need to create custom WordPress query. To query the recent posts ordered by date. We do it like this:

After we created the query, we should use it to call the posts.

Now we need to add action to shortcodes and register your shortocde with the following:

Congratulations! That’s all. You created your shortcode. If you don’t know what loops mean in php and wordpress. Please read here. Here is the full function that we developed.

To call the shortocode from your content editor. Simply use the following:

*You can change the style with css. I used html lists to display the recent posts. Feel free to style them or use different html elements.

Fonte: How to create wordpress shortcode? – Darko Gjorgjijoski

Object-Oriented Programming in WordPress

  1. An Introduction
  2. Classes
  3. Types
  4. Control Structures: Conditional Statements
  5. Control Structures: Loops
  6. Functions and Attributes
  7. Scope
  8. Building the Plugin I
  9. Building the Plugin II
  10. Document the Plugin I
  11. Document the Plugin II
  12. Inheritance I

Over the last 12 posts, we’ve taken a look at the basics of PHP, the basics of object-oriented programming, how to do so within the context of WordPress, and we’ve even looked at the beginning of more intermediate concepts such as inheritance.

At this point, it’s time to draw this beginner’s series to a close but prior to doing so, I’d like to provide a summary of each of the articles so that we not only have a refresher of the everything that we’ve done, but so that we also have a single summary page to bookmark for reference.

With that said, let’s review everything we’ve covered up to this article. We’ll include links back to the original article, short descriptions, and other pertinent information.

In the first post of the series, we discussed where we were headed with the articles that were to follow. In short, we provided a high-level outline as to what we’d be discussing, and then moved forward from there.

Perhaps the most important take away from this article was understanding “where do I start?” Which is a question many people ask when getting started with programming.

To that, we said:

But those who have been at it for a significant amount of time often forget what it was like when originally trying to figure out how to decipher code, understand why something was written the way that it was, how the author knew to use what function and where, and determine the rationale behind certain implementation decisions.

We’ve all been there at some point, right? We’ve looked at the code, tried to figure out the flow of control, and at one time asked “where do I even start?”

And the purpose of this series is to answer that question.

And so that’s exactly what we aimed to do with the following points that were covered each in their own article.

The purpose of this post was to define the foundation of object-oriented programming – classes. First, we mentioned that classes are typically defined as the following:

A class is a blueprint for creating an object.

But we also recognized that this is a particularly confusing for most people especiallyif they’re just beginning object-oriented programming.

So instead, we talked about class in terms of what characteristics it defines:

So let’s generalize this idea to objects. In fact, let’s substitute one word for another:

A noun is an object.

An adjective an an attribute (or a property).

A verb is a method (or a function).

Additionally, we looked at both good and bad examples as to what defines a class, and we worked on defining a mental model for how to pictures classes when working with them

This ultimately laid the ground work for the plugin that we’d be writing in the future. But first, we needed to make sure that we had a firm understanding of the basics of PHP before moving into the more advanced feature of classes.

In this article, we talked about the two types that exist within WordPress:

  1. Simple Types
  2. Complex Types

And then we defined each of the above as such:

Simple data types are defined as such because the data that they represent is, y’know, simple. That is to say that it will normally fall under the banner of true, false, decimals, and words and/or sentences.

And then we said:

The two primary complex datatypes that we’re going to focus on in this series as arrays and objects. There are more, but they are outside the scope of this series, so if you’re interested, then feel free to take a look at the PHP manual, but I warn you: if you’re an absolute beginner, the content may feel a little overwhelming.

In short, examples of the above can be illustrated as:

  • booleans
  • integers
  • floating point numbers
  • strings
  • arrays
  • objects
  • …and more

Of course, these are primarily useful once we start using them within the context of more advanced features such as conditional statements and control structures.

In the first article in the Control Structures series, we talked about conditional statements.

First, recall that:

“Control Structures” is a fancy term term that describes how we can, ahem, control how the code flows through our program based a number of factors.

The two control structures that we talked about are if/then statements andswitch/case statements, then we looked at examples of each. On top of that, we employed these in some of the code that we wrote in either our plugin or in our example of inheritance.

In the same series, we talked about loops.  Remember:

Assume that we have a set of data, perhaps a set of 10 posts, and that we want to loop through and print out the title and date of each post. Loops allow us to do this.

The list of loops at which we looked included:

  • for
  • foreach
  • do
  • while

And we looked at examples of each and how to use them while iterating through a variety of data structures.

After covering some of the foundational aspects of PHP development, we moved onto covering functions – which can still be used in procedural programming – and attributes, which are unique to object-oriented programming.

To summarize, functions are used to complete a unit of work but they also use some of the aforementioned structures to help complete said work:

Variables, conditionals, loops, and so on are responsible for completing a single unit work, as well; however, each of those work in conjunction with one another to achieve something slightly greater than themselves.

We then took a look at an example of various functions – some which were extremely simply, others which were more complex that leveraged all of the above types, control structures, and loops.

But that’s not all: Since functions can exist within a class and help a class complete their work, they also work in conjunction with attributes (which are the adjectives of an object, if you recall from earlier in the article).

The thing about attributes is this:

They are nothing but variables as we’ve looked at earlier in the series, and they can hold any type of value be it a primitive data type such as a string, integer, boolean or it can reference a more complex data type such as an array or another object.

The thing is, they aren’t locked into a function. Instead, they live at the class level. And when they reside at the class level, there’s a level of scope that they – along with the functions – must have.

From there, we began talking about scope.

In short, scope refers to how variables and functions can be access from third-party objects or child objects within the program.

In the article, we even looked at a high-level diagram as well as some source code that demonstrated the point.

The key takeaway; however, is that scope can come in three different flavors:

  1. public which is available to the class itself and all third-party classes
  2. protected which is available to the class itself and all subclasses
  3. private which is available only to the class in which it is defined

This became even more clear as we began building our plugin using what we’ve learned.

In the Building The Plugin series, we first talked about exactly what we’d actually be building and then we actually began to implement the plugin.

Throughout this process, we learned the importance of planning out the plugin before we actually begin implementation so that we have a roadmap, of sorts, in order to know where we’re headed.

After doing that, we then began the actual implementation of the ideas that we had outlined to the point where we had a fully functional plugin that covered exactly everything we had covered up to this point.

In fact, we made the plugin available for download on GitHub.

But we weren’t done yet. After that, we needed to document the plugin using proper code comments to explicate what each of our files, classes, attributes, and methods do.

In this series of articles, we first talked about the PSR standards as well as the WordPress Coding Standards and we began documenting the basics of our plugin.

However, it wasn’t until the second part of the series that we really began to employ the documentation strategies as providing in the WordPress Coding Standards. In this post, we rounded out the rest of our documentation efforts by providing comments for every class, attribute, function, and even require statement that exists within the plugin.

Ultimately, this rounded out development of the plugin and allowed us to transfer our discussion to a more intermediate topic.

Over the next two posts, we covered one of the more intermediate topics of object-oriented programming: Inheritance. This wasn’t meant to be an all inclusive-primer on the topic, but it was meant to be enough to help those of you with a budding interest in object-oriented programming in PHP become familiar with how it works.

In the first article, we took a look at some of the fundamentals as well as how it’s used throughout the WordPress application specifically when using widgets.

In the final article, we built our own implementation of inheritance that, although very simplistic, provided a workable demonstration for how inheritance works within PHP.

Obviously, we have covered a lot of content in this series. Hopefully, those of you who are just getting started with working in WordPress and object-oriented programming in general have found it useful.

Though I’m not opposed to running another series of advanced topics, I’m more curious about your feedback, comments, and questions on the current series. Please feel free to offer that up in the comment feed.

As far as any future series are concerned, let me know and we’ll see what we can do.

Other than that, good luck with your endeavors with WordPress, object-oriented programming, and so on. I can’t wait to see what you come up with!

Fonte: Object-Oriented Programming in WordPress: A Summary – Tuts+ Code Article

10 Useful WordPress Security Tweaks – Smashing Magazine

 

Security has always been a hot topic. Offline, people buy wired homes, car alarms and gadgets to bring their security to the max. Online, security is important, too, especially for people who make a living from websites and blogs. In this article, we’ll show you some useful tweaks to protect your WordPress-powered blog.

[Offtopic: by the way, did you know that there is a Smashing eBook Series? Book #1 is Professional Web Design, 242 pages for just $9,90.]

1. Prevent Unnecessary Info From Being Displayed

The problem
When you fail to log into a WordPress blog, the CMS displays some info telling you what went wrong. This is good if you’ve forgotten your password, but it might also be good for people who want to hack your blog. So, why not prevent WordPress from displaying error messages on failed log-ins?

The solution
To remove log-in error messages, simply open your theme’s functions.php file, and paste the following code:

view source

print?

1
add_filter('login_errors',create_function('$a', "return null;"));

Save the file, and see for yourself: no more messages are displayed if you fail to log in.

Please note that there are several functions.php files. Be sure to change the one in your wp-content directory.

Code explanation
With this code, we’ve added a simple hook to overwrite the login_errors() function. Because the custom function that we created returns only null, the message displayed will be a blank string.

Source

2. Force SSL Usage

The problem
If you worry about your data being intercepted, then you could definitely use SSL. In case you don’t know what it is, SSL is a cryptographic protocol that secures communications over networks such as the Internet.

Did you know that forcing WordPress to use SSL is possible? Not all hosting services allow you to use SSL, but if you’re hosted on Wp WebHost or HostGator, then SSL is enabled.

The solution
Once you’ve checked that your Web server can handle SSL, simply open your wp-config.php file (located at the root of your WordPress installation), and paste the following:

view source

print?

1
define('FORCE_SSL_ADMIN', true);

Save the file, and you’re done!

Code explanation
Nothing hard here. WordPress uses a lot of constants to configure the software. In this case, we have simply defined the FORCE_SSL_ADMIN constant and set its value to true. This results in WordPress using SSL.

Source

3. Use .htaccess To Protect The wp-config File

The problem
As a WordPress user, you probably know how important the wp-config.php file is. This file contains all of the information required to access your precious database: username, password, server name and so on. Protecting the wp-config.php file is critical, so how about exploiting the power of Apache to this end?

The solution
The .htaccess file is located at the root your WordPress installation. After creating a back-up of it (it’s such a critical file that we should always have a safe copy), open it up, and paste the following code:

view source

print?

1
<files wp-config.php>

2
order allow,deny

3
deny from all

4
</files>

Code explanation
.htaccess files are powerful and one of the best tools to prevent unwanted access to your files. In this code, we have simply created a rule that prevents any access to the wp-admin.php file, thus ensuring that no evil bots can access it.

Source

4. Blacklist Undesired Users And Bots

Sm4 in 10 Useful WordPress Security Tweaks

The problem
This is as true online as it is in real life: someone who pesters you today will probably pester you again tomorrow. Have you noticed how many spam bots return to your blog 10 times a day to post their annoying comments? The solution to this problem is quite simple: forbid them access to your blog.

The solution
Paste the following code in your .htaccess file, located at the root of your WordPress installation. As I said, always back up the .htaccess file before editing it. Also, don’t forget to change 123.456.789 to the IP address you want to ban.

view source

print?

1
<Limit GET POST PUT>

2
order allow,deny

3
allow from all

4
deny from 123.456.789

5
</LIMIT>

Code explanation
Apache is powerful and can easily be used to ban undesirable people and bots from your website. With this code, we’re telling Apache that everyone is allowed to visit our blog except the person with the IP address 123.456.789.

To ban more people, simply repeat line 4 of this code on a new line, using another IP address, as shown below:

view source

print?

1
<Limit GET POST PUT>

2
order allow,deny

3
allow from all

4
deny from 123.456.789

5
deny from 93.121.788

6
deny from 223.956.789

7
deny from 128.456.780

8
</LIMIT>

Source

5. Protect Your WordPress Blog From Script Injections

The problem
Protecting dynamic websites is especially important. Most developers always protect their GET and POST requests, but sometimes this is not enough. We should also protect our blog against script injections and any attempt to modify the PHP GLOBALS and _REQUEST variables.

The solution
The following code blocks script injections and any attempts to modify the PHP GLOBALS and _REQUEST variables. Paste it in your .htaccess file (located in the root of your WordPress installation). Make sure to always back up the .htaccess file before modifying it.

view source

print?

1
Options +FollowSymLinks

2
RewriteEngine On

3
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]

4
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]

5
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})

6
RewriteRule ^(.*)$ index.php [F,L]

Code explanation
Using the power of the .htaccess file, we can check requests. What we’ve done here is check whether the request contains a <script> and whether it has tried to modify the value of the PHP GLOBALS or _REQUEST variables. If any of these conditions are met, the request is blocked and a 403 error is returned to the client’s browser.

Sources

6. Fight Back Against Content Scrapers

The problem
If your blog is the least bit known, people will no doubt try to use your content on their own websites without your consent. One of the biggest problems is hot-linking to your images, which saps your server’s bandwidth.

The solution
To protect your website against hot-linking and content scrapers, simply paste the following code in your .htaccess file. As always, don’t forget to back up when modifying the .htaccess file.

view source

print?

1
RewriteEngine On

2
#Replace ?mysite\.com/ with your blog url

3
RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mysite\.com/ [NC]

4
RewriteCond %{HTTP_REFERER} !^$

5
#Replace /images/nohotlink.jpg with your "don't hotlink" image url

6
RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]

Once you’ve saved the file, only your website will be able to link to your images, or, to be more correct, no one would link to your images, because it would be way too complicated and time-consuming. Other websites will automatically display the nohotlink.jpg image. Note that you can also specify a non-existent image, so websites that try to hot-link to you would display a blank space.

Code explanation
With this code, the first thing we’ve done is check the referrer to see that it matches our blog’s URL and it is not empty. If it doesn’t, and the file has a JPG, GIF, BMP or PNG extension, then the nohotlink image is displayed instead.

Source

7. Create A Plug-In To Protect Your Blog From Malicious URL Requests

Sm7 in 10 Useful WordPress Security Tweaks

The problem
Hackers and evil-doers often use malicious queries to find and attack a blog’s weak spots. WordPress has good default protection, but enhancing it is possible.

The solution
Paste the following code in a text file, and save it as blockbadqueries.php. Once you’ve done that, upload it to your wp-content/plugins directory and activate it as you would any other plug-in. Now your blog is protected against malicious queries.

view source

print?

01
<?php

02
/*

03
Plugin Name: Block Bad Queries

04
Plugin URI: http://perishablepress.com/press/2009/12/22/protect-wordpress-against-malicious-url-requests/

05
Description: Protect WordPress Against Malicious URL Requests

06
Author URI: http://perishablepress.com/

07
Author: Perishable Press

08
Version: 1.0

09
*/

10

11
global $user_ID

12

13
if($user_ID) {

14
if(!current_user_can('level_10')) {

15
if (strlen($_SERVER['REQUEST_URI']) > 255 ||

16
strpos($_SERVER['REQUEST_URI'], "eval(") ||

17
strpos($_SERVER['REQUEST_URI'], "CONCAT") ||

18
strpos($_SERVER['REQUEST_URI'], "UNION+SELECT") ||

19
strpos($_SERVER['REQUEST_URI'], "base64")) {

20
@header("HTTP/1.1 414 Request-URI Too Long");

21
@header("Status: 414 Request-URI Too Long");

22
@header("Connection: Close");

23
@exit;

24
}

25
}

26
}

27
?>

Code explanation
What this code does is pretty simple. It checks for excessively long request strings (more than 255 characters) and for the presence of either the eval or base64 PHP functions in the URI. If one of these conditions is met, then the plug-in sends a 414 error to the client’s browser.

Source

8. Remove Your WordPress Version Number… Seriously!

The problem
As you may know, WordPress automatically displays the version you are using in the head of your blog files. This is pretty harmless if your blog is always up to date with the latest version (which is certainly what you should be doing anyway). But if for some reason your blog isn’t up to date, WordPress still displays it, and hackers will learn this vital piece of information.

The solution
Paste the following line of code in the functions.php file of your theme. Save it, refresh your blog, and voila: no more WordPress version number in the header.

view source

print?

1
remove_action('wp_head', 'wp_generator');

Code explanation
To execute certain actions, WordPress uses a mechanism called “hooks,” which allow you to hook one function to another. The wp_generator function, which displays the WordPress version, is hooked. We can remove this hook and prevent it from executing by using the remove_action() function.

Source

9. Change The Default “Admin” Username

Sm9 in 10 Useful WordPress Security Tweaks

The problem
Brute force is one of the easiest ways to break a password. The method is simple: try as many different passwords as possible until the right one is found. Users of the brute force method use dictionaries, which give them a lot of password combinations.

But knowing your username certainly makes it easier for them to guess the right combination. This is why you should always change the default “admin” username to something harder to guess.

Note that WordPress 3.0 let you choose your desired username by default. Therefore, this tip is still usefull if you still use the old “admin” account from older WordPress versions.

The solution
If you haven’t changed the “admin” username yet, simply run the following SQL query to your database to change it for good. Don’t forget to specify your desired username.

view source

print?

1
UPDATE wp_users SET user_login = 'Your New Username' WHERE user_login = 'Admin';

Code explanation
Usernames are stored in the database. To change one, a simple UPDATE query is enough. Note that this query will not transfer posts written by “admin” to your new username; the source post below shows you how to easily do that.

Source

10. Prevent Directory Browsing

The problem
By default, most hosts allow directory listing. So, if you type http://www.yourblog.com/wp-includes in the browser’s address bar, you’ll see all of the files in that directory. This is definitely a security risk, because a hacker could see the last time that files were modified and access them.

The solution (Updated)
Just add the following to the Apache configuration or your .htaccess file:

view source

print?

1
Options -Indexes

Code explanation
Please note that it’s not enough to update the blog’s robots.txt file with Disallow: /wp*. This would prevent the wp-directory from being indexed, but will not prevent users from seeing it.

Source