scriptygoddess

This is possibly the most bizarre thing I've ever seen. (This is relevant to version 2.8.4). If you have your WordPress install set up to be http://www.yourdomain.com but your blog install set up to be http://yourdomain.com (note the missing "www") and you try to search for posts from with the WordPress admin, you get redirected to your blog's (front end) homepage. If you change your WordPress install to match your blog install (ie. remove the WWW – then it works fine) Sounds like a bug to me. I'll submit it to the WP team and see what they say – but in the meantime should you be up past 1am trying to figure that little gem out, hopefully I've saved you some trouble and you can get to sleep earlier than I did. LOL!

I was recently asked by a client how they could easily add anchor links within a particularly long post they had made in WordPress. (Ie. a list of links at the top of the page that would jump the user down to the appropriate section where they needed to be.) I thought about maybe explaining to them to switch over the HTML tab and writing the HTML for the anchor links, but that step alone can sometimes really freak some clients out. :) So I came up with a solution to the problem using shortcodes and using the "build link" button already in the WordPress edit post box.

So the first step is to create the code so the shortcode will work. If you don't already have a functions.php file in your template directory, make a new file, name it "functions.php" and add the following code (surrounded by <?php and ?>). If you do already have a functions.php file, add the following code within those php tags:

function anchorlink($atts) {
extract(shortcode_atts(array(
"id" => ''
), $atts));
return '<a name="'.$id.'"></a>';
}
add_shortcode('anchor', 'anchorlink');

Then, in your post. In front of the location you want to be able to create a link to add the following:

[anchor id="unique_id_here"]

So for example.. If your post is a "Q/A" type page, down where you have the full question and answer, add that shortcode:

[anchor id="elephantquestion"]Q: What do elephants eat?
A: Elephants eat mainly grass, leaves, bark and twigs. Sometimes they will also eat fruit and seeds.

Then at the top – where you probably have a list of all the questions on the page like this:

What do elephants eat?
What do giraffes eat?
etc.

(In this example) highlight the "What do elephants eat" text, click the LINK button in the edit post area – remove the "http://" that automatically is included in the link field that pops up and instead, add a pound symbol # and then the id you used:
Screen shot 2009-09-10 at Sep 10  11.51.47 AM

I know this isn't a huge leap from simply writing the HTML that does this. But I've found that some clients don't understand (and don't want to understand) HTML. This IS actually simpler for them. Especially when you might run into the scenario of someone forgetting to close the anchor tag with a </a> – and suddenly the whole page is acting weird… I also think it's probably helpful to SEE the ID right there in plain text in the post – so that when you're making the links at the top, you can quickly see what the ID is that you need to link to.

29 Aug, 2009

Simple Shortcode for Line Breaks

Posted by: Jennifer In: WordPress| WordPress Hacks

One kind of funny thing with WordPress is that entering HTML in the post window can sometimes lead to unexpected results. Sometimes WordPress (or probably more specifically the WYSIWYG visual editor) will eat some or all of the HTML. A friend of mine (Hi Chris!) was asking me how to add line breaks to her post. Adding the actual HTML for a line break didn't work because WordPress ate it. The simplest solution for this is to use shortcodes to get the HTML into the post without WordPress munching it.

To add the shortcode – go to your themes functions.php file (if you don't have this file in your theme, simply create a file called "functions.php" and throw it in your theme folder.) Then add the following code to this file (make sure the function name doesn't class with something else already in there just in case!)

function breakall() {
   return '<br clear="all" />';
}
add_shortcode('br', 'breakall');

Now, when writing your posts, if you need to add a line break or two just add the following where you want the linebreak:

[br]

That will be converted to <br clear="all" /> when the page is displayed.

Shortcodes are an amazingly powerful little feature. Read more about shortcodes here:

Shortcode API
Mastering WordPress Shortcodes
10 Incredibly Cool WordPress Shortcodes

28 Aug, 2009

Playing with Post Attachments

Posted by: Jennifer In: WordPress| WordPress Hacks

I've been doing a ton of sites recently using WordPress (almost always as a CMS, and only occasionally as a real BLOG) – and there is a lot of power that can be gained by playing around with the post attachments. Specifically if you want photos or documents that are "attached" to a post to show up somewhere outside of the "loop". (FYI: Something that is "attached" to a post means that you uploaded a photo, video or document when editing a particular post. That file is then associated (aka "attached") with that particular post)

If you have the post's ID you can pull attachments anywhere in your layout, and on any post or page in your WordPress site. Here's an example: On one site, my client is using WordPress for their press releases. For each "post," in a sidebar, they wanted to have some photos and copies of the press release for download in various formats (Word, PDF, and Text). So the first trick is getting and saving the current post's ID. (*I'll add that maybe I'm missing something here, but when I've tried to pull out the post ID outside of the loop or with other methods, I would tend to have some unexpected results. This worked – so I've just stuck with it)

So, we're working on the single.php template file. Before you start the loop – declare the variable we'll be using in the sidebar:

<?php $thepostid = ""; ?>

Once inside the loop, we need to fill the variable with the post id of the current post:

<?php $thepostid = $post->ID; ?>

Now we can use $thepostid anywhere we like… So in our sidebar, here are various ways to grab attachments, based on their file type.

This will grab all images attached to the post, sorted by the "sort order" you entered in the "gallery" tab in that media popup for the post:

$images = get_children(array(
'post_type' => 'attachment',
'post_status' => null,
'post_parent' => $thepostid,
'post_mime_type' => 'image',
'order' => 'ASC',
'orderby' => 'menu_order ID'));

This one will pull any attachments that are word docs:

$worddocs = get_children(array(
'post_type' => 'attachment',
'post_status' => null,
'post_parent' => $thepostid,
'post_mime_type' => 'application/msword'));

Change "post_mine_type" to 'text/plain' for .txt files, or 'application/pdf' for .pdf files. Here's a list of more mime types you can specify. (That list has a bunch of file types you'd probably never use in WordPress – but it's pretty complete)

Using the Word docs example – If we want to automatically list and link to the word docs attached to the post then we can do the following:

if ($worddocs) {
foreach($worddocs as $worddoc) {
echo '<p><a href="'.$worddoc->guid.'">Word Format</a></p>';
}
}

FYI – $worddoc->guid is the path to the file. In fact, while we're on that subject, once you've pulled in the attachments, there's a lot of info you have at your fingertips when you run that foreach loop. Some of these aren't really applicable to an attachment – but they're in there anyway: (I've bolded the ones most useful)

  • ID (attachment's ID)
  • post_author
  • post_date
  • post_date_gmt
  • post_content
  • post_title (attachment's Title)
  • post_excerpt (attachment's caption)
  • post_status
  • comment_status
  • ping_status
  • post_password
  • post_name (attachment's filename without the extension)
  • to_ping
  • pinged
  • post_modified
  • post_modified_gmt
  • post_content_filtered
  • post_parent (The ID of the post the attachment is associated with)
  • guid (Full URL to attachment)
  • menu_order (Gallery sort order)
  • post_type (For attachments, this will be "attachment")
  • post_mime_type (This is where you can specifically look for the mime type. Images will be image/jpeg image/gif image/png etc.)
  • comment_count

Here's an example of looping through those images. (This is what I used in that Press release template. We wanted to show the thumbnail for the image, then offer a link to download the other sizes of the photos as well as show the caption for the photo)

<?php
if ($images) {
foreach($images as $image) {
//get thumbnail of image first: (we'll actually display this one)
$attachment=wp_get_attachment_image_src($image->ID, 'thumbnail');
?>
<p class="thumbnail"><img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> /></p>
<p class="imagecaption"><?= $image->post_excerpt; ?></p>
<?php
// get medium size image image next, we'll just link to this one
$attachment=wp_get_attachment_image_src($image->ID, 'medium');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View Large Image</a></p>
<?php
//Now get the full size image, again just linking for people to download
$attachment=wp_get_attachment_image_src($image->ID, 'full');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View High Resolution Image</a></p>
<?php }
} ?>

So here's a VERY IMPORTANT thing about using that $thepostid in the sidebar template. If you pull in your sidebar into your template using the standard get_sidebar(); the value of $thepostid will not be retained. You will have to pull in your sidebar as an include like so:

<?php include( TEMPLATEPATH . '/sidebar.php' ); ?>

Here are some extra things you can do. Let's say on some posts, you want to be able to specify it to ignore pulling in the attachments like this. Solution: Add a custom field for that post in WordPress – then in your sidebar file, have it check for the value of that custom field before pulling in the attachments.

So for this example, on the post, the custom field you would add would have a key of "showimages", and a value of "false" on posts you don't want to have the attachments show up on. Modify your sidebar and add the following before you pull in the attachments:

$showimages = get_post_meta($thepostid, "showimages");
if ($showimages != "false") {
... pull in attachments ...
}

Ok another extra: Let's say you've already uploaded a photo to a DIFFERENT post, and you want that included in our sidebar for THIS post. This gets a little trickier. You have to know the ID of the actual attachment you want to add in. Kind of hard to find this, but if you go to "Media" (WordPress side navigation) – it will show you a list of all the attachments you've ever uploaded. Find the one you want to add to your post. If you mouseover the "edit" link for that attachment and if you look at the "status" in your browser (very bottom of the browser window) – you'll see a URL that probably looks something like this:

http://www.yourdomain.com/wp-admin/media.php?action=edit&attachment_id=1607

Make a note of that "attachment ID" – that's what you need for this…

Go back to editing your post. You'll add a custom field for each extra image you want to pull in. The key for each will be "extraimage" the value will be the attachment ID. In your template you need the following:

$extraimage = get_post_meta($thepostid, "extraimage");

(The above pulls in an array of those custom fields – it will be an array of attachment IDs that you wanted to pull into the sidebar)

Now we'll first check to see if we even HAVE any values in there

<?php
if ($extraimage) {
//Now loop through images specified in custom fields...
foreach($extraimage as $imageid) {
//notice this is not get_children! That's because we're using the attachment ID specifically - not the POST's ID
$image = get_post($imageid);
$excerpt = $image->post_excerpt;
//get the thumbnail to show
$attachment=wp_get_attachment_image_src($imageid, 'thumbnail');
?>
<p class="thumbnail"><img src="<?php echo $attachment[0]; ?>" <?php echo $attributes; ?> /></p>
<p class="imagecaption"><?= $excerpt; ?></p>
<?php
//get the medium size for the link
$attachment=wp_get_attachment_image_src($imageid, 'medium');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View Large Image</a></p>
<?php
// get the large size for the link
$attachment=wp_get_attachment_image_src($imageid, 'full');
?>
<p class="imagelink"><a href="<?=$attachment[0];?>" target="_blank">View High Resolution Image</a></p>
</div>
<?php }
} ?>

Here's my last little trick. In some cases – some images you'll want to have show up in the sidebar, and others, you may actually be including in the post itself. The ones being included in the post itself, you probably don't want repeated in the sidebar – so to distinguish one between the other, we can use the "sort order" to tell whether it should be included or not. When you're uploading your images, set the sort order to 1 for any image you DO NOT want included in the sidebar, and then you can use 2 and up to control the order and indicate the images you DO want included in the sidebar. (Little side note: The default sort order for images you upload will probably be BLANK which means it's 0 – which, using this method, means it will not automatically show up in the sidebar unless you give it a value or 2 or greater) Some slight adjustments to the code to check for that menu order (aka sort order) are as follows.

Just showing a snippet of what we've done above so you get the idea.

foreach($images as $image) {
if ($image->menu_order > 1) {
$attachment=wp_get_attachment_image_src($image->ID, 'thumbnail');
echo '<p><img src="'. $attachment[0].'" /></p>';
}
}
}

08 Aug, 2009

Adding alternate row styles to a table with JQuery

Posted by: Jennifer In: jquery

JQuery's simplicity is so wonderful and powerful. Here's a perfect example. If you have a table, and you want to alternate the row colors. To do so, all you need is this:

$(document).ready(function() {
$("table.striped tr:nth-child(even)").addClass("altrow");
});

Then, just add class="striped" to your table tag, and jquery will automatically apply add the class "altrow" to every other row. (If you want to change which row it starts with – change 'even' to 'odd' in the code above).

Then just include a style for your altrow:

table.striped tr.altrow td {
background-color: #ccc;
}

And to think I used to do that manually. OY!

17 Jun, 2009

Wordpress 2.8 Issues

Posted by: Jennifer In: WordPress: Lessons Learned

In case you hadn't heard (and if you're using wordpress, how could you NOT have heard) :) Wordpress 2.8 is out. One of the features included in this round was a rework of the way Widgets work – including a easier to use API. In light of this, I made use of the new API (armed with this great tutorial and sample file) and created some custom widgets for my clients.

A few problems:
I needed to use TinyMCE for one of the textareas, (There's some good information here on how to do that) because the client doesn't know and doesn't want to know HTML. Trying to apply TinyMCE to the textarea in a widget presented all kind of problems.

Also – just simply dragging and dropping the widgets onto the correct sidebar was excruciating slow.

The solution to both of these problems was solved in the 2.8 FAQ – specifically – turning on "Accessibility Mode" in the screen options for the widgets page. It's not as snazzy as it was before – but being excruciatingly slow and TinyMCE not working isn't snazzy either. So I'll take "functional" over "Snazzy but not functional".

Anyway – just putting this out there for anyone else running into similar problems.

This is the second time I've run into this problem. I opted not to post about it the first time, because the solution was so simple it was kind of silly. But lo-and-behold – I hit it again and forgot what the solution was anyway. :)

I know there can be more than one thing that causes that "open_basedir restriction in effect" error – but in my case it was because:

1) I was moving a wordpress site to another location (usually a subdomain of a live site so I could set it up as a "test area")
2) In the settings page, I had specified a different path for uploads (this is done on the "miscellaneous" settings page). This directory was actually OUTSIDE of the wordpress directory, which means I had to use the full server path to point to my custom uploads directory…

So I copied over the files to the test area, copied the database to the test database, changed the domain to the test domain using this method. But if you've specified a path for uploads on that miscellaneous page – you'll need to log in once everything is all set up and change the path there too to the new one pointed at the new location.

A recent project I've been working on involved a portfolio page that required a "carousel" type browser. It also needed to have multiple rows (so that images could be grouped into various projects). Also, because this page would contain a large number of images, it was required that the images not be loaded until you pulled up that particular project/row in the carousel.

There are a lot of carousel scripts out there, and there is a scrolling plugin that I had been counting on to help me create what I needed – but to be honest, either I couldn't get those scripts to work the way I wanted them to, or I couldn't get them to work AT ALL. I spent a few frustrating days fighting with the plugins, when I finally threw in the towel. I knew what I wanted to do, and figured I'd be better off hand coding specifically what I needed instead of retrofitting a pre-made plugin or script. It turned out to be less time consuming, and in the end I got exactly what I wanted.

So while this script was for a specific purpose, I thought I would put it out here anyway on the chance that it might work for or help someone else. It's probably possible to "package it up" into a more modular plugin.

So first here is the very rough, proof of concept/demo. (no design on that page – just wanted to show how the script works) :)

Here you can download all the files (except the photos – I originally grabbed them from stock.xchng)

I'll walk through just a few of the details of how the HTML needs to be structured in order to get the script to work – but the files in the zip are well commented and should explain the rest.

One important trick with this script is that there are some "naming conventions" that it relies on. Each row of photos is setup as a unordered list. The ID of that unordered list is used as a base for naming other related elements. So for example – the first row is named with and ID of "row1" – I use that base for the ID of a div that contains links to the images in that row. I want this div to only appear when that row1 is being shown. So the ID of the div needs to be created like ROW BASE NAME + "-nav". So, specifically: "row1-nav".

You'll notice in the HTML when I link to rows or specific images in the row – I didn't put the id of the image inside the "href" element. I actually repurposed the "rel" attribute and put the image I wanted to display in the carousel in that. (The script didn't work quite right if I put the row name in the href value).

Another "repurpose" I've done is for use with the delayed image loading. In each of the LI element, I "store" the path to the image that will be loaded inside the LI element in the "title" tag.

I've pulled out as many "variables" as I could in the javascript.js – row names, image names, classnames – and explained what they are and how they relate to the HTML in the comments to make reusing the code as easy as possible.

So an important note, I don't claim this to be an easy to use plugin. If you're going to use this script, you do have to some level of understanding of jquery, javascript, html. I also can't promise too much (un-paid) support. If you want to use it, you're welcome to it – please leave the credit lines in place – I spent quite a bit of time getting this to work. And for my own curiosity, I'd love it if you came back here and posted a link to where you're using it. If you can't get it to work, you're welcome to post a question here, but I can't guarantee I'll be able to help out.

If you are using the default theme and have made modifications to it without renaming it - you may be in for a surprise when you upgrade using the new easy auto-upgrade button. Your theme will be replaced with the original one that WordPress came with. For all I know there's probably already a document/installation instruction that warns you of this fact somewhere. (I would hope anyway)

I know this may or may not apply to many people – but having just lost a bunch of changes on a site I was working on (had been tweaking the default theme to test out some stuff) I didn't realize that 1-click upgrade feature would do that.

Other than that – the new upgrade thing is awesome. Easily upgraded a bunch of other sites (that thankfully used custom named themes!) without issue and because it just a one-click upgrade – I did it much sooner than I would have if I had to download and manually upload everything.

When you use wp_list_pages() – you get a full dump of everything. If you restrict the depth, then you might not be showing the child / subpages under each page.

The code I have below will first list only the "main nav" (parent) pages. If you click on one of the main nav / (parent) pages and it has children pages – then it will list ALL subpages under that parent page (including if there are multiple parent/child pages under it – it will list all of them). So for example…

If this is your page structure:

  • Home
  • About Us
    • Who we are
    • What we do
    • Why you want to hire us
      • Our prices
      • Our people
      • Our philosopy
  • Contact Us
    • Map to our offices
    • Phone Numbers
    • Contact Form

So this would first list just the main nav items – Home, About Us, and Contact us. Like this:

  • MAIN NAV (you can change/remove this – just put it here for explanatory purposes)
    • Home
    • About Us
    • Contact Us

Once you click on About us – all the subnav under about us is revealed in a separate list below the main nav items – and will stick around for as long as you're in an "about us" page. Kind of like this:

  • MAIN NAV (you can change/remove this – just put it here for explanatory purposes)
    • Home
    • About Us
    • Contact Us
  • SUB NAV FOR: About Us
    • Who we are
    • What we do
    • Why you want to hire us
      • Our prices
      • Our people
      • Our philosopy

<ul>
<?php wp_list_pages('title_li=<h2>MAIN NAV</h2>&depth=1' ); ?>
</ul>
<?php
if ($post->post_parent == 0) {
$children = wp_list_pages("title_li=&child_of=".$post->ID."&echo=0");
$parentpage = $wpdb->get_row("SELECT ID, post_title, post_name FROM $wpdb->posts WHERE ID = '".$post->ID."'");
}
if ($post->post_parent != 0) {
$next_post_parent = $post->post_parent;
while ($next_post_parent != 0) {
$children = wp_list_pages("title_li=&child_of=".$next_post_parent."&echo=0");
$parentpage = $wpdb->get_row("SELECT ID, post_title, post_parent, post_name FROM $wpdb->posts WHERE ID = '".$next_post_parent."'");
$next_post_parent = $parentpage->post_parent;
}
}
?>
<?php if ($children) { ?>
<ul>
<li><h2>SUBNAV FOR: <a href="<?php echo get_permalink($parentpage->ID); ?>"><?php echo $parentpage->post_title; ?></a></h2>
<ul>
<?php echo $children; ?>
</ul>
</li>
</ul>
<?php } ?>

If someone knows of an easier/better way than this – please let me know. I've looked and couldn't find anything (and was happy to have figured something out that worked!)

You can put this anywhere in your template file really. This code would be used OUTSIDE of the WordPress loop…

Update: So just a bit more advanced "features" here. On my installment of this – I wanted only the first level of subnav pages visible, and then if you clicked on a subnav page that had child pages – then that list became visible. And if one of those pages had child pages – then that 3rd level of pages would be shown also (all the while keeping all the other sub nav for this section visible. When I get more time, I'll include screenshots to demonstrate what I'm talking about. In the meantime , I'm dumping the code here before I lose it again! LOL! Oh, also – I wanted to add some kind of indicator on the subnav links that showed there was navigation below it – like an + sign or something…

<script type="text/javascript" src="/js/jquery-1.3.1.min.js"></script>
<script type="text/javascript">
jQuery.noConflict();
jQuery(document).ready( function() {
jQuery('ul').parent('li').addClass("parentul");
});
</script>

That will find any unordered list that is WITHIN a list item – and apply the class "parentul" to the PARENT li item.

Then I used the following styles to hide the blocks that needed to be hidden, and show the "+" sign next to the linkts that had more subnav items below them:

#sidebar .current_page_ancestor ul,
#sidebar .current_page_item ul,
#sidebar .current_page_ancestor.current_page_parent .current_page_item ul,
#sidebar .current_page_ancestor.current_page_parent ul {
display: block;
}
#sidebar .current_page_item ul ul,
#sidebar .current_page_ancestor.current_page_parent ul ul,
#sidebar ul ul ul {
display: none;
}
#sidebar ul li,
#sidebar ul li ul li,
#sidebar ul li ul li ul li {
padding-left: 8px;
}
#sidebar ul li.parentul {
background:url(images/more.gif) 0 3px no-repeat;
}

The "more.gif" was my + sign.

Just to clarify more… Here are the screenshots:

This is the default view of wp_list_pages:
picture-11

Here is what the code above will do:

If there is no subnav pages under the section we're in – no subnav is displayed…
picture-71

picture-41
In this view, we're in the "about" section – on the "What we do" page… notice that you're seeing only the subnav pages under "about", and the pages under "why you want to hire us" are collapsed with the + sign (my "more.gif" in front of the link…

picture-5
Now we're on the "why you want to hire us" page – so the subnav under that page are revealed.

picture-8
Now we're on a subnav of a subnav … the "our prices" page under "why you want to hire us" (in the About section)

I tweaked the stylesheets a bit for these screenshots. You'll have to play with it to suit your needs. For the screenshots, I wanted to bold the section we're in in the main nav, and the subnav page, as well as the subnav page, and subnav "parent" page… Here's the styles I used to do that:

#sidebar .current_page_ancestor ul,
#sidebar .current_page_item ul,
#sidebar .current_page_ancestor.current_page_parent .current_page_item ul,
#sidebar .current_page_ancestor.current_page_parent ul {
display: block;
}
#sidebar .current_page_item ul ul,
#sidebar .current_page_ancestor.current_page_parent ul ul,
#sidebar ul ul ul {
display: none;
}
#sidebar ul li,
#sidebar ul li ul li,
#sidebar ul li ul li ul li {
padding-left: 8px;
}
#sidebar ul li.parentul {
background: none;
}
#sidebar ul ul li.parentul {
background:url(images/more.gif) 0 3px no-repeat;
}
#sidebar .current_page_parent li,
#sidebar .current_page_item li {
font-weight: normal;
}
#sidebar li.current_page_ancestor,
#sidebar li.current_page_item {
font-weight: bold;
}

Featured Sponsors


  • Michael: You can use get_header(2) in your case. The filename of your custom header has to be header-2.php. The problem with include(your_file.php) is, all
  • cliff: hi wonder if you can help me, pls i designed www.kouga.mobi using dreamweaver CS3 and now want to make the phonenumbers into links so that if you
  • jerey: how do i rewrite this because it tried RewriteEngine on #Options +FollowSymlinks RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FIL

About


Advertisements