<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dev.enekoalonso.com &#187; drupal</title>
	<atom:link href="http://dev.enekoalonso.com/tag/drupal/feed/" rel="self" type="application/rss+xml" />
	<link>http://dev.enekoalonso.com</link>
	<description>having fun with code</description>
	<lastBuildDate>Wed, 12 Oct 2011 21:40:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Got NFS working</title>
		<link>http://dev.enekoalonso.com/2010/02/06/got-nfs-working/</link>
		<comments>http://dev.enekoalonso.com/2010/02/06/got-nfs-working/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 06:19:27 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[exports]]></category>
		<category><![CDATA[fedora]]></category>
		<category><![CDATA[fedora11]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[nfs]]></category>
		<category><![CDATA[nfs4]]></category>
		<category><![CDATA[nfsserver]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=457</guid>
		<description><![CDATA[Well, last night I started reading about how to share the files folder of a Drupal installation on a site with multiple web servers. Seems like NFS is the right way to go (as long as your traffic doesn&#8217;t grow too much). Perfect for Spaniards.es, since I want to move from a 2 dedicated server [...]]]></description>
			<content:encoded><![CDATA[<p>Well, last night I started reading about how to share the files folder of a Drupal installation on a site with multiple web servers. Seems like NFS is the right way to go (as long as your traffic doesn&#8217;t grow too much). Perfect for Spaniards.es, since I want to move from a 2 dedicated server setup to a more flexible one where I can launch new web servers easily, almost on demand.</p>
<div class="geshi no bash">
<ol>
<li class="li1">
<div class="de1"><span class="co0"># Install NFS</span></div>
</li>
<li class="li1">
<div class="de1">yum -y <span class="kw2">install</span> rpcbind nfs-utils nfs-utils-lib system-config-nfs rsync</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># chkconfig nfs on</span></div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">/</span>sbin<span class="sy0">/</span>chkconfig nfs on</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">vi <span class="sy0">/</span>etc<span class="sy0">/</span>idmapd.conf</div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># [General]</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># Domain = spaniards.es</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># [Mapping]</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># Nobody-User = nfsnobody</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co0"># Nobody-Group = nfsnobody</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">service rpcidmapd restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&quot;/files/archivos &nbsp;/nfs4exports/archivos none bind 0 0&quot;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>fstab</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">mount</span> <span class="sy0">/</span>nfs4exports<span class="sy0">/</span>archivos</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&quot;/nfs4exports XXX.177.133.25(rw,insecure,no_subtree_check,nohide,fsid=0) XXX.177.136.14(rw,insecure,no_subtree_check,nohide,fsid=0)&quot;</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>exports</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&quot;/nfs4exports/archivos XXX.177.133.25(rw,insecure,no_subtree_check,nohide) XXX.177.136.14(rw,insecure,no_subtree_check,nohide)&quot;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>exports</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">su</span> -c <span class="st0">&quot;/usr/sbin/exportfs -rva&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="sy0">/</span>sbin<span class="sy0">/</span>service nfs restart</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;portmap:ALL&#39;</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;lockd:ALL&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;mountd:ALL&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;rquotad:ALL&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;statd:ALL&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.deny</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;portmap:XXX.177.133.25,XXX.177.136.14&#39;</span> <span class="sy0">&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.allow</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;lockd:XXX.177.133.25,XXX.177.136.14&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.allow</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;mountd:XXX.177.133.25,XXX.177.136.14&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.allow</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;rquotad:XXX.177.133.25,XXX.177.136.14&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.allow</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;statd:XXX.177.133.25,XXX.177.136.14&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>hosts.allow</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;LOCKD_TCPPORT=48620&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;LOCKD_UDPPORT=48620&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;MOUNTD_PORT=48621&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;STATD_PORT=48622&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;RQUOTAD=no&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
<li class="li1">
<div class="de1"><span class="kw3">echo</span> <span class="st0">&#39;RQUOTAD_PORT=48623&#39;</span> <span class="sy0">&gt;&gt;</span> <span class="sy0">/</span>etc<span class="sy0">/</span>sysconfig<span class="sy0">/</span>nfs</div>
</li>
</ol>
</div>
<p>At the end, setting up NFS is not that complicated, but it was my first time, so it took a while. Actually, I had everything working before I noticed, since, logged in as root, I couldn&#8217;t figure out why I wasn&#8217;t able to write to the nfs mounted directory, being this mounted as rw. Well, turns out that you shouldn&#8217;t do this as root, since <a href="http://lists.freebsd.org/pipermail/freebsd-questions/2005-October/101886.html">root access on nfs, once enabled does not require authentication</a>.</p>
<p>I&#8217;m not sure why there is a need to mount a bind directory on the nfs server, but I think it has to do with the NFS4 directory configuration.</p>
<p>I think I got all the information I needed between these two links:<br />
<a href="http://fconfig.wordpress.com/2006/08/17/setting-up-a-fedora-nfs-server/">http://fconfig.wordpress.com/2006/08/17/setting-up-a-fedora-nfs-server/</a><br />
<a href="http://fedorasolved.org/Members/renich/howtos/f7/en/nfsv4-fedora/?searchterm=nfs">http://fedorasolved.org/Members/renich/howtos/f7/en/nfsv4-fedora/?searchterm=nfs</a></p>
<p>Next step: set up the round robin load balancer: haproxy or dns?</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>January 31, 2010 -- <a href="http://dev.enekoalonso.com/2010/01/31/cloudservers-creating-a-new-web-server-with-httpd-php-memcached/" title="CloudServers: Creating a new web server with httpd, php &#038; memcached">CloudServers: Creating a new web server with httpd, php &#038; memcached</a> (1)</li><li>January 31, 2010 -- <a href="http://dev.enekoalonso.com/2010/01/31/cloudservers-creating-a-new-mysql-db-server/" title="CloudServers: Creating a new MySQL db server">CloudServers: Creating a new MySQL db server</a> (0)</li><li>January 30, 2010 -- <a href="http://dev.enekoalonso.com/2010/01/30/got-new-servers-on-rackspace-cloud/" title="Got new servers on Rackspace Cloud">Got new servers on Rackspace Cloud</a> (5)</li><li>May 12, 2011 -- <a href="http://dev.enekoalonso.com/2011/05/12/angry-birds-as-a-web-app/" title="Angry Birds as a Web App">Angry Birds as a Web App</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2010/02/06/got-nfs-working/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Un Navarro en California is back!</title>
		<link>http://dev.enekoalonso.com/2010/01/29/un-navarro-en-california-is-back/</link>
		<comments>http://dev.enekoalonso.com/2010/01/29/un-navarro-en-california-is-back/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 23:53:11 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[personal]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=429</guid>
		<description><![CDATA[Yeah baby, I&#8217;m back. I have restored the Drupal installation I had for my personal blog, kinda missed it a lot. Hopefully all the old links will still work. Visit: Un Navarro en California Related Posts:February 7, 2010 -- My current SVN setup (0)February 6, 2010 -- Got NFS working (0)August 8, 2009 -- Drupal: [...]]]></description>
			<content:encoded><![CDATA[<p>Yeah baby, I&#8217;m back. I have restored the Drupal installation I had for my personal blog, kinda missed it a lot. Hopefully all the old links will still work.<br />
Visit: <a href="http://enekoalonso.com/main">Un Navarro en California</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>February 7, 2010 -- <a href="http://dev.enekoalonso.com/2010/02/07/my-current-svn-setup/" title="My current SVN setup">My current SVN setup</a> (0)</li><li>February 6, 2010 -- <a href="http://dev.enekoalonso.com/2010/02/06/got-nfs-working/" title="Got NFS working">Got NFS working</a> (0)</li><li>August 8, 2009 -- <a href="http://dev.enekoalonso.com/2009/08/08/drupal-users-cant-access-content-node_access-gone-wild/" title="Drupal: users can&#8217;t access content! (node_access gone wild)">Drupal: users can&#8217;t access content! (node_access gone wild)</a> (0)</li><li>February 24, 2009 -- <a href="http://dev.enekoalonso.com/2009/02/24/upgrading-spaniards-to-drupal-6/" title="Upgrading Spaniards.es to Drupal 6">Upgrading Spaniards.es to Drupal 6</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2010/01/29/un-navarro-en-california-is-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drupal: users can&#8217;t access content! (node_access gone wild)</title>
		<link>http://dev.enekoalonso.com/2009/08/08/drupal-users-cant-access-content-node_access-gone-wild/</link>
		<comments>http://dev.enekoalonso.com/2009/08/08/drupal-users-cant-access-content-node_access-gone-wild/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 21:46:23 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[access]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[permissions]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=363</guid>
		<description><![CDATA[If you are having trouble with users accessing content, check out the node_access table and make sure all permissions are set properly. Unless you are using modules like Organic Groups which set the node access permissions by user, you will only need one row on that table, with user id 0: Restore permissions: TRUNCATE TABLE [...]]]></description>
			<content:encoded><![CDATA[<p>If you are having trouble with users accessing content, check out the node_access table and make sure all permissions are set properly. Unless you are using modules like Organic Groups which set the node access permissions by user, you will only need one row on that table, with user id 0:</p>
<p>Restore permissions:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">TRUNCATE</span> <span class="kw1">TABLE</span> node_access;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> node_access <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">0</span>, <span class="st0">&#39;all&#39;</span>, <span class="nu0">1</span>, <span class="nu0">0</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>October 12, 2011 -- <a href="http://dev.enekoalonso.com/2011/10/12/command-line-scripting-with-node-js/" title="Command line scripting with Node.js">Command line scripting with Node.js</a> (0)</li><li>October 1, 2010 -- <a href="http://dev.enekoalonso.com/2010/10/01/having-fun-with-node-js-redis/" title="Having fun with node.js &#038; Redis">Having fun with node.js &#038; Redis</a> (1)</li><li>February 18, 2010 -- <a href="http://dev.enekoalonso.com/2010/02/18/google-fiber-in-san-luis-obispo-that-would-be-awesome/" title="Google Fiber in San Luis Obispo? That would be awesome!">Google Fiber in San Luis Obispo? That would be awesome!</a> (0)</li><li>February 6, 2010 -- <a href="http://dev.enekoalonso.com/2010/02/06/got-nfs-working/" title="Got NFS working">Got NFS working</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2009/08/08/drupal-users-cant-access-content-node_access-gone-wild/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Upgrading Spaniards.es to Drupal 6</title>
		<link>http://dev.enekoalonso.com/2009/02/24/upgrading-spaniards-to-drupal-6/</link>
		<comments>http://dev.enekoalonso.com/2009/02/24/upgrading-spaniards-to-drupal-6/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 06:12:24 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[spaniards.es]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=279</guid>
		<description><![CDATA[Last Saturday I decided to upgrade Spaniards.es to Drupal 6. I&#8217;ve been waiting for a long time, since Drupal 6 came out, basically because this site uses a lot of modules which weren&#8217;t available yet for the new version. Recently drupal.org was also upgraded and that was a decisive point for me. It took me [...]]]></description>
			<content:encoded><![CDATA[<p>Last Saturday I decided to upgrade Spaniards.es to Drupal 6. I&#8217;ve been waiting for a long time, since Drupal 6 came out, basically because this site uses a lot of modules which weren&#8217;t available yet for the new version. Recently drupal.org was also upgraded and that was a decisive point for me.</p>
<p>It took me five hours to upgrade, but most of the process was making sure I had good backups copied on both servers but also downloaded to my personal computer. It takes a while to download a site like this!</p>
<p>Here is my log:</p>
<ol>
<li>Set Site Maintenance</li>
<li>Set .htaccess maintenance redirect</li>
<li>Stop MYSQL</li>
<li>Backup spdba_main</li>
<li>Backup public_html</li>
<li>Rename public_html to public_html_5.15</li>
<li>Create sym link to public_html: <code>ln -s public_html_5.15 public_html</code></li>
<li>Grab list of active modules <code>select filename, status from system where filename like '%.module' and status = 1;</code></li>
<li>Disable all non-core modules</li>
<li>Download Drupal 6.9</li>
<li>Delete sym link <code>rm public_html</code></li>
<li>Create sym link to Drupal 6 <code>ln -s drupal-6.9 public_html</code></li>
<li>Copy default.settings.php to settings.php</li>
<li>Update DB connection string</li>
<li>Process to upgrade Drupal: www.spaniards.es/update.php</li>
</ol>
<p>Once the DB was updated, it was a matter of installing all the modules and upgrading the DB when needed. Most of the staff worked fine. I had to do some fixes on my custom modules, specially for the new menu hooks.</p>
<p>Drupal 6 rocks.</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>February 6, 2010 -- <a href="http://dev.enekoalonso.com/2010/02/06/got-nfs-working/" title="Got NFS working">Got NFS working</a> (0)</li><li>January 29, 2010 -- <a href="http://dev.enekoalonso.com/2010/01/29/un-navarro-en-california-is-back/" title="Un Navarro en California is back!">Un Navarro en California is back!</a> (0)</li><li>August 29, 2009 -- <a href="http://dev.enekoalonso.com/2009/08/29/spaniards-for-iphone-available-now/" title="Spaniards for iPhone available now">Spaniards for iPhone available now</a> (0)</li><li>August 8, 2009 -- <a href="http://dev.enekoalonso.com/2009/08/08/drupal-users-cant-access-content-node_access-gone-wild/" title="Drupal: users can&#8217;t access content! (node_access gone wild)">Drupal: users can&#8217;t access content! (node_access gone wild)</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2009/02/24/upgrading-spaniards-to-drupal-6/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>vancode2int</title>
		<link>http://dev.enekoalonso.com/2009/02/24/vancode2int/</link>
		<comments>http://dev.enekoalonso.com/2009/02/24/vancode2int/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 05:52:01 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[comment]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[counter]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=277</guid>
		<description><![CDATA[vancode2int is a very simple but nice function I was looking for for a while and I had no idea Drupal included. It basically decodes the thread id of a comment in Drupal converting it back to an integer, which is very useful when displaying comments on a plain list, instead of on a threaded [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://api.drupal.org/api/function/vancode2int/6">vancode2int</a> is a very simple but nice function I was looking for for a while and I had no idea Drupal included. It basically decodes the thread id of a comment in Drupal converting it back to an integer, which is very useful when displaying comments on a plain list, instead of on a threaded conversation tree.</p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>December 14, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/" title="Keyboard shortcuts in Drupal: Navigating through comments">Keyboard shortcuts in Drupal: Navigating through comments</a> (2)</li><li>December 13, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part III">Ajax comments in Drupal 5: How I made it &#8211; Part III</a> (10)</li><li>December 11, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part II">Ajax comments in Drupal 5: How I made it &#8211; Part II</a> (0)</li><li>December 10, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/" title="Ajax comments in Drupal 5: How I made it &#8211; Part I">Ajax comments in Drupal 5: How I made it &#8211; Part I</a> (10)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2009/02/24/vancode2int/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keyboard shortcuts in Drupal: Navigating through comments</title>
		<link>http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/</link>
		<comments>http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 17:44:19 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[key]]></category>
		<category><![CDATA[keyboard]]></category>
		<category><![CDATA[keydown]]></category>
		<category><![CDATA[keyup]]></category>
		<category><![CDATA[shortcut]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=148</guid>
		<description><![CDATA[It was one of the best features of Google Reader and Google GMail: the keyboard shortcuts, specially the ones to navigate through messages or posts (n = next, p = previous). I decided it was time to implement it on spaniards.es, so here is the code I used. So far it only navigates through comments [...]]]></description>
			<content:encoded><![CDATA[<p>It was one of the best features of Google Reader and Google GMail: the keyboard shortcuts, specially the ones to navigate through messages or posts (n = next, p = previous).</p>
<p>I decided it was time to implement it on <a href="http://www.spaniards.es">spaniards.es</a>, so here is the code I used. So far it only navigates through comments back and forth on the same page (does not go to next page or so). I am planning to add other shortcuts soon.</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">$<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">keyup</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>event<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">target</span>.<span class="me1">tagName</span> == <span class="st0">&quot;INPUT&quot;</span> <span class="sy0">||</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; event.<span class="me1">target</span>.<span class="me1">tagName</span> == <span class="st0">&quot;TEXTAREA&quot;</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> selected = $<span class="br0">&#40;</span><span class="st0">&#39;.comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Next comment</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">keyCode</span> == <span class="nu0">78</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>selected.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected.<span class="me1">removeClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected = selected.<span class="me1">nextAll</span><span class="br0">&#40;</span><span class="st0">&#39;.comment:first&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected = $<span class="br0">&#40;</span><span class="st0">&#39;.comment:first&#39;</span><span class="br0">&#41;</span>.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>selected.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; window.<span class="me1">scrollTo</span><span class="br0">&#40;</span><span class="nu0">0</span>, selected.<span class="me1">offset</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">top</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Previous comment</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>event.<span class="me1">keyCode</span> == <span class="nu0">80</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>selected.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected.<span class="me1">removeClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected = selected.<span class="me1">prevAll</span><span class="br0">&#40;</span><span class="st0">&#39;.comment:first&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; selected = $<span class="br0">&#40;</span><span class="st0">&#39;.comment:last&#39;</span><span class="br0">&#41;</span>.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;comment-selected&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>selected.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; window.<span class="me1">scrollTo</span><span class="br0">&#40;</span><span class="nu0">0</span>, selected.<span class="me1">offset</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">top</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>As you can see, it is important to leave the input and textarea fields alone, so the keyboard shortcuts don&#8217;t interfere with the user typing some text. With a little bit of CSS the selected comment can be displayed with a different border color or background. And that&#8217;s it!</p>
<p>Check an example topic at <a href="http://www.spaniards.es/foros/2008/12/12/empresas-alemanas-que-trabajen-ingles">www.spaniards.es</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>December 13, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part III">Ajax comments in Drupal 5: How I made it &#8211; Part III</a> (10)</li><li>December 11, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part II">Ajax comments in Drupal 5: How I made it &#8211; Part II</a> (0)</li><li>December 10, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/" title="Ajax comments in Drupal 5: How I made it &#8211; Part I">Ajax comments in Drupal 5: How I made it &#8211; Part I</a> (10)</li><li>February 24, 2009 -- <a href="http://dev.enekoalonso.com/2009/02/24/vancode2int/" title="vancode2int">vancode2int</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ajax comments in Drupal 5: How I made it &#8211; Part III</title>
		<link>http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/</link>
		<comments>http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 20:42:11 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=128</guid>
		<description><![CDATA[In Ajax comments in Drupal 5: How I made it parts I and II we saw the code needed on the back-end. Now, let&#8217;s see what goes on the client side: the Javascript. Submitting the comment with an ajax request Basically, to add a comment we need the node id (nid) and the comment text. [...]]]></description>
			<content:encoded><![CDATA[<p>In Ajax comments in Drupal 5: How I made it <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-i">parts I</a> and <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii">II</a> we saw the code needed on the back-end. Now, let&#8217;s see what goes on the client side: the Javascript.</p>
<h3>Submitting the comment with an ajax request</h3>
<p>Basically, to add a comment we need the node id (nid) and the comment text. The code in the back-end will handle the user info and permissions. The first thing we do is find the comment form and the submit button. Then we hook the click event on the submit button.</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> commentForm = jQuery<span class="br0">&#40;</span><span class="st0">&#39;form#comment-form&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>commentForm.<span class="me1">length</span><span class="br0">&#41;</span> <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> submitBtn = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-submit&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>submitBtn.<span class="me1">length</span><span class="br0">&#41;</span> <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; submitBtn.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>ev<span class="br0">&#41;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// &#8230;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>When the user clicks the submit button, we get the node id (we could have done on domready) and the comment text. If the comment is empty, we don&#8217;t do anything, so the comment will be submitted the standard way and Drupal will fail the comment form validation.</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get Node Id</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> nid = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#node-nid&#39;</span><span class="br0">&#41;</span>.<span class="me1">text</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>nid<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>; <span class="co1">// Do nothing&#8230;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>parseInt<span class="br0">&#40;</span>nid<span class="br0">&#41;</span> <span class="sy0">&lt;</span>= <span class="nu0">0</span><span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get Comment Text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> text = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-comment&#39;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>text<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>; <span class="co1">// Let Drupal validate the form</span></div>
</li>
</ol>
</div>
<p>Since we don&#8217;t want to get back just the comment added but all the new comments added by any user on this node, we want to pass the last comment id on screen.</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get last comment Id</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> lastComment = jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.comment:last&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> lastCommentId = <span class="br0">&#40;</span>lastComment.<span class="me1">length</span><span class="br0">&#41;</span>? lastComment.<span class="me1">id</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&#39;-&#39;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> : <span class="nu0">0</span>;</div>
</li>
</ol>
</div>
<p>Due to my limited knowledge of jQuery at the time, I used the load function for the ajax request. The problem with this function is that, from what I know, it only works on elements already included in the DOM. So before the request, I had to create a container for the new comments. The point of insertion will differ if the page already has comments or not:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// We got both nid and text. Let&#39;s create the comment holder</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> comment = jQuery<span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">&#39;div&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; comment.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>lastComment.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; lastComment.<span class="me1">after</span><span class="br0">&#40;</span>comment<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; comment.<span class="me1">insertBefore</span><span class="br0">&#40;</span>jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.box&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Finally, the load request:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Ajax submit/load</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; comment.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&#39;/add/comment&#39;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp;<span class="st0">&#39;nid&#39;</span>: nid, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#39;text&#39;</span>: text,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#39;lastcid&#39;</span>: lastCommentId </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>responseText, textStatus, XMLHttpRequest<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>textStatus == <span class="st0">&#39;success&#39;</span> <span class="sy0">&amp;&amp;</span> responseText<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ajax_insert_comment<span class="br0">&#40;</span>comment<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; comment.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Error: No se pudo enviar el comentario&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>If the request failed, the container was removed. If the request succeeded, the new comments were added to the page:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">ajax_insert_comment = <span class="kw2">function</span><span class="br0">&#40;</span>comment<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Insert new comments</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; comment.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
</ol>
</div>
<p>And that was it! Ajax comments in Drupal working like a charm.</p>
<h3>Adding/removing the &#8220;new&#8221; indicator</h3>
<p>Now that I had my Ajax comments working I wanted them to look better. For example, I wanted the new added comments to have the &#8220;new&#8221; indicator, while at the same time I wanted to remove the indicator from the comments already on the screen. On ajax_insert_comment:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Clear &#39;new&#39; from previous comments</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.comment&#39;</span><span class="br0">&#41;</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#39;span.new&#39;</span><span class="br0">&#41;</span>.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Add &#39;new&#39; indicator</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> newcomment = jQuery<span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">&#39;span&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; newcomment.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;new&#39;</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span><span class="st0">&#39;new&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; newcomment.<span class="me1">insertBefore</span><span class="br0">&#40;</span>comment.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#39;div.comment-author&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>And many other tweaks like that.</p>
<h3>The code</h3>
<p>Here is the whole code for ajax comment submission I currently use:</p>
<div class="geshi no javascript">
<ol>
<li class="li1">
<div class="de1">ajax_comments = <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> commentForm = jQuery<span class="br0">&#40;</span><span class="st0">&#39;form#comment-form&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>commentForm.<span class="me1">length</span><span class="br0">&#41;</span> <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> submitBtn = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-submit&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>submitBtn.<span class="me1">length</span><span class="br0">&#41;</span> <span class="kw1">return</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; submitBtn.<span class="me1">val</span><span class="br0">&#40;</span><span class="st0">&#39;Enviar comentario&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; submitBtn.<span class="me1">click</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>ev<span class="br0">&#41;</span> </div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Disable submit button</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; submitBtn.<span class="me1">val</span><span class="br0">&#40;</span><span class="st0">&#39;Enviando&#8230;&#39;</span><span class="br0">&#41;</span>.<span class="me1">attr</span><span class="br0">&#40;</span><span class="st0">&quot;disabled&quot;</span>,<span class="st0">&quot;disabled&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Clear the &#39;edit&#39; link from previous comments</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; jQuery<span class="br0">&#40;</span><span class="st0">&#39;li.edit-comment-link&#39;</span><span class="br0">&#41;</span>.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get Node Id</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> nid = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#node-nid&#39;</span><span class="br0">&#41;</span>.<span class="me1">text</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>nid<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>; <span class="co1">// Do nothing&#8230;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>parseInt<span class="br0">&#40;</span>nid<span class="br0">&#41;</span> <span class="sy0">&lt;</span>= <span class="nu0">0</span><span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get Comment Text</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> text = jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-comment&#39;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span>text<span class="br0">&#41;</span> <span class="kw1">return</span> <span class="kw2">true</span>; <span class="co1">// Let Drupal validate the form</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Get last comment Id</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> lastComment = jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.comment:last&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> lastCommentId = <span class="br0">&#40;</span>lastComment.<span class="me1">length</span><span class="br0">&#41;</span>? lastComment.<span class="me1">id</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.<span class="me1">split</span><span class="br0">&#40;</span><span class="st0">&#39;-&#39;</span><span class="br0">&#41;</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span> : <span class="nu0">0</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// // We got both nid and text. Let&#39;s create the comment holder</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">var</span> comment = jQuery<span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">&#39;div&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; comment.<span class="me1">hide</span><span class="br0">&#40;</span><span class="br0">&#41;</span>; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>lastComment.<span class="me1">length</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; lastComment.<span class="me1">after</span><span class="br0">&#40;</span>comment<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; comment.<span class="me1">insertBefore</span><span class="br0">&#40;</span>jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.box&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Ajax submit/load</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; comment.<span class="me1">load</span><span class="br0">&#40;</span><span class="st0">&#39;/add/comment&#39;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> &nbsp;<span class="st0">&#39;nid&#39;</span>: nid, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#39;text&#39;</span>: text,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&#39;lastcid&#39;</span>: lastCommentId </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>, </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>responseText, textStatus, XMLHttpRequest<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>textStatus == <span class="st0">&#39;success&#39;</span> <span class="sy0">&amp;&amp;</span> responseText<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ajax_insert_comment<span class="br0">&#40;</span>comment<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-comment&#39;</span><span class="br0">&#41;</span>.<span class="me1">val</span><span class="br0">&#40;</span><span class="st0">&#39;&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span> <span class="kw1">else</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; comment.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">alert</span><span class="br0">&#40;</span><span class="st0">&quot;Error: No se pudo enviar el comentario&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Reenable submit button</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; submitBtn.<span class="me1">val</span><span class="br0">&#40;</span><span class="st0">&#39;Enviar comentario&#39;</span><span class="br0">&#41;</span>.<span class="me1">removeAttr</span><span class="br0">&#40;</span><span class="st0">&quot;disabled&quot;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">ajax_insert_comment = <span class="kw2">function</span><span class="br0">&#40;</span>comment<span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Clear &#39;new&#39; from previous comments</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; jQuery<span class="br0">&#40;</span><span class="st0">&#39;div.comment&#39;</span><span class="br0">&#41;</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#39;span.new&#39;</span><span class="br0">&#41;</span>.<span class="me1">remove</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Add &#39;new&#39; indicator</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw2">var</span> newcomment = jQuery<span class="br0">&#40;</span>document.<span class="me1">createElement</span><span class="br0">&#40;</span><span class="st0">&#39;span&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; newcomment.<span class="me1">addClass</span><span class="br0">&#40;</span><span class="st0">&#39;new&#39;</span><span class="br0">&#41;</span>.<span class="me1">html</span><span class="br0">&#40;</span><span class="st0">&#39;new&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; newcomment.<span class="me1">insertBefore</span><span class="br0">&#40;</span>comment.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#39;div.comment-author&#39;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Remove comment count</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; comment.<span class="me1">find</span><span class="br0">&#40;</span><span class="st0">&#39;span.commentcount&#39;</span><span class="br0">&#41;</span>.<span class="me1">empty</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="co1">// Insert new comments</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; comment.<span class="me1">show</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; jQuery<span class="br0">&#40;</span><span class="st0">&#39;#edit-comment&#39;</span><span class="br0">&#41;</span>.<span class="kw3">focus</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">jQuery<span class="br0">&#40;</span>document<span class="br0">&#41;</span>.<span class="me1">ready</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; ajax_comments<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>As you can see, when I wrote this code back in July, I have just started using jQuery and I didn&#8217;t know much about event handling. So I used the old return true/false to stop the submit event if needed. Also, now that I see the code again I can think on better ways to do parts of it. Well, that&#8217;s a good sign: it means I&#8217;m getting better :)</p>
<p>Series:<br />
<a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/">Ajax comments in Drupal 5: How I made it &#8211; Part I</a><br />
<a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/">Ajax comments in Drupal 5: How I made it &#8211; Part II</a><br />
<a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/">Ajax comments in Drupal 5: How I made it &#8211; Part III</a></p>
<h3>See the ajax comments in action</h3>
<p>Please, note this is a WordPress based blog. The Drupal website where I have implemented the ajax comments is <a href="http://www.spaniards.es">www.spaniards.es</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>December 11, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part II">Ajax comments in Drupal 5: How I made it &#8211; Part II</a> (0)</li><li>December 10, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/" title="Ajax comments in Drupal 5: How I made it &#8211; Part I">Ajax comments in Drupal 5: How I made it &#8211; Part I</a> (10)</li><li>December 14, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/" title="Keyboard shortcuts in Drupal: Navigating through comments">Keyboard shortcuts in Drupal: Navigating through comments</a> (2)</li><li>February 24, 2009 -- <a href="http://dev.enekoalonso.com/2009/02/24/vancode2int/" title="vancode2int">vancode2int</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Ajax comments in Drupal 5: How I made it &#8211; Part II</title>
		<link>http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/</link>
		<comments>http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 04:48:54 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=104</guid>
		<description><![CDATA[In Axaj comments in Drupal 5: How I made it &#8211; Part I I covered the most important part of the module code: saving comments to the database. Now, let&#8217;s see how to display them properly. Rendering the new comment Comments usually have more information than the user name and the comment text. In my [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i">Axaj comments in Drupal 5: How I made it &#8211; Part I</a> I covered the most important part of the module code: saving comments to the database. Now, let&#8217;s see how to display them properly.</p>
<h3>Rendering the new comment</h3>
<p>Comments usually have more information than the user name and the comment text. In my website, for instance, comments have information like the user registered date, where he/she lives, the country flag, the comment number on the thread, etc. All this information could not be made up at the client side; the server had to send it back to the client once the comment was saved.</p>
<p>Also, we want to take full advantage of Drupal: we want the corresponding filters applied to the comment text to remove malicious HTML tags, convert plain URLs into HTML links, etc.   </p>
<p>The best way to do this is to use the function theme with the parameter &#8216;comment_view&#8217;. The difference between theme(&#8216;comment&#8217;,&#8230;) and theme(&#8216;comment_view&#8217;,&#8230;) is that filters are applied only in the second case, if I am not mistaken. </p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> _spaniards_get_latest_comments<span class="br0">&#40;</span><span class="re1">$nid</span><span class="sy0">,</span> <span class="re1">$fromcid</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re1">$result</span> <span class="sy0">=</span> db_query<span class="br0">&#40;</span><span class="st0">&#39;select * from comments where nid = %d and cid &gt; %d&#39;</span><span class="sy0">,</span> <span class="re1">$nid</span><span class="sy0">,</span> <span class="re1">$fromcid</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re1">$content</span> <span class="sy0">=</span> <span class="st0">&#39;&#39;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">while</span> <span class="br0">&#40;</span><span class="re1">$comment</span> <span class="sy0">=</span> db_fetch_object<span class="br0">&#40;</span><span class="re1">$result</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="re1">$comment</span><span class="sy0">-&gt;</span><span class="me1">status</span> <span class="sy0">==</span> COMMENT_NOT_PUBLISHED<span class="br0">&#41;</span> <span class="kw1">continue</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$links</span> <span class="sy0">=</span> module_invoke_all<span class="br0">&#40;</span><span class="st0">&#39;link&#39;</span><span class="sy0">,</span> <span class="st0">&#39;comment&#39;</span><span class="sy0">,</span> <span class="re1">$comment</span><span class="sy0">,</span> <span class="nu0">1</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$content</span> <span class="sy0">.=</span> theme<span class="br0">&#40;</span><span class="st0">&#39;comment_view&#39;</span><span class="sy0">,</span> <span class="re1">$comment</span><span class="sy0">,</span> <span class="re1">$links</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">return</span> <span class="re1">$content</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>As I mentioned before, we don&#8217;t want to return just the comment added by the user but any comment added by any other user since the user loaded the page. This function will return any comment on the thread with comment Id greater than the parameter $fromcid.</p>
<p>Besides using theme(&#8216;comment_view&#8217;,&#8230;) it is a good idea also to invoke the link hook. This will let other modules like <a href="http://drupal.org/project/fasttoggle">fasttoggle</a> inject their very useful links in out comment.</p>
<p>And that is it for now. This code, together with the code on Part I will be the only PHP needed. We will see the client side Javascript code on Part III.</p>
<p>Series:<br />
<a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/">Ajax comments in Drupal 5: How I made it &#8211; Part I</a><br />
<a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/">Ajax comments in Drupal 5: How I made it &#8211; Part II</a><br />
<a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/">Ajax comments in Drupal 5: How I made it &#8211; Part III</a></p>
<h3>See the ajax comments in action</h3>
<p>Please, note this is a WordPress based blog. The Drupal website where I have implemented the ajax comments is <a href="http://www.spaniards.es">www.spaniards.es</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>December 13, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part III">Ajax comments in Drupal 5: How I made it &#8211; Part III</a> (10)</li><li>December 10, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/" title="Ajax comments in Drupal 5: How I made it &#8211; Part I">Ajax comments in Drupal 5: How I made it &#8211; Part I</a> (10)</li><li>December 14, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/" title="Keyboard shortcuts in Drupal: Navigating through comments">Keyboard shortcuts in Drupal: Navigating through comments</a> (2)</li><li>February 24, 2009 -- <a href="http://dev.enekoalonso.com/2009/02/24/vancode2int/" title="vancode2int">vancode2int</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ajax comments in Drupal 5: How I made it &#8211; Part I</title>
		<link>http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/</link>
		<comments>http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 04:29:43 +0000</pubDate>
		<dc:creator>Eneko Alonso</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://dev.enekoalonso.com/?p=95</guid>
		<description><![CDATA[First of all, I would like to apologize for not publishing this the right way. I haven&#8217;t had time to put it all on a standalone module, which will make it easier to share the code at www.drupal.org. Feel free to grab the code and put it on a module if you wish (and let [...]]]></description>
			<content:encoded><![CDATA[<p>First of all, I would like to apologize for not publishing this the right way. I haven&#8217;t had time to put it all on a standalone module, which will make it easier to share the code at <a href="http://www.drupal.org">www.drupal.org</a>. Feel free to grab the code and put it on a module if you wish (and let me know if you do so :)</p>
<h3>Why Ajax comments?</h3>
<p>Ajax comments let users to submit comments without having to reload the whole page. Reloading a page is not only slow, but its an overload for the server which has to process and send the whole page again just to add a simple comment to the DOM. So yes, Ajax comments are a big benefit, both for the user, which has to wait less, and for the server, which has to process and send less information.</p>
<h3>Available modules</h3>
<p>Point explained, lets see how it went. In the past I tried the <a href="http://drupal.org/project/jstools">Javascript Tools</a> set of modules, which had other dependencies if I am not mistaken. And I don&#8217;t know why but it didn&#8217;t work at all for me. My comments kept reloading the whole page while sent. A couple of months ago I decided it was time to do it myself.</p>
<h3>The plan</h3>
<p>My original plan was simple: when the user hits the submit button, send the comment to the server, save it and add it to the DOM at the end of the comment list. This looked simple, but it had a few thing to deal with. I didn&#8217;t want to mess with Drupal&#8217;s comment module neither modify any line of Drupal&#8217;s core. So I decided to take an alternative path.</p>
<h3>Saving a comment</h3>
<p>Saving a comment doesn&#8217;t require much information. Since the user has to be logged in, the only information needed is basically the node Id and the comment itself. Drupal has a very nice hook_menu that allows you to create pages with a specific URL. These pages can process data, serve data or both. The only drawback, if so, was that hooks only works on modules, so I had to create my own. I decided to add it to my custom site module.</p>
<div class="geshi no php">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">function</span> spaniards_menu<span class="br0">&#40;</span><span class="re1">$may_cache</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="re1">$items</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re1">$may_cache</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// Add comment</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re1">$items</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;path&#39;</span> <span class="sy0">=&gt;</span> <span class="st0">&#39;add/comment&#39;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;title&#39;</span> <span class="sy0">=&gt;</span> <span class="st0">&#39;Add Comment&#39;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;callback&#39;</span> <span class="sy0">=&gt;</span> <span class="st0">&#39;spaniards_add_comment&#39;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;callback arguments&#39;</span> <span class="sy0">=&gt;</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;access&#39;</span> <span class="sy0">=&gt;</span> user_access<span class="br0">&#40;</span><span class="st0">&quot;post comments&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; <span class="st0">&#39;type&#39;</span> <span class="sy0">=&gt;</span> MENU_CALLBACK<span class="sy0">,</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> spaniards_add_comment<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">global</span> <span class="re1">$user</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$text</span> <span class="sy0">=</span> <span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;text&#39;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span> <span class="sy0">=</span> <span class="kw3">array</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;uid&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re1">$user</span><span class="sy0">-&gt;</span><span class="me1">uid</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;nid&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;nid&#39;</span><span class="br0">&#93;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;pid&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;subject&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="kw3">substr</span><span class="br0">&#40;</span><span class="re1">$text</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">20</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;comment&#39;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="re1">$text</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">// Add comment to DB</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$cid</span> <span class="sy0">=</span> comment_save<span class="br0">&#40;</span><span class="re1">$comment</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">// Mark the node as viewed by the user</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;node_tag_new<span class="br0">&#40;</span><span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;nid&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="co1">// Get all comments since the last one</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="re1">$fromcid</span> <span class="sy0">=</span> <span class="kw3">isset</span><span class="br0">&#40;</span><span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;lastcid&#39;</span><span class="br0">&#93;</span><span class="br0">&#41;</span>? <span class="re1">$_REQUEST</span><span class="br0">&#91;</span><span class="st0">&#39;lastcid&#39;</span><span class="br0">&#93;</span> <span class="sy0">:</span> <span class="nu0">0</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">print</span> _spaniards_get_latest_comments<span class="br0">&#40;</span><span class="re1">$comment</span><span class="br0">&#91;</span><span class="st0">&#39;nid&#39;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="re1">$fromcid</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp;<span class="kw3">exit</span><span class="sy0">;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Just with those two functions we can bypass Drupal&#8217;s comment submission system and add new comments to the database. As long as we use the comment_save function, the actual process involved in saving a comment is safe (hooks get called, watchdog logging works, etc). Also, hook_menu guarantees only requests with the right access will be able to add a comment (in this case the user_access function verifies the user has &#8220;post comments&#8221; permissions granted).</p>
<p>Once the comment is saved, the node is marked as viewed by the user, to remove all &#8220;new&#8221; labels from the new comments added.</p>
<p>Finally the comment is rendered and returned to the user. But wait! What if another user has posted a comment in between? During a conversation between multiple users this will happen very often. The solution: return all comments added since the last comment visible when the user visited the thread.</p>
<p>We will see how to do that next.</p>
<p>Series:<br />
<a href="http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/">Ajax comments in Drupal 5: How I made it &#8211; Part I</a><br />
<a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/">Ajax comments in Drupal 5: How I made it &#8211; Part II</a><br />
<a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/">Ajax comments in Drupal 5: How I made it &#8211; Part III</a></p>
<h3>See the ajax comments in action</h3>
<p>Please, note this is a WordPress based blog. The Drupal website where I have implemented the ajax comments is <a href="http://www.spaniards.es">www.spaniards.es</a></p>
<h3  class="related_post_title">Related Posts:</h3><ul class="related_post"><li>December 13, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/13/ajax-comments-in-drupal-5-how-i-made-it-part-iii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part III">Ajax comments in Drupal 5: How I made it &#8211; Part III</a> (10)</li><li>December 11, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/11/ajax-comments-in-drupal-5-how-i-made-it-part-ii/" title="Ajax comments in Drupal 5: How I made it &#8211; Part II">Ajax comments in Drupal 5: How I made it &#8211; Part II</a> (0)</li><li>December 14, 2008 -- <a href="http://dev.enekoalonso.com/2008/12/14/keyboard-shortcuts-in-drupal-navigating-through-comments/" title="Keyboard shortcuts in Drupal: Navigating through comments">Keyboard shortcuts in Drupal: Navigating through comments</a> (2)</li><li>February 24, 2009 -- <a href="http://dev.enekoalonso.com/2009/02/24/vancode2int/" title="vancode2int">vancode2int</a> (0)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://dev.enekoalonso.com/2008/12/10/ajax-comments-in-drupal-5-how-i-made-it-part-i/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

