Archive for the 'tutorial' Category

GrailsUI Component Accessibility Example: Switching Tabs in TabView

Monday, November 10th, 2008

Recently, someone asked a very good question on the Grails mailing lists about GrailsUI. How can someone add a button within each tab in a tabView that switches to the next tab? Well, there is nothing within the GrailsUI API that allows such custom behavior, so it’s not like you can just add addButtonToEachTabThatNavigatesToTheNextButton=”true” to the tabView attributes ;).

But there definitely is a way to access the YUI TabView component that the GrailsUI tabView tag creates. And if you can access this component and you refer to the YUI API for TabView, it turns out to be pretty easy to hook up this functionality.

For this example, lets create a simple tabbed pane with tabView first, then we’ll put buttons in each tab that will activate the next tab within the pane.

Initial tabView
<gui:tabView id="myTabView">
<gui:tab label="tab 0" active="true">
<h2>TAB at index 0</h2>
</gui:tab>
<gui:tab label="tab 1">
<h2>TAB at index 1</h2>
</gui:tab>
<gui:tab label="tab 2">
<h2>TAB at index 2</h2>
</gui:tab>
<gui:tab label="tab 3">
<h2>TAB at index 3</h2>
</gui:tab>
</gui:tabView>

This produces a plain old tab view:

POTV

We want to put a button within each tab that will switch to the next tab, so let’s add the buttons with unique ids:

TabView with buttons
<gui:tabView id="myTabView">
<gui:tab label="tab 0" active="true">
<h2>TAB at index 0</h2>
<button id='button0' value='1' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 1">
<h2>TAB at index 1</h2>
<button id='button1' value='2' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 2">
<h2>TAB at index 2</h2>
<button id='button2' value='3' type='button'>Next</button>
</gui:tab>
<gui:tab label="tab 3">
<h2>TAB at index 3</h2>
<button id='button3' value='0' type='button'>Next</button>
</gui:tab>
</gui:tabView>

Now each tab has a button that we want to activate the next tab, but it does nothing. Note the value of each button is the index of the tab it should activate.

TabView with buttons

Nothing special yet… but now we get to the component accessibility portion of the tutorial.

You, as a GrailsUI user, have direct access to the YUI components that are created behind the scenes for you by the plugin. You can directly manipulate these objects after they are created, including adding event listeners, changing attributes, re-rendering, etc. This concept is called Component Accessibility, and is explained like this in the GrailsUI Docs:
Each YUI component that is created can be referenced via JavaScript in other areas of the page. This allows users to create event listeners to trigger custom actions. If an ‘id’ attribute is passed along to the component tag, this can be used to access the YUI component.

What we need to do now is add event listeners to the buttons we created that will select specific tabs on the YUI TabView object that GrailsUI created for us. So after our declaration, we need to get down-and-dirty with some JavaScript. This can go anywhere in the page within script tags, because I’m wrapping it in the YUI onDOMReady function (see here for more info).

JavaScript to activate the buttons
YAHOO.util.Event.onDOMReady(function(){
var buttons = ['button0','button1','button2','button3'];
for (i in buttons) {
YAHOO.util.Event.on(buttons[i], ‘click’, function(e) {
GRAILSUI.myTabView.set(’activeIndex’, e.target.value);
});
};
});

This little script is looping through the button ids and attaching an even listener to each. On click, the code within this listener will be evaluated. The important line is GRAILSUI.myTabView.set(’activeIndex’, e.target.value);, because this is where we access the YUI TabView directly. When this line is executed within the listener, the tabView active index it set by the value of the button.

That’s it. Pretty simple, really. Yes, you do have to get you hands a little dirty with some JavaScript, but if you are a UI developer nowadays, JavaScript is a pretty sharp tool in your toolbox. So get used to it ;).


Adding Row Expansion to the GrailsUI dataTable

Sunday, November 2nd, 2008

One of the coolest features of the GrailsUI dataTable is its ability to turn on row expansion. In order to have enough data to do this, we need to know a URL for the dataTable to load on row click. We also need to turn the rowExpansion feature on in the tag. Let’s continue using the example I set up in my last post about using the GrailsUI dataTable tag. We’ll expand on it and I’ll link the new source code at the bottom of this post.

First off, turning on rowExpansion in the tag is easy enough.

dataTable with rowExpansion on
<gui:dataTable
controller="book" action="dataTableJSON"
columnDefs="[
[key:'name', label:'Name', sortable: true, resizeable: true],
[key:'isbn', label:'ISBN', sortable: true, resizeable: true],
[key:'author', label:'Author', sortable: true, resizeable: true],
[key:'publishDate', label:'Published on', sortable: true, resizeable: true]
]"
sortedBy="name"
draggableColumns="true"
rowsPerPage="12"
paginatorConfig="[
template:'{PreviousPageLink} {PageLinks} {NextPageLink} {CurrentPageReport}',
pageReportTemplate:'{totalRecords} total records'
]"
rowExpansion="true"
/>

The real work is in setting up and passing the dataUrl in the controller action that serves the dataTable:

dataTableJSON with dataURL passing
def dataTableJSON = {
def books = Book.list(params)
// let's convert our book list into an array of maps so we can format
// each value exactly as we want...
def formattedBooks = books.collect {
[
name: it.name,
isbn: it.isbn,
publishDate: new java.text.SimpleDateFormat("MMM dd, yyyy").format(it.publishDate),
author: it.author.name,
dataUrl: g.createLink(action:'bookDetail', id:it.id)
]
}
def data = [
totalRecords: Book.count(),
results: formattedBooks
]
render data as JSON
}

The dataTable will only enable row expansion if it finds a ‘dataUrl’ field in the JSON data that populates it. Our controller is now creating a URL that will be called by the dataTable on row click to populate the new expanded element.

Only problem is that we don’t have a bookDetail action yet. We want to add a bookDetail action that will serve up the HTML to display in the row expansion. So let’s take our ’show’ page and break out a template to show the book detail.

_bookDetail.gsp
<table>
<tbody>
<tr class="prop">
<td valign="top" class="name">Id:</td>
<td valign="top" class="value">${fieldValue(bean:book, field:'id')}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Author:</td>
<td valign="top" class="value"><g:link controller="author" action="show"
id="${book?.author?.id}">${book?.author?.encodeAsHTML()}</g:link></td>
</tr>
<tr class="prop">
<td valign="top" class="name">Isbn:</td>
<td valign="top" class="value">${fieldValue(bean:book, field:'isbn')}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Name:</td>
<td valign="top" class="value">${fieldValue(bean:book, field:'name')}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Publish Date:</td>
<td valign="top" class="value">${fieldValue(bean:book, field:'publishDate')}</td>
</tr>
</tbody>
</table>

And now we can render the book to this template from our bookDetail controller action:

BookController.bookDetail
def bookDetail = {
render(template:"bookDetail", model:[book:Book.get(params.id)])
}

Add a little CSS to change the row expansion background and text colors in list.gsp:

Style update in list.gsp
<style>
tr.ymod-expandedData div.ymod-expandedDataContent td {
background: #FFF;
color: #000;
}
</style>

And we have dataTable with a rowExpansion that calls a controller method that renders detailed info in a template. Click on any row, and it will expand to show whatever is rendered in the bookDetail action. Click the row again to hide the expansion. Any sorting or pagination will force the expansion to close.

DataTable with Row Expansion

Here is the row expansion demo source code. Just unzip it, then run:

grails upgrade
grails install-plugin yui
grails install-plugin bubbling
grails install-plugin grails-ui
grails run-app

Using GrailsUI dataTable tag

Sunday, November 2nd, 2008

The GUI dataTable is the most complicated tag to set up, because there is a lot of data configuration required. You have to correctly set up the column definitions in the tag, and you have to set up the controller to serve up the proper data.

Let’s start from scratch with the basic book / author demo.

Book.groovy
class Book {
String name
String isbn
static belongsTo = [author:Author]
Date publishDate
}

We want a to create a dataTable tag that will display all the Books I loaded up in Bootstrap.groovy. First off, since we know we’ll be using a dataTable GUI tag in our page, we need to declare this to the resources tag in the page head element. The resources tag will include all the YUI CSS and JavaScript files it knows it will need to build a dataTable.

Resources tag in HEAD
<gui:resources components="['dataTable']"/>

Now for the dataTable tag. We’ll set up something basic first.

Initial dataTable tag
<div class="yui-skin-sam">
<gui:dataTable
controller="book" action="dataTableJSON"
columnDefs="[
[key:'id', label:'ID'],
[key:'name', label:'Name'],
[key:'isbn', label:'ISBN'],
[key:'author', label:'Author'],
[key:'publishDate', label:'Published on']
]"
/>
</div>
Note that I’ve wrapped this whole tag in a div with the yui-skin-sam class. This is necessary if I want to take advantage of the default YUI skin. If you want another skin, it can all be provided in local CSS.

So our dataTable is now expecting at least five fields for each row of data it receives: id, name, isbn, author, and publishDate. We need to set up a controller action that will serve this data in JSON format for us. In the dataTable tag, I’ve already decided the action will be called ‘dataTableJSON’, so let’s code it.

Initial dataTableJSON action
def dataTableJSON = {
def books = Book.list(params)
def data = [
totalRecords: Book.count(),
results: books
]
render data as JSON
}

The dataTable will be calling this method to populate itself with data, so the params will be the dataTable’s filtering information, like how to sort, where to start, etc. The GUI dataTable knows only to send params that can be understood by the Grails list domain class function, so we can just send the params directly into Book.list(params).

By default, the GUI dataTable expects there to be a piece of metaData called “totalRecords” that contains the total amount of records in the entire possible dataset that could be displayed by the table. This is necessary to calculate how many pages of data there are in order to render the pagination controls. If this totalRecords is absent or incorrect, the dataTable pagination will not work properly.

The totalRecords must be the total count of records that might be displayed in the table, not the total count of records that is being passed back by the action.

In the data map above, the ‘results’ key is where the dataTable will look by default for its data. This can be changed in the dataTable tag. For example, if you added resultsList=”myResults” in the dataTable tag, and changed the controller action to return myResults: list instead of results: list, things would work fine.

At this point, we should have something that looks very much like this:

Initial Data Table

Not bad, but that date looks nasty because it is handled as a String (there is no type formatting in the dataTable yet). And I would really rather see the Author name rather than id. Also, we don’t really want to see the Book id in the table either. So we’re going to have to dig into our controller and take a firmer grip on how the JSON is being created from our domain class.

dataTableJSON action w/ custom formatting
def dataTableJSON = {
def books = Book.list(params)
// let's convert our book list into an array of maps so we can format
// each value exactly as we want...
def formattedBooks = books.collect {
[
name: it.name,
isbn: it.isbn,
publishDate: new java.text.SimpleDateFormat("MMM dd, yyyy").format(it.publishDate),
author: it.author.name
]
}
def data = [
totalRecords: Book.count(),
results: formattedBooks
]
render data as JSON
}

At this point, we are in total control of the JSON being produced. Grails isn’t converting our domain objects into JSON anymore. We added a custom date format, and we drilled down into the Author to get a name. We also omitted the id field, so we’ll have to go into our tag and omit the id field in the column definitions. If the id field was left in the tag’s columnDefs, there would be an empty column in the table. While we are at it, let’s make all the columns sortable, resizeable, and draggable.

dataTable tag, sortable, resizeable, draggable, & without id
<div class="yui-skin-sam">
<gui:dataTable
controller="book" action="dataTableJSON"
columnDefs="[
[key:'name', label:'Name', sortable: true, resizeable: true],
[key:'isbn', label:'ISBN', sortable: true, resizeable: true],
[key:'author', label:'Author', sortable: true, resizeable: true],
[key:'publishDate', label:'Published on', sortable: true, resizeable: true]
]"
sortedBy="name"
draggableColumns="true"
/>
</div>

Notice that the id column definition is removed, sortable and resizeable were added to each column def, draggableColumns is on, and we added a sortedBy attribute.

The GUI dataTable is sorted by id by default. Because we just removed the id from the column definition, we must explicitly announce how the dataTable should sort upon first render, so the sortedBy=’name’ is absolutely necessary.

Now our table looks like this:

DataTable after some formatting

But there is no mention anywhere of how many total records there are! Sure, you can see how many pages, how many rows per page, and do the math, but who wants to do that? So now lets say we want to display 12 rows per page, and show the total amount of records. Well, this doesn’t have anything to do with our data, so the controller action that provides the data will be fine as it is. But we do need to specify some more information to the tag on how to render the paginator.

dataTable tag, sortable, resizeable, draggable, & without id
<div class="yui-skin-sam">
<gui:dataTable
controller="book" action="dataTableJSON"
columnDefs="[
[key:'name', label:'Name', sortable: true, resizeable: true],
[key:'isbn', label:'ISBN', sortable: true, resizeable: true],
[key:'author', label:'Author', sortable: true, resizeable: true],
[key:'publishDate', label:'Published on', sortable: true, resizeable: true]
]"
sortedBy="name"
draggableColumns="true"
rowsPerPage="12"
paginatorConfig="[
template:'{PreviousPageLink} {PageLinks} {NextPageLink} {CurrentPageReport}',
pageReportTemplate:'{totalRecords} total records'
]"
/>
</div>

So we’ve added rowsPerPage, and a paginatorConfig. The rowsPerPage is really a paginatorConfig value, but for the convenience of not having to define the paginatorConfig only for setting rowsPerPage, it was opened up as a main attribute. All the paginatorConfig values are passed through to the dataTable’s YUI Paginator object upon creation. More information on Paginator templates can be found on the YUI Paginator page.

Now we should have a 12-row table with total records displayed:

Final Data Table

And there you go. Sortable, resizeable, draggable columns, with a total record count and customized data formatting. If you want to have a hands-on look, here is the source code. Just unzip it, then run:

grails upgrade
grails install-plugin yui
grails install-plugin bubbling
grails install-plugin grails-ui
grails run-app

Mapping Java 5 enums with Hibernate

Sunday, September 23rd, 2007

Hibernate is used to map java objects to a relational database. Ideally, you would like your java object model to be as object-oriented as possible. It is also nice to be able to use features like java 5 enums while coding the object model. In this tutorial, I’ll share with you how I ended up mapping a simple object model using java 5 enums into Hibernate.

I’ve found the best way to jumpstart yourself into using Hibernate is to go through the official tutorial on the Hibernate site.

A Simple Example

I have a Beer object that corresponds directly to a BEER table in a database. The Beer object can wither be an “Ale” or a “Lager”, and there may be more types in the future. So the database schema looks like this:

Simple Beer schema
+--------------------+
| BEER               |
+--------------------+           +----------------+
| NUMBER  | ID       |           | BEER_TYPE      |
| VARCHAR | BRAND    |           +----------------+
| NUMBER  | TYPE     | FK------- | NUMBER  | ID   |
| NUMBER  | VOLUME   |           | VARCHAR | NAME |
+--------------------+           +----------------+

It is pretty straightforward how to create a java class to represent this data. Ideally, I would like to use a java 5 enum object to keep track of the beer type, so I use it within my data object to specify type:

Beer Data Object
public class Beer {
    private BeerType type;
    private String brand;
    private double volume;

    public BeerType getType() {
        return type;
    }

    public void setType(BeerType type) {
        this.type = type;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public double getVolume() {
        return volume;
    }

    public void setVolume(double volume) {
        this.volume = volume;
    }
}

The BeerType enum will simply specify the type of beer for each Beer object. This enum is going to map directly to the BEER_TYPE table. So I’ve given each beer type its own id through the private internal enum constructor. There is an accessor method for hibernate to retrieve the id when it needs to do the mapping.

BeerType enum
public enum BeerType {
    UNKNOWN(0), ALE(1), LAGER(2);

    private int id;

    private BeerType(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

}

One of the first things I found when I started searching the internet for ways to map Java 5 enums to a database using Hibernate was this article on the Hibernate page. It shows an implementation of the Hibernate UserType in a way that will allow an enum to be used within a hibernate key mapping. So if I create a custom type definition in the key-mapping that uses the GenericEnumUserType class as the class, and passes in the actual BeerType enum classpath as a parameter, I can do the work to break out the enum details in the GenericEnumUserType implementation.

Hibernate key-mapping for Beer
<hibernate-mapping>
    <typedef class="net.dangertree.GenericEnumUserType" name="beerType">
        <param name="enumClassName">net.dangertree.BeerType</param>
        <param name="identifierMethod">getId</param>
    </typedef>

    <class name="net.dangertree.Beer" table="BEER">
        <id name="id" type="int" column="ID">
            <generator class="native"/>
        </id>
        <property name="type" type="beerType" column="TYPE"/>
        <property name="brand" type="string" column="BRAND"/>
        <property name="volumn" type="double" column="VOLUME"/>
    </class>
</hibernate-mapping>

Here is the full code for the GenericEnumUserType class that I used to help map my enums into Hibernate. Reflection is used to find an “identifier” method in the enum that will get the id for each value. I have specified in the type-def in my key mapping that I’m going to use the getId() method of my enum to get an identifying attribute. By default, the class will look for the inherent name method of enum, but I’m using ids as my identifier.

The two method objects are grabbed and saved, then called in the null-safe setter and getter deeper within the Hibernate workings.

This class implementation of UserType is not exactly the same as any of those listings on the hibernate article I mentioned earlier. I had to make several minor changes to get it working with this code.
Generic Enum UserType implementation
import org.hibernate.HibernateException;
import org.hibernate.type.NullableType;
import org.hibernate.type.TypeFactory;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class GenericEnumUserType implements UserType, ParameterizedType {
    private static final String DEFAULT_IDENTIFIER_METHOD_NAME = “name”;
    private static final String DEFAULT_VALUE_OF_METHOD_NAME = “valueOf”;

    private Class enumClass;
    private Class identifierType;
    private Method identifierMethod;
    private Method valueOfMethod;
    private NullableType type;
    private int[] sqlTypes;

    public void setParameterValues(Properties parameters) {
        String enumClassName = parameters.getProperty(”enumClassName”);
        try {
            enumClass = Class.forName(enumClassName).asSubclass(Enum.class);
        } catch (ClassNotFoundException cfne) {
            throw new HibernateException(”Enum class not found”, cfne);
        }

        String identifierMethodName = parameters.getProperty(”identifierMethod”,
            DEFAULT_IDENTIFIER_METHOD_NAME);

        try {
            identifierMethod = enumClass.getMethod(identifierMethodName,
                new Class[0]);
            identifierType = identifierMethod.getReturnType();
        } catch (Exception e) {
            throw new HibernateException(”Failed to obtain identifier method”,
                e);
        }

        type = (NullableType) TypeFactory.basic(identifierType.getName());

        if (type == null)
            throw new HibernateException(”Unsupported identifier type ”
                + identifierType.getName());

        sqlTypes = new int[] { type.sqlType() };

        String valueOfMethodName = parameters.getProperty(”valueOfMethod”,
            DEFAULT_VALUE_OF_METHOD_NAME);

        try {
            valueOfMethod = enumClass.getMethod(valueOfMethodName,
                new Class[] { identifierType });
        } catch (Exception e) {
            throw new HibernateException(”Failed to obtain valueOf method”, e);
        }
    }

    public Class returnedClass() {
        return enumClass;
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        Object identifier = type.get(rs, names[0]);
        if (rs.wasNull()) {
            return null;
        }

        try {
            return valueOfMethod.invoke(enumClass, new Object[] { identifier });
        } catch (Exception e) {
            throw new HibernateException(”Exception while invoking ”
                + “valueOf method ‘” + valueOfMethod.getName() + “‘ of ”
                + ”enumeration class ‘” + enumClass + “‘”, e);
        }
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index)
            throws HibernateException, SQLException {
        try {
            if (value == null) {
                st.setNull(index, type.sqlType());
            } else {
                Object identifier = identifierMethod.invoke(value,
                    new Object[0]);
                type.set(st, identifier, index);
            }
        } catch (Exception e) {
            throw new HibernateException(”Exception while invoking ”
            + “identifierMethod ‘” + identifierMethod.getName() + “‘ of ”
            + ”enumeration class ‘” + enumClass + “‘”, e);
        }
    }

    public int[] sqlTypes() {
        return sqlTypes;
    }

    public Object assemble(Serializable cached, Object owner)
            throws HibernateException {
        return cached;
    }

    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return x == y;
    }

    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    public boolean isMutable() {
        return false;
    }

    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }
}

Ok, there is only one problem now. The DEFAULT_VALUE_OF_METHOD_NAME method is specified by default to be valueOf, and I have not provided a parameter to override that in the type-def. So in order for my enum to match this, I need to add a valueOf method to my enum. And when the nullSafeGet method calls the “valueOfMethod“, it sends it an identifier as a parameter, so our valueOf method needs to take an int id as a parameter.

Modified BeerType enum
public enum BeerType {
    UNKNOWN(0), ALE(1), LAGER(2);

    private int id;

    private BeerType(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public static BeerType valueOf(int id) {
        switch (id) {
            case 1: return ALE;
            case 2: return LAGER;
            default: return UNKNOWN;
        }
    }
    
}

Now I have my data object, the enum it is using, my key-mapping, and an implementation of UserType that provides a way to access the enum through a type-def element in the key-mapping.

It’s all working for me now! Does anyone have any questions or comments? This is the very first time that I have interacted with hibernate, so I’m a little bit shaky with the details (especially the UserType implementation).

Edit: correction of mapping file pointed out by commenters.


Adding Digg integration to Wordpress

Saturday, June 2nd, 2007

I just added Digg links to all my Wordpress posts on this page, and it was really easy. Here is a quick tutorial on how to do it yourself, just in case you don’t want to muddle through it yourself.

First, visit the Digg integration site where you’ll find what code snippets you need to add to your page. I’m going to list the code snippets that are available on their site today, but to ensure yours are up-to-date, you’ll want to go to their site and get the latest. There is good info on their page, but I’m going to show you specifically how to make the same graphic as you see on this post.

There is only one real complication: You want readers to be able to digg your posts from within the post’s permanent link page, or anywhere else it shows up in a list of posts. It is really easy to add a digg graphic to individual posts on their permanent link pages. Here is the Digg code snippet you will add:

<script src=”http://digg.com/tools/diggthis.js” type=”text/javascript”>
</script>

This snippet will digg the URL of the current page the browser if viewing, so it is only appropriate to be placed on a post’s permalink page. For example, take this entry. This entry’s permalink page is http://weblog.dangertree.net /2007/06/02/ adding-digg- integration-to- wordpress/. But you may be viewing it from the main index page or an archive. To edit the post’s permalink page, you need to edit a template file that handles your theme’s presentation. I use the Wordpress default theme, Kubrick, so I’ll show you how I did it with that theme. If you use another theme, you’ll have to decide where the best place to put your Digg graphic will be.

Open wp-content/themes/default/single.php. You can do with from your server or through the Wordpress admin site (Presentation section). If single.php is not editable, you’ll have to chmod it. I wanted my Digg graphic to float just to the right of the post title, so I encased it in a div tag. So my snippet now looks like this:

<div style=”float:right; padding:10px”>
<script src=”http://digg.com/tools/diggthis.js” type=”text/javascript”>
</script>
<div>

Then I placed it just before the heading containing the post title (search for “the_title”). This will float the Digg graphic at the same level as the post title on the right hand side.

Now if you want Digg graphics to show up on the main page and archive pages of your site for all the posts listed, it is just a little bit (but not much!) more complicated. Take a look at the Digg integration site again and see the example for “When the URL you wish dugg differs from the current webpage”. Here is the code snippet that you’ll use:

<div style=”float:right; padding:10px”>
<script type=”text/javascript”>
digg_url = ‘WEBSITE_URL’;
</script>
<script src=”http://digg.com/tools/diggthis.js” type=”text/javascript”>
</script>
<div>

Where you see WEBSITE_URL is where you’ll have to make Wordpress put the permalink URL to the post that is being viewed. We’re going to work on the archive page and the index page within the your theme directory. You will post the same code into both the archive.php and index.php files, and all you have to do with the code above is replace WEBSITE_URL with <?php the_permalink() ?>. This calls a php method in Wordpress that returns the current post’s permalink URL. It is that easy! So put that code wherever you want in both files, and you should be done!

Also, please Digg this entry to support this tutorial. Thanks!