Contribute to the DSpace Development Fund

The newly established DSpace Development Fund supports the development of new features prioritized by DSpace Governance. For a list of planned features see the fund wiki page.

Tagging DSpace records by users

The goal of this patch is to add the possibility to tag DSpace records with words proposed by users.

It is based on a previous patch that Desmond Elliott proposed to bookmark records.

It is for DSpace 1.4.2 JSP UI only but it should not be too difficult to port it to newer DSpace versions.

For the users:

  • multiple tags can be added to any displayed item by any logged in user: 
  • in MyDSpace, the tags of the logged-in user are listed with their frequency. Clicking on any word brings the list of the items tagged with this word:
  • In the left navigation bar, a "Tag" entry can appear. It gives access to the tags owned by the user but also to the tags of all the other users (collaborative tagging)
  • a special tag "v" (viewed) is used to simply tick records. This special tag can be set/reset directly from a result list or from the top of a record.

For the application manager:

In dspace/config/dspace.cfg, you can define:

# "v" is recommended as a tag for "ticked" records:

webui.itemlist.tagviewed = v

# HTML code to show that a record is ticked (and can be unticked)
webui.itemlist.viewed = <a href="[root]/handle/[handle]?bookmarkremoved=v[framed]"[targetbibl_record]><img src="[root]/image/viewed.gif" border="0" align="left"/></a>

# HTML code to show that a record is unticked (and can be ticked)
webui.itemlist.notviewed = <a href="[root]/handle/[handle]?bookmarkadded=v[framed]"[targetbibl_record]><img src="[root]/image/notviewed.gif" border="0" align="left"/></a>

Icons:

  • You need one icon for "viewed" records (image/viewed.gif). Something looking like a tick mark in a colored circle.
  • You need another one for unticked (but tickable). Something like an empty colored circle
  • Examples are attached for testing but I ask you to use your own.

In Messages.properties, you add:

jsp.display-item.bookmark = Record My Tags
jsp.mydspace.bookmarks.info1                                    = Your tags have been updated.
jsp.mydspace.bookmarks.info2                                    = To tag an item, visit the item's page, put in Tag terms separated by ";" and click on the "My Tags" button.
jsp.mydspace.bookmarks.info3                                    = Below are the items tagged
jsp.mydspace.bookmarks.info4                                    = You have not tagged any items.
jsp.mydspace.bookmarks.theirs                                   = Their Tags
jsp.mydspace.bookmarks.title                                    = Tags
jsp.mydspace.bookmarks.yours                                    = Your Tags
jsp.mydspace.main.bookmarks.link                                = Click on one of your Tags:
jsp.layout.navbar-default.tags = Tags

For the developpers:

in the PostgreSQL database:

A new database table must be added:

CREATE SEQUENCE bookmark_seq
  INCREMENT 1
  MINVALUE 1
  MAXVALUE 9223372036854775807
  START 1
  CACHE 1;
ALTER TABLE bookmark_seq OWNER TO <<<Put here the right PostgreSQL user as the table owner>>>;

CREATE TABLE bookmark
(
  bookmark_id integer NOT NULL DEFAULT nextval('bookmark_seq'::regclass),
  eperson_id integer,
  item_id integer,
  tag_value character varying(128),
  CONSTRAINT bookmark_pkey PRIMARY KEY (bookmark_id),
  CONSTRAINT bookmark_eperson_id_fkey FOREIGN KEY (eperson_id)
      REFERENCES eperson (eperson_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT bookmark_item_id_fkey FOREIGN KEY (item_id)
      REFERENCES item (item_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (OIDS=FALSE);
ALTER TABLE bookmark OWNER TO <<<Put here the right PostgreSQL user as the table owner>>>;
CREATE INDEX bookmark_idx1
  ON bookmark
  USING btree
  (eperson_id);
CREATE INDEX bookmark_idx2
  ON bookmark
  USING btree
  (item_id);
CREATE INDEX bookmark_idx3
  ON bookmark
  USING btree
  (md5(tag_value::text));

In the Java Code:

New classes (java files attached to this page):

  • org.dspace.eperson.BookmarkManager
  • org.dspace.eperson.Tag
  • org.dspace.app.webui.servlet.BookmarkServlet
  • org.dspace.app.webui.servlet.ListTagsServlet

Modified classes:

In org.dspace.app.webui.jsptag.ItemListTag:

At the beginning of "getThumbMarkup", you can add the display of the "viewed" tag in search result lists:

    /* generate the (X)HTML required to show the thumbnail */
    private String getThumbMarkup(HttpServletRequest hrq, Context c, Item item, String suffix)
            throws JspException
    {
        String handle = item.getHandle();
        Bundle[] original = null;
        String tag = "";
        String tagVu = ConfigurationManager.getProperty("webui.itemlist.tagviewed");
        String htmlVu = ConfigurationManager.getProperty("webui.itemlist.viewed");
        String htmlNotVu = ConfigurationManager.getProperty("webui.itemlist.notviewed");
        String vu = "";

        EPerson eperson = c.getCurrentUser();
        if (eperson != null) {
           tag = BookmarkManager.getBookmarkTag(c,eperson,item);
           if (tag != null && (!"".equals(tag))) {
              if ( tag.startsWith(tagVu+";") || (tag.indexOf("; "+tagVu+";")>=0) )
                vu = htmlVu;
              tag = " "+UIUtil.addLinksURL(hrq.getContextPath()+"/bookmark?tag=",";",tag);
           }
           if ("".equals(vu)) vu = htmlNotVu;
        }

        Collection colls[] = null;
        try
        {
        	original = item.getBundles("ORIGINAL");
                colls = item.getCollections();
        }
        catch(SQLException sqle)
        {
        	throw new JspException(sqle.getMessage());
        }
...

in Java Server Pages (JSP):

New JSPs (attached to this page):

  • mydspace/listtags.jsp
  • mydspace/bookmarks.jsp

Modified JSPs:

in navbar-default.jsp
... You can add where you want the option of listing tags of everybody:
  <tr class="navigationBarItem">
    <td>
      <img alt="" src="<%= request.getContextPath() %>/image/<%= ( currentPage.endsWith( "/browse-tags" ) ? "arrow-highlight" : "arrow" ) %>.gif" width="16" height="16"/>
    </td>
    <td nowrap="nowrap" class="navigationBarItem">
      <a href="<%= request.getContextPath() %>/browse-tags"><fmt:message key="jsp.layout.navbar-default.tags"/></a>
    </td>
  </tr>
in display-item.jsp:
... Imports...
<%@ page import="org.dspace.eperson.BookmarkManager" %>
... Initialization...
    // Show Bookmark or Unbookmark button?
    String bookmarked = "";
	// Marked as viewed?
    boolean vu = false;
    if (currentUser != null) {
        bookmarked = BookmarkManager.getBookmarkTag(context, currentUser, item);
        if (bookmarked != null && (!"".equals(bookmarked))) {
              if ( bookmarked.startsWith("v;") || (bookmarked.indexOf("; v;")>=0) )
                vu = true;
        }
    }
    String otherBookmark = BookmarkManager.getBookmarkOtherTag(context, currentUser, item);
... Where you want to display "ticked" records:
<%
    if (currentUser != null) {
      if (vu) {
%>
		<a href="<%= locationLink %>?bookmarkremoved=v"><img src="<%= request.getContextPath() %>/image/viewed.gif" border="0"/></a>
<%
	  } else {
%>
		<a href="<%= locationLink %>?bookmarkadded=v"><img src="<%= request.getContextPath() %>/image/notviewed.gif" border="0"/></a>
<%
	  }
%>
... Where you want to display current tags:
<%
    if (bookmarked != null && (! "".equals(bookmarked))) { %>
      <b style="color:Orange;"><fmt:message key="jsp.mydspace.bookmarks.yours"/>: <%=UIUtil.addLinksURL(request.getContextPath()+"/bookmark?tag=",";",bookmarked)%></b>
<%  }
    if (otherBookmark != null && (! "".equals(otherBookmark))) { %>
      <fmt:message key="jsp.mydspace.bookmarks.theirs"/>: <%=UIUtil.addLinksURL(request.getContextPath()+"/bookmark?allusers=on&tag=",";",otherBookmark)%>
<%  } %>
... Where you want to edit current tags:
	<form method="get" action="<%= locationLink %>" style="display:inline;">
        <fmt:message key="jsp.mydspace.bookmarks.yours"/>: <input size=20 name="bookmarked" value="<%=bookmarked%>" />
        <input type="submit" name="Bookmark-Flag" value="<fmt:message key="jsp.display-item.bookmark"/>"/>
<% if (otherBookmark != null && (!"".equals(otherBookmark))) { %>
        <br/><fmt:message key="jsp.mydspace.bookmarks.theirs"/>: <%=otherBookmark%>
<% } %>
        </form>
in mydspace/main.jsp (where you want to display user's tags):
... Imports...
<%@ page import="org.dspace.eperson.BookmarkManager" %>
... Initialization...
    Context context = UIUtil.obtainContext(request);
    Map taglist = null;
    if (user != null) taglist = BookmarkManager.getBookmarkTags(context,user);
%>
... Display:
 <%
if (taglist != null) {
%>
    <li><a href="<%= request.getContextPath() %>/bookmark"><fmt:message key="jsp.mydspace.main.bookmarks.link"/></a>
    <ul>
<%
        Iterator curTag = taglist.keySet().iterator();
        while (curTag.hasNext())
        {
          String aTag = (String) curTag.next();
          Integer aFreq = (Integer) taglist.get(aTag);
        %><li><a href="<%= request.getContextPath() %>/bookmark?tag=<%= aTag %>"><%=aTag%> (<%=aFreq.intValue()%>)</a></li><%
        }
%>  </ul></li>
<%
}
%>

in WEB-INF/web.xml:

You must add the definitions for the two new servlets (tagging servlet and tags list servlet):

...
    <servlet>
        <servlet-name>browse-tags</servlet-name>
        <servlet-class>org.dspace.app.webui.servlet.ListTagsServlet</servlet-class>
    </servlet>
  <servlet>
    <servlet-name>bookmark</servlet-name>
    <servlet-class>org.dspace.app.webui.servlet.BookmarkServlet</servlet-class>
  </servlet>
...
    <servlet-mapping>
        <servlet-name>browse-tags</servlet-name>
        <url-pattern>/browse-tags</url-pattern>
    </servlet-mapping>
   <servlet-mapping>
      <servlet-name>bookmark</servlet-name>
      <url-pattern>/bookmark</url-pattern>
  </servlet-mapping>
...  


For any help, I check the DSpace Developpers list often.

Good luck!

Christophe Dupriez

  • No labels