<?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>James Tombs &#187; drupal</title>
	<atom:link href="http://jamestombs.co.uk/tag/drupal/feed" rel="self" type="application/rss+xml" />
	<link>http://jamestombs.co.uk</link>
	<description>Development blog from James Tombs about PHP, XHTML + CSS and Drupal</description>
	<lastBuildDate>Wed, 25 Aug 2010 21:51:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Block API module changes coming soon</title>
		<link>http://jamestombs.co.uk/2010-07-16/block-api-module-changes-coming-soon/1299</link>
		<comments>http://jamestombs.co.uk/2010-07-16/block-api-module-changes-coming-soon/1299#comments</comments>
		<pubDate>Fri, 16 Jul 2010 10:39:16 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[block api]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1299</guid>
		<description><![CDATA[After reviewing and updating Block API for Drupal 7, I saw that there were some fairly big changes made to the way the block system works from a code perspective which meant I have had to change a fair bit of the module for Drupal 7. So rather than having 2 quite distinct bits of [...]]]></description>
			<content:encoded><![CDATA[<p>After reviewing and updating Block API for Drupal 7, I saw that there were some fairly big changes made to the way the block system works from a code perspective which meant I have had to change a fair bit of the module for Drupal 7.  So rather than having 2 quite distinct bits of code, I will be updating the Drupal 6 version to work like the Drupal 7 version so that the documentation is the same.  This not only makes the module easier to maintain from my perspective but also anyone else using Block API.</p>
<p><span id="more-1299"></span></p>
<h3>So what has changed?</h3>
<p>hook_block() no longer exists in Drupal 7.  It has been split in to individual hooks for each $op.  So rather than hook_block() we now have:</p>
<ul>
<li>hook_block_info()</li>
<li>hook_block_configure()</li>
<li>hook_block_save()</li>
<li>hook_block_view()</li>
</ul>
<p>A few of these new hooks conflicted with the hooks put in place by the Block API module, so I have made a few changes to the way other modules hook in to it.</p>
<pre class="brush: php">function html_block_block($op = &#039;list&#039;, $delta = NULL, $edit = array()) {
  $function = &#039;block_api_block_&#039;. $op;
  return $function(&#039;html_block&#039;, $delta, $edit);
}</pre>
<p>The above has gone completely. Rather than passing the modules name to the core Blocks module, Block API will pass on it&#8217;s own name and handle the block management of modules using the API itself.  This reduces the amount of code needed (although it wasn&#8217;t that much to start off with) and also makes it easier to remember what you need to use to hook in to Block API.</p>
<p><em>hook_block_api_info()</em> has now changed to <em>hook_block_api_block_types()</em>, the code stays exactly the same. This was caused by the function name changes made in Drupal 7.</p>
<p><em>hook_block_api_view()</em> has changed to <em>hook_block_api_display()</em>, this was also due to the function change in Drupal 7.</p>
<p>Everything else stays the same.  The Block API has now been made slightly easier to use and hook in to thanks to Drupal 7.</p>
<p>The code on d.o should be updated soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-16/block-api-module-changes-coming-soon/1299/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>World of Warcraft &#8211; PHP Raider Block</title>
		<link>http://jamestombs.co.uk/2010-07-13/world-of-warcraft-php-raider-block/1289</link>
		<comments>http://jamestombs.co.uk/2010-07-13/world-of-warcraft-php-raider-block/1289#comments</comments>
		<pubDate>Tue, 13 Jul 2010 14:32:05 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[world of warcraft]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1289</guid>
		<description><![CDATA[This module adds the ability to have a block pulling out the upcoming raids from PHP Raider. Download: ZIP Last updated: 2010-07-13 18:30 The block displays however many raids you want to display and gives you more information which is available on mouseover. As well as the block configuration, the module has an admin form [...]]]></description>
			<content:encoded><![CDATA[<p>This module adds the ability to have a block pulling out the upcoming raids from <a href="http://www.phpraider.com/">PHP Raider</a>.</p>
<p><strong>Download:</strong> <a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/wow_phpraider.zip">ZIP</a> <strong>Last updated:</strong> 2010-07-13 18:30</p>
<p><span id="more-1289"></span></p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/raid_block.jpg" alt="" title="Raid Block" width="209" height="254" class="alignnone size-full wp-image-1291" /> <img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/raid_hover.jpg" alt="" title="Raid Block - Hover" width="396" height="265" class="alignnone size-full wp-image-1292" /></p>
<p>The block displays however many raids you want to display and gives you more information which is available on mouseover.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/raid_settings.jpg" alt="" title="Raider Block Settings" width="476" height="337" class="alignnone size-full wp-image-1293" /></p>
<p>As well as the block configuration, the module has an admin form that must be filled in before any blocks can be created.  This is to make sure that Drupal knows where PHP Raider is located and where the database is.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/raider_config.jpg" alt="" title="PHP Raider configuration screen" width="500" height="306" class="alignnone size-full wp-image-1294" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-13/world-of-warcraft-php-raider-block/1289/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>World of Warcraft Blocks for Drupal</title>
		<link>http://jamestombs.co.uk/2010-07-12/world-of-warcraft-blocks-for-drupal/1279</link>
		<comments>http://jamestombs.co.uk/2010-07-12/world-of-warcraft-blocks-for-drupal/1279#comments</comments>
		<pubDate>Mon, 12 Jul 2010 17:53:03 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1279</guid>
		<description><![CDATA[I have been working on a site for a World of Warcraft guild to get their frontpage up to scratch with their old site which was running the TinyPortal on SMF. With a server change and some mods becoming unsupported, the decision was made to switch to something else for the frontpage. I had only [...]]]></description>
			<content:encoded><![CDATA[<p>I have been working on a site for a World of Warcraft guild to get their frontpage up to scratch with their old site which was running the TinyPortal on SMF. With a server change and some mods becoming unsupported, the decision was made to switch to something else for the frontpage. I had only one thing on my mind which was Drupal.  But soon found that there didn&#8217;t appear to be many modules on Drupal.org for World of Warcraft.</p>
<p>So far I have created two blocks using the Block API module I developed and will release more when I have written and tested them.</p>
<p>Both blocks are set up in one module, which I have called wow_blocks. If you already have a module called wow_blocks, it may be a bit of a mission getting this to work, so you will have to chose one of the modules.</p>
<p>Download: <a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/wow_blocks.zip">ZIP</a>. <strong>Last updated:</strong> 2010-07-12 18:30</p>
<p><span id="more-1279"></span></p>
<h3>Block 1: Recruitment</h3>
<p>The first block is a block for recruitment.  An admin can set the roles and specs that the guild requires to be displayed in the block, so users know which areas the guild is recruiting in.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/recruitment_block.jpg" alt="" title="recruitment_block" width="199" height="497" class="alignnone size-full wp-image-1281" /></p>
<p>All the images are included in the ZIP file.</p>
<p>The admin screen, allows the admin to select the links to use for the Apply now and Recruitment details buttons as well as options for each individual role and spec.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/recruitment_settings_full.jpg" rel="shadowbox[post-1279];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/recruitment_settings_small.jpg" alt="" title="recruitment_settings_small" width="511" height="357" class="alignnone size-full wp-image-1283" /><br />Click for larger version</a></p>
<h3>Block 2: Progression</h3>
<p>This block shows the guilds progression against the bosses of the game.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/progression_view.jpg" alt="" title="progression_view" width="436" height="296" class="alignnone size-full wp-image-1284" /></p>
<p>The block features an expandable group of game zones with all the bosses in the zone.</p>
<p>All bosses from the following zones are in the module:</p>
<ul>
<li>&#8216;Icecrown Citadel</li>
<li>Argent Coliseum</li>
<li>Ulduar</li>
<li>Eye of Eternity</li>
<li>Obsidian Sanctum</li>
<li>Naxxramas</li>
<li>Vault of Archavon</li>
</ul>
<p>Admins have full control over which zones are available and shown in the block as well as selecting which bosses have been defeated.</p>
<p>If you have any requests for World of Warcraft related blocks, let me know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-12/world-of-warcraft-blocks-for-drupal/1279/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding additional form elements using ahah_helper in Drupal 6</title>
		<link>http://jamestombs.co.uk/2010-07-08/adding-additional-form-elements-using-ahah_helper-in-drupal-6/1276</link>
		<comments>http://jamestombs.co.uk/2010-07-08/adding-additional-form-elements-using-ahah_helper-in-drupal-6/1276#comments</comments>
		<pubDate>Thu, 08 Jul 2010 10:41:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[ahah]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1276</guid>
		<description><![CDATA[This tutorial will show you how to add new form elements which will be available in $form_state['values'] once the form has been submitted using a submit button by taking advantage of the AHAH helper module. The AHAH helper module does provide a demo, but the demo shows how to change a few fields depending on [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will show you how to add new form elements which will be available in $form_state['values'] once the form has been submitted using a submit button by taking advantage of the <a href="http://drupal.org/project/ahah_helper">AHAH helper module</a>.</p>
<p>The AHAH helper module does provide a demo, but the demo shows how to change a few fields depending on a selection made from a select element.  The tutorials I looked at online either didn&#8217;t cover the issue properly or just didn&#8217;t work.<br />
<span id="more-1276"></span><br />
Currently the 6.x-2.0 release throws up errors if you are using certain PHP versions, but these are gone in the 6.x-2.x-dev release.</p>
<h3>Scenario</h3>
<p>You want the user to enter in some data, lets say their favourite car.  But you want the ability for them to add as many cars as they want if they have more than one.</p>
<h3>Code</h3>
<p>Firstly you will need to set up a menu callback for your form, but I will assume you know how to do this if you are looking at this tutorial.</p>
<p>We will set up the basic form first, this includes one textfield and a submit button to submit the form with the textfield in a wrapper (this is important later on for the ahah_helper module).</p>
<pre class="brush: php">function test_form($form_state = NULL) {
  $form[&#039;cars&#039;] = array(
    &#039;#type&#039; =&gt; &#039;fieldset&#039;,
    &#039;#title&#039; =&gt; t(&#039;Favourite cars(s)&#039;),
    &#039;#prefix&#039; =&gt; &#039;&lt;div id=&quot;favourite-cars-wrapper&quot;&gt;&#039;,
    &#039;#suffix&#039; =&gt; &#039;&lt;/div&gt;&#039;,
  );
  $form[&#039;cars&#039;][&#039;car&#039;] = array(
    &#039;#type&#039; =&gt; &#039;textfield&#039;,
    &#039;#title&#039; =&gt; t(&#039;Favourite car&#039;),
    &#039;#size&#039; =&gt; 36,
    &#039;#default_value&#039; =&gt; $form_state[&#039;values&#039;][&#039;car&#039;],
  );
  $form[&#039;submit&#039;] = array(
    &#039;#type&#039; =&gt; &#039;submit&#039;,
    &#039;#value&#039; =&gt; t(&#039;Submit&#039;),
  );
  return $form;
}</pre>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>This is very basic and allows the user to enter one car and submit the form.  We now need to add in the extra functionality of ahah_helper to be able to add mulitple fields.</p>
<pre class="brush: php">function test_form($form_state = NULL) {

  ahah_helper_register($form, $form_state); // Absolutely vital for ahah_helper to do it&#039;s job

  // We check to see if quantity has been set, ie if the form has been submitted yet.  If not, we show 1 field, you can change this to however many fields you want to show up as default.
  if (!isset($form_state[&#039;storage&#039;][&#039;quantity&#039;])) {
    $quantity = 1;
  }
  else {
    // If the form has been submitted we get the quantity that was stored.
    $quantity = $form_state[&#039;storage&#039;][&#039;quantity&#039;];
    // We then do a check to see if the user has clicked the &quot;Add another car&quot; button, if they have we increase the amount by 1.
    if (isset($form_state[&#039;values&#039;][&#039;cars&#039;][&#039;add_more&#039;]) &amp;&amp; $form_state[&#039;values&#039;][&#039;op&#039;] == &#039;Add another car&#039;) {
      $quantity++;
    }
  }

  // We create a hidden form element to store the amount of fields that the user has added.
  $form[&#039;quantity&#039;] = array(
    &#039;#type&#039; =&gt; &#039;value&#039;,
    &#039;#value&#039; =&gt; $quantity,
  );

  $form[&#039;cars&#039;] = array(
    &#039;#type&#039; =&gt; &#039;fieldset&#039;,
    &#039;#title&#039; =&gt; t(&#039;Favourite cars(s)&#039;),
    &#039;#prefix&#039; =&gt; &#039;&lt;div id=&quot;favourite-cars-wrapper&quot;&gt;&#039;,
    &#039;#suffix&#039; =&gt; &#039;&lt;/div&gt;&#039;,
    &#039;#tree&#039; =&gt; TRUE // This is important for ahah_helper.
  );
  // We now do a simple loop, creating however many textfields are defined by $form_state[&#039;storage&#039;][&#039;quantity&#039;]
  for ($i = 1; $i &lt;= $quantity; $i++) {
    // The element name needs to be different for each textfield, otherwise we will only get one value after the form is submitted.
    $form[&#039;cars&#039;][&#039;car_&#039;. $i] = array(
      &#039;#type&#039; =&gt; &#039;textfield&#039;,
      &#039;#title&#039; =&gt; t(&#039;Favourite car&#039;),
      &#039;#size&#039; =&gt; 36,
      &#039;#default_value&#039; =&gt; $form_state[&#039;values&#039;][&#039;cars&#039;][&#039;car_&#039;. $i],
    );
  }

  // We add in a button with the #ahah element which will handle all our work for us.
  $form[&#039;cars&#039;][&#039;add_more&#039;] = array(
    &#039;#type&#039; =&gt; &#039;submit&#039;,
    &#039;#value&#039; =&gt; t(&#039;Add another car&#039;),
    &#039;#ahah&#039; =&gt; array(
      &#039;event&#039; =&gt; &#039;click&#039;, // When the button is &quot;clicked&quot;, AHAH will do it&#039;s job
      &#039;path&#039; =&gt; ahah_helper_path(array(&#039;cars&#039;)), // The array features the wrapper form field. So our form wrapper is $form[&#039;cars&#039;], so we set this to array(&#039;cars&#039;). If your form was $form[&#039;cars&#039;][&#039;another_wrapper&#039;], the path would be array(&#039;cars&#039;, &#039;another_wrapper&#039;).
      &#039;wrapper&#039; =&gt; &#039;favourite-cars-wrapper&#039;, // We then define the wrapper which will be changed.
    ),
  );
  $form[&#039;submit&#039;] = array(
    &#039;#type&#039; =&gt; &#039;submit&#039;,
    &#039;#value&#039; =&gt; t(&#039;Submit&#039;),
  );
  return $form;
}</pre>
<p>So what have we done&#8230;first we added the following line:</p>
<pre class="brush: php">ahah_helper_register($form, $form_state);</pre>
<p>This is a vital function that needs to be present in your form for ahah_helper to do it&#8217;s job.</p>
<p>Next we check to see if the form has been submitted before and if it has, get the amount of textfields that the form had by storing it in a hidden field.  We then do a further check to find out what button was clicked.  If the &#8220;add more&#8221; button was clicked, then we add another textfield by increasing the value of the quantity variable.</p>
<p>A minor, but very important change we make is adding &#8216;#tree&#8217; => TRUE to our wrapper element, this is a requirement for ahah_helper to do it&#8217;s job properly.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>Next we use a for loop, to add all our textfields into the form.  This should be self-explanitory but will go in to a bit more depth further on when we talk about the #ahah element.</p>
<p>We added an additional button to the form, this is so that the user can add another field to the form. You don&#8217;t need to worry about javascript degradation as ahah_helper takes care of this.</p>
<p>One attribute of #ahah on the button that isn&#8217;t listed in the form, but is very important, is the &#8220;method&#8221;.  The default value of this is replace, which is what we want. This replaces the whole contents of the wrapper which we define with the data from the path which we defined.  This is why we needed the for loop to recreate the textfields.</p>
<p>To take care of the form when javascript is disabled, you must check which button was pressed when the form was submitted.</p>
<pre class="brush: php">function test_form_submit($form, $form_state) {
  if ($form_state[&#039;values&#039;][&#039;op&#039;] == &#039;Submit&#039;) {
    drupal_set_message(&#039;Submit button clicked&#039;);
  }
  else {
    drupal_set_message(&#039;Add more button clicked&#039;);
  }
}</pre>
<p>With javascript enabled, when clicking the Add more button, Drupal will perform validation on the form, but will not submit the form.  Whereas clicking the submit button will perform validation and submit the form.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-08/adding-additional-form-elements-using-ahah_helper-in-drupal-6/1276/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Display iframed content as a block using Block API</title>
		<link>http://jamestombs.co.uk/2010-07-05/display-iframed-content-as-a-block-using-block-api/1270</link>
		<comments>http://jamestombs.co.uk/2010-07-05/display-iframed-content-as-a-block-using-block-api/1270#comments</comments>
		<pubDate>Mon, 05 Jul 2010 13:21:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[block api]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1270</guid>
		<description><![CDATA[This will give a quick look over the code needed to create a block type using Block API to allow users to create new blocks which use an iframe to display content from external sites. This can be useful for widgets that the user wants to display but doesn&#8217;t know HTML, or if the admin [...]]]></description>
			<content:encoded><![CDATA[<p>This will give a quick look over the code needed to create a block type using Block API to allow users to create new blocks which use an iframe to display content from external sites.  This can be useful for widgets that the user wants to display but doesn&#8217;t know HTML, or if the admin wants to add a bit more control rather than allowing too much HTML.</p>
<p>Not every user will understand this:</p>
<pre class="brush: html">&lt;iframe src=&quot;http://drupal.org/&quot; width=&quot;100%&quot; height=&quot;500px&quot; frameborder=&quot;1&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;</pre>
<p>And will find this much simpler and easier to use:</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/iframe_block_settings.jpg" alt="" title="iframe_block_settings" width="502" height="551" class="alignnone size-full wp-image-1271" /></p>
<p><span id="more-1270"></span></p>
<p>First off, you need to create a module like you normally would with your .info and .module files.</p>
<p>My module is going to be called iframe_block, so you will need to change this in certain cases if you use a different name.</p>
<pre class="brush: php">name = Iframe Block
description = Add new blocks which contain an iframe of a specified URL.
core = 6.x
dependencies[] = block_api</pre>
<p>That is for the .info file which sets the dependency on block_api.  If block_api isn&#8217;t available then this module can&#8217;t be used.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>Our .module file is going to be fairly simple and just hooks in to Block API, using three of the available hooks. But before we use any of the Block API hooks, we need to forwards the Drupal block related calls to the Block API module.</p>
<pre class="brush: php">function iframe_block_block($op = &#039;list&#039;, $delta = 0, $edit = array()) {
  $function = &#039;block_api_block_&#039;. $op;
  return $function(&#039;iframe_block&#039;, $delta, $edit);
}</pre>
<p>This will pass any calls to iframe_block_block() to the Block API module which in turn will add it&#8217;s own hooks which we can take advantage of.</p>
<p>The first one and most important is hook_block_api_info(), which we use to tell Drupal about our block type.</p>
<pre class="brush: php">function iframe_block_block_api_info() {
  $types[&#039;iframe_block&#039;] = array(
    &#039;title&#039; =&gt; t(&#039;Iframe Block&#039;),
    &#039;description&#039; =&gt; t(&#039;Create a block from with content from a specified URL using an iframe.&#039;),
    &#039;storage&#039; =&gt; BLOCK_API_STORAGE_DATABASE,
  );
  return $types;
}</pre>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/iframe_block_selection.jpg" alt="" title="iframe block selection" width="559" height="454" class="alignnone size-full wp-image-1272" /></p>
<p>Next we define our form for the user to fill in. The attributes we require are the source (the URL), the height and the width.  I am also going to provide the user the option of overriding the frameborder and scrolling attributes.</p>
<pre class="brush: php">function iframe_block_block_api_form($config, $edit) {
  if ($config[&#039;block_type&#039;] == &#039;iframe_block&#039;) {
    $form[&#039;url&#039;] = array(
      &#039;#type&#039; =&gt; &#039;textfield&#039;,
      &#039;#title&#039; =&gt; t(&#039;URL&#039;),
      &#039;#description&#039; =&gt; t(&#039;The URL of the page you would like to use as the source of the iframe.&#039;),
      &#039;#required&#039; =&gt; TRUE,
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;url&#039;],
    );
    $form[&#039;width&#039;] = array(
      &#039;#type&#039; =&gt; &#039;textfield&#039;,
      &#039;#title&#039; =&gt; t(&#039;Iframe width&#039;),
      &#039;#description&#039; =&gt; t(&#039;Enter the width of the iframe. Include the measurement type (px, em or %)&#039;),
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;width&#039;] ? $config[&#039;settings&#039;][&#039;width&#039;] : &#039;100%&#039;,
      &#039;#required&#039; =&gt; TRUE,
      &#039;#size&#039; =&gt; 10,
    );
    $form[&#039;height&#039;] = array(
      &#039;#type&#039; =&gt; &#039;textfield&#039;,
      &#039;#title&#039; =&gt; t(&#039;Iframe height&#039;),
      &#039;#description&#039; =&gt; t(&#039;Enter the height of the iframe. Include the measurement type (px, em or %)&#039;),
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;height&#039;] ? $config[&#039;settings&#039;][&#039;height&#039;] : &#039;300px&#039;,
      &#039;#required&#039; =&gt; TRUE,
      &#039;#size&#039; =&gt; 10,
    );
    $form[&#039;frameborder&#039;] = array(
      &#039;#type&#039; =&gt; &#039;select&#039;,
      &#039;#title&#039; =&gt; t(&#039;Iframe border&#039;),
      &#039;#description&#039; =&gt; t(&#039;Select whether you want to show a border around the iframe.&#039;),
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;frameborder&#039;] ? $config[&#039;settings&#039;][&#039;frameborder&#039;] : 0,
      &#039;#required&#039; =&gt; TRUE,
      &#039;#options&#039; =&gt; array(1 =&gt; t(&#039;Show border&#039;), 0 =&gt; t(&#039;Don\&#039;t show a border&#039;)),
    );
    $form[&#039;scrolling&#039;] = array(
      &#039;#type&#039; =&gt; &#039;select&#039;,
      &#039;#title&#039; =&gt; t(&#039;Scrolling&#039;),
      &#039;#description&#039; =&gt; t(&#039;Select whether the iframe should be scrollable or not&#039;),
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;scrolling&#039;] ? $config[&#039;settings&#039;][&#039;scrolling&#039;] : &#039;auto&#039;,
      &#039;#required&#039; =&gt; TRUE,
      &#039;#options&#039; =&gt; drupal_map_assoc(array(&#039;yes&#039;, &#039;no&#039;, &#039;auto&#039;)),
    );
  }
  return $form;
}</pre>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>This will allow the user to set up their iframe by entering the required information. </p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/iframe_block_settings.jpg" alt="" title="Iframe block settings" width="502" height="551" class="alignnone size-full wp-image-1271" /></p>
<p>Finally, we need to hook in to hook_block_api_view() to be able to display our iframe using the users input.</p>
<pre class="brush: php">function iframe_block_block_api_view($config) {
  if ($config[&#039;block_type&#039;] == &#039;iframe_block&#039;) {
    $output = &#039;&lt;iframe src=&quot;&#039;. $config[&#039;settings&#039;][&#039;url&#039;] .&#039;&quot; width=&quot;&#039;. $config[&#039;settings&#039;][&#039;width&#039;] .&#039;&quot; height=&quot;&#039;. $config[&#039;settings&#039;][&#039;height&#039;] .&#039;&quot; frameborder=&quot;&#039;. $config[&#039;settings&#039;][&#039;frameborder&#039;] .&#039;&quot; scrolling=&quot;&#039;. $config[&#039;settings&#039;][&#039;scrolling&#039;] .&#039;&quot;&gt;&#039;. $config[&#039;settings&#039;][&#039;no_iframes&#039;] .&#039;&lt;/iframe&gt;&#039;;
  }
  return array(&#039;content&#039; =&gt; $output);
}</pre>
<p>Very simply we are taking the users input and entering it in to some HTML code to give us the desired output.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/iframe_block_view.jpg" rel="shadowbox[post-1270];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/iframe_block_view-300x257.jpg" alt="" title="Iframe Block View" width="300" height="257" class="alignnone size-medium wp-image-1273" /><br /><small>Click for larger version</small></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-05/display-iframed-content-as-a-block-using-block-api/1270/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Displaying nodes as blocks using Block API</title>
		<link>http://jamestombs.co.uk/2010-07-05/displaying-nodes-as-blocks-using-block-api/1252</link>
		<comments>http://jamestombs.co.uk/2010-07-05/displaying-nodes-as-blocks-using-block-api/1252#comments</comments>
		<pubDate>Mon, 05 Jul 2010 10:31:47 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[block api]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1252</guid>
		<description><![CDATA[Recently I wrote a new module called Block API which allows other modules writers to create modules to develop templates for users to easily create new blocks rather than relying on copying and pasting HTML. The example module included copies the functionality of the core block module. Below I will show how to use Block [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote a new module called <a href="http://jamestombs.co.uk/2010-06-30/new-drupal-module-block-api/1245">Block API</a> which allows other modules writers to create modules to develop templates for users to easily create new blocks rather than relying on copying and pasting HTML.</p>
<p>The example module included copies the functionality of the core block module.  Below I will show how to use Block API to display a specific node as a block with further configuration options available to the user to choose from.<br />
<span id="more-1252"></span><br />
First off, if you just want to download this module to use, you can do so by <a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/node_block.zip">clicking here</a>.</p>
<p>As with any other module, create an info file using whatever module name you want.  The module name I will be using is node_block.</p>
<pre class="brush: php">name = Node Block
description = Add new blocks by using pre-existing nodes.
core = 6.x
dependencies[] = block_api</pre>
<p>In your .module file, we need to first set up the hook to allow Block API to do it&#8217;s job. So our first function will be the following:</p>
<pre class="brush: php">function node_block_block($op = &#039;list&#039;, $delta = 0, $edit = array()) {
  $function = &#039;block_api_block_&#039;. $op;
  return $function(&#039;node_block&#039;, $delta, $edit);
}</pre>
<p>This passes all the hook_block calls through the Block API which then allows users to select your block types through a single interface.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/module_block.jpg" alt="" title="Module Block selection through Block API" width="560" height="442" class="alignnone size-full wp-image-1257" /></p>
<p>Next, we need to define our block types that we will provide users.  To do this we use hook_block_api_info().</p>
<pre class="brush: php">function node_block_block_api_info() {
  $types[&#039;node_block&#039;] = array(
    &#039;title&#039; =&gt; t(&#039;Node Block&#039;),
    &#039;description&#039; =&gt; t(&#039;Create a block from a pre-existing node.&#039;),
    &#039;storage&#039; =&gt; BLOCK_API_STORAGE_DATABASE,
  );
  return $types;
}</pre>
<p>This is very simple, and defines the block type.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>For this module we are going to allow the user to select a node to display and choose whether to display the full node or just the teaser.  As well as this, we are going to give the administrator the choice of which node types are available to the user to chose nodes from as well as selecting whether users can use unpublished nodes or not.</p>
<p>First we will define the administration form to chose which content types are available.  To do this, we need to use hook_menu() to define our menu item pointing to our form.</p>
<pre class="brush: php">function node_block_menu() {
  $items[&#039;admin/settings/node_block&#039;] = array(
    &#039;access callback&#039; =&gt; &#039;user_access&#039;,
    &#039;access arguments&#039; =&gt; array(&#039;administer blocks&#039;),
    &#039;page callback&#039; =&gt; &#039;drupal_get_form&#039;,
    &#039;page arguments&#039; =&gt; array(&#039;node_block_admin_form&#039;),
    &#039;title&#039; =&gt; &#039;Node Block Configuration Settings&#039;,
    &#039;description&#039; =&gt; &#039;Set the configuration options for Node Blocks.&#039;,
    &#039;type&#039; =&gt; MENU_NORMAL_ITEM,
  );
  return $items;
}</pre>
<p>There is nothing complex here, just a standard menu item.  We now have to create the form node_block_admin_form().</p>
<pre class="brush: php">function node_block_admin_form() {
  $types = node_get_types(&#039;names&#039;);
  $form[&#039;node_block_content_types&#039;] = array(
    &#039;#type&#039; =&gt; &#039;checkboxes&#039;,
    &#039;#title&#039; =&gt; t(&#039;Node types available to create blocks&#039;),
    &#039;#description&#039; =&gt; t(&#039;Set the node types that are allowed to be displayed as blocks.&#039;),
    &#039;#required&#039; =&gt; TRUE,
    &#039;#options&#039; =&gt; $types,
    &#039;#default_value&#039; =&gt; variable_get(&#039;node_block_content_types&#039;, &#039;&#039;),
  );
  $form[&#039;node_block_published_only&#039;] = array(
    &#039;#type&#039; =&gt; &#039;checkbox&#039;,
    &#039;#title&#039; =&gt; t(&#039;Only allow published nodes to be shown as blocks.&#039;),
    &#039;#description&#039; =&gt; t(&#039;By checking this box only published nodes will be available for selection and appear as blocks.&#039;),
    &#039;#default_value&#039; =&gt; variable_get(&#039;node_block_published_only&#039;, 1),
  );
  $form[&#039;node_block_sql_order&#039;] = array(
    &#039;#type&#039; =&gt; &#039;select&#039;,
    &#039;#title&#039; =&gt; t(&#039;Order autocomplete results by&#039;),
    &#039;#description&#039; =&gt; t(&#039;Select the column name to order the autocomplete results by.&#039;),
    &#039;#default_value&#039; =&gt; variable_get(&#039;node_block_sql_order&#039;, &#039;nid&#039;),
    &#039;#required&#039; =&gt; TRUE,
    &#039;#options&#039; =&gt; array(&#039;nid&#039; =&gt; t(&#039;Node ID&#039;), &#039;title&#039; =&gt; t(&#039;Node title&#039;), &#039;type&#039; =&gt; t(&#039;Node type&#039;)),
  );
  $form[&#039;node_block_sql_sort&#039;] = array(
    &#039;#type&#039; =&gt; &#039;select&#039;,
    &#039;#title&#039; =&gt; t(&#039;Order of autocomplete results&#039;),
    &#039;#description&#039; =&gt; t(&#039;The order in which autocomplete results will be ordered.&#039;),
    &#039;#default_value&#039; =&gt; variable_get(&#039;node_block_sql_sort&#039;, &#039;ASC&#039;),
    &#039;#options&#039; =&gt; array(&#039;ASC&#039; =&gt; t(&#039;Ascending&#039;), &#039;DESC&#039; =&gt; t(&#039;Descending&#039;)),
    &#039;#required&#039; =&gt; TRUE,
  );
  $form[&#039;node_block_autocomplete_limit&#039;] = array(
    &#039;#type&#039; =&gt; &#039;textfield&#039;,
    &#039;#title&#039; =&gt; t(&#039;Amount of results to display in autocomplete&#039;),
    &#039;#description&#039; =&gt; t(&#039;Enter the amount of results to appear in the autocomplete when selecting a node.&#039;),
    &#039;#required&#039; =&gt; TRUE,
    &#039;#default_value&#039; =&gt; variable_get(&#039;node_block_autocomplete_limit&#039;, 25),
    &#039;#size&#039; =&gt; 5,
  );
  return system_settings_form($form);
}</pre>
<p>To get a list of nodes types, you can run your own custom SQL query, but it is a lot easier to use Drupal&#8217;s built in node_get_types() function. If you pass along &#8216;types&#8217; as the first argument, you will get a lot more information, but all we need is the node type machine name and the display name.  node_get_types(&#8216;names&#8217;) does exactly this with an associative array with the key being the machine name and the value being the display name.</p>
<p>The rest of the form is very simple, giving the administrator full control over the ordering of the autocomplete which users will select their node from.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/admin_settings.jpg" alt="" title="Administration form" width="560" height="601" class="alignnone size-full wp-image-1259" /></p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>We now have our admin form set up, so now it is time to create the configuration form for the users when adding a new block. Again we hook in to the Block API, this time using hook_block_api_form($config, $edit).</p>
<pre class="brush: php">function node_block_block_api_form($config, $edit) {
  if ($config[&#039;block_type&#039;] == &#039;node_block&#039;) {
    $form[&#039;nid&#039;] = array(
      &#039;#type&#039; =&gt; &#039;textfield&#039;,
      &#039;#title&#039; =&gt; t(&#039;Node ID&#039;),
      &#039;#description&#039; =&gt; t(&#039;Start typing the title of the node and select it from the autocomplete list.&#039;),
      &#039;#required&#039; =&gt; TRUE,
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;nid&#039;],
      &#039;#autocomplete_path&#039; =&gt; &#039;js/node_block/autocomplete&#039;,
    );
    $form[&#039;teaser&#039;] = array(
      &#039;#type&#039; =&gt; &#039;select&#039;,
      &#039;#title&#039; =&gt; t(&#039;Show the Teaser or full node&#039;),
      &#039;#description&#039; =&gt; t(&#039;Select whether you would like just the teaser displayed in the block or the full node.&#039;),
      &#039;#default_value&#039; =&gt; $config[&#039;settings&#039;][&#039;teaser&#039;],
      &#039;#required&#039; =&gt; TRUE,
      &#039;#options&#039; =&gt; array(0 =&gt; t(&#039;Full node&#039;), 1 =&gt; t(&#039;Teaser&#039;)),
    );
  }
  return $form;
}</pre>
<p>Here we give the user two options.  The first is an autocomplete field to select the node and the second being a simple checkbox allowing the user to select whether they want to show the teaser of the node or the full node.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/block_settings.jpg" alt="" title="Block API - Block settings form" width="544" height="432" class="alignnone size-full wp-image-1258" /></p>
<p>To get the autocomplete working, we need to set up our autocomplete menu item and function to run the search query.</p>
<p>In your existing hook_menu(), add the following to create a menu callback for our autocomplete textfield.</p>
<pre class="brush: php">$items[&#039;js/node_block/autocomplete&#039;] = array(
    &#039;page callback&#039; =&gt; &#039;node_block_js_autocomplete&#039;,
    &#039;access callback&#039; =&gt; TRUE,
    &#039;type&#039; =&gt; MENU_CALLBACK,
  );</pre>
<p>A very simple callback, no need for a title or description and access is open to everyone, although you could limit it to the users who are able to create blocks.</p>
<p>Next we need to set up the SQL query that will fetch the nodes based on the users input.</p>
<pre class="brush: php">function node_block_js_autocomplete() {
  $str = $_POST[&#039;nid&#039;];
  $sql = &quot;SELECT nid, title FROM {node} WHERE LOWER(title) LIKE LOWER(&#039;%%%s%%&#039;)&quot;;
  foreach (variable_get(&#039;node_block_content_types&#039;, &#039;&#039;) as $type =&gt; $value) {
    if (strlen($value) &gt; 1) $types[] = &#039;&quot;&#039;. $type .&#039;&quot;&#039;;
  }
  $sql .= &quot; AND type IN (&quot;. implode(&quot;, &quot;, $types) .&quot;)&quot;;
  if (variable_get(&#039;node_block_published_only&#039;, 1) == 1) {
    $sql .= &quot; AND status = 1&quot;;
  }
  $sql .= &quot; ORDER BY &quot;. variable_get(&#039;node_block_sql_order&#039;, &#039;nid&#039;) .&quot; &quot;. variable_get(&#039;node_block_sql_sort&#039;, &#039;ASC&#039;);
  $sql .= &quot; LIMIT 0, &quot;. variable_get(&#039;node_block_autocomplete_limit&#039;, 25);
  $query = db_query($sql, filter_xss($str));
  $results = array();
  while ($data = db_fetch_object($query)) {
    $results[$data-&gt;nid] = check_plain($data-&gt;title);
  }
  print drupal_to_js($results);
}</pre>
<p>We get the users current inputted text from $_POST and set up the basic SQL. As we gave the administrator the chance to limit the options available, we must now apply those filters. First we make sure the query only gets results for the right content types, then check for only published nodes if defined by the administrator. The next few lines are for the autocomplete ordering and limiting the amount of results.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<p>We now have our two admin forms configured, the only bit remaining is showing the block on the page.  This is done by using hook_block_api_view().</p>
<pre class="brush: php">function node_block_block_api_view($config) {
  if ($config[&#039;block_type&#039;] == &#039;node_block&#039;) {
    $node = node_load($config[&#039;settings&#039;][&#039;nid&#039;]);
    if ($node-&gt;status == 0 &amp;&amp; variable_get(&#039;node_block_published_only&#039;, 1) == 1) return FALSE;
    $output = node_view($node, $config[&#039;settings&#039;][&#039;teaser&#039;] == 1 ? TRUE : FALSE);
  }
  return array(&#039;content&#039; =&gt; $output);
}</pre>
<p>First, we load the node using the NID saved from our form by Block API.  It is probably best to add some code in to make sure that a node ID has been saved either at view stage or when saving the block.</p>
<p>Next we make sure the node is not unpublished if the administrator has defined that only published nodes can be shown as blocks.</p>
<p>Then we use the function node_view() to display the node. The second argument is the $teaser argument. If TRUE it will display the teaser of the node, otherwise the full node will be published.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/07/block_view.jpg" rel="shadowbox[post-1252];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/07/block_view-300x163.jpg" alt="" title="Block API - Block View" width="300" height="163" class="alignnone size-medium wp-image-1260" /><br /><small>Click for larger image</small></a></p>
<p>You may also want to hide the node block if you are viewing the node page itself, so adding a line after the status line such as:</p>
<pre class="brush: php">if (arg(0) == &#039;node&#039; &amp;&amp; arg(1) == $config[&#039;settings&#039;][&#039;nid&#039;]) return FALSE;</pre>
<p>And that is it.  You will now be able to create blocks </p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-07-05/displaying-nodes-as-blocks-using-block-api/1252/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Create a multi-step moderation process in Drupal 6</title>
		<link>http://jamestombs.co.uk/2010-06-30/create-a-multi-step-moderation-process-in-drupal-6/1189</link>
		<comments>http://jamestombs.co.uk/2010-06-30/create-a-multi-step-moderation-process-in-drupal-6/1189#comments</comments>
		<pubDate>Wed, 30 Jun 2010 14:02:25 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1189</guid>
		<description><![CDATA[This will guide you through creating a multi-step process of content moderation in Drupal 6. This is a follow on to the guide on Drupal.org about creating a revisioning system and the follow on, on creating a revisioning system with state-based access. Both of which only allow a single step revisioning sytem, i.e. Author creates [...]]]></description>
			<content:encoded><![CDATA[<p>This will guide you through creating a multi-step process of content moderation in Drupal 6. This is a follow on to the guide on Drupal.org about creating a <a href="http://drupal.org/node/408968">revisioning system</a> and the follow on, on creating a <a href="http://drupal.org/node/408052">revisioning system with state-based access</a>. Both of which only allow a single step revisioning sytem, i.e. Author creates content, moderator either edits and publishes or sends back to author to edit.</p>
<h3>Scenario</h3>
<p>A user submits a piece of content, we will refer to this user as the author. The content is not published and is sent to another user for moderation, we will refer to this user as the moderator.</p>
<p>The moderator can then either set the content from a moderation state back to a draft state for the author to amend or through to a &#8220;to be published state&#8221;.</p>
<p>Once the moderator has checked the content and made amends they can mark the content as ready for publishing.  At which point a third user which we will refer to as the publisher, can make further amends to the content and publish it, make further amends and send back to the moderator to check through the changes or mark the content as back to draft to allow the author to change it.<br />
<span id="more-1189"></span></p>
<h3>Required modules</h3>
<p>A few contributed modules are required to get this process in place as well as a couple of core modules.</p>
<ul>
<li>Trigger (Core, optional)</li>
<li>Profile (Core)</li>
<li><a href="http://drupal.org/project/module_grants">Module Grants</a> (Contrib)</li>
<li><a href="http://drupal.org/project/smart_menus">Smart tabs</a> (Contrib)</li>
<li><a href="http://drupal.org/project/revisioning">Revisioning</a> (Contrib)</li>
<li><a href="http://drupal.org/project/token">Token</a> (Contrib)</li>
<li><a href="http://drupal.org/project/workflow">Workflow</a> (Contrib)</li>
<li><a href="http://drupal.org/project/diff">Diff</a> (Contrib, optional)</li>
</ul>
<p>The <a href="http://drupal.org/project/diff">Diff module</a> is optional, but can be useful to easily see what parts of the content have changed from each revision.</p>
<h3>Enable modules</h3>
<p>Some of the modules have sub-modules which come with the main module, so be sure to check all the required modules, which are:</p>
<ul>
<li>Module Grants</li>
<li>Module Grants Monitor (Optional)</li>
<li>Node Tools</li>
<li>User Tools</li>
<li>Profile</li>
<li>Trigger (Optional)</li>
<li>Smart tabs</li>
<li>Diff (Optional)</li>
<li>Revisioning</li>
<li>Token</li>
<li>Token actions</li>
<li>Workflow</li>
<li>Workflow access</li>
</ul>
<p>If you already have content on your site, you will also need to download and install <a href="http://drupal.org/project/workflow_post_install">Workflow Post Install</a>, otherwise all old content may only be accessible by administrator.</p>
<h3>Create user roles</h3>
<p>You can have as many different roles to allow more fine grained control over who can create what content types, but to try and keep this tutorial as simple as possible, I will stick to the three main roles defined in the scenario.</p>
<ul>
<li>Author</li>
<li>Moderator</li>
<li>Publisher</li>
</ul>
<p>It may be best to give your author role a different role name as the Workflow module automatically adds a line in the admin for &#8220;author&#8221; which applies to any role creating content.</p>
<p>Go to Administer &gt; User management &gt; Roles (admin/user/roles).</p>
<p>Then add your three roles, I will be using author role, moderator role and publisher role.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/roles.jpg" alt="" title="User roles" width="470" height="198" class="alignnone size-full wp-image-1194" /></p>
<h3>Set up workflow settings</h3>
<p>Go to Administer &gt; Site building &gt; Workflow (admin/build/workflow).</p>
<p>Create a new Workflow and call it <strong>Moderation</strong>. </p>
<p>In the <strong>State name</strong> box, enter <em>in draft</em> and set the <strong>weight</strong> to <em>-10</em>. Save the state.</p>
<p>Once the state has saved, click the <strong>List</strong> tab and click the <strong>Add state</strong> link.</p>
<p>Add the following states:</p>
<ul>
<li>in moderation (weight: -2)</li>
<li>is moderated (weight: 2)</li>
<li>live (weight: 10)</li>
</ul>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow_states.jpg" alt="" title="Workflow states" width="428" height="238" class="alignnone size-full wp-image-1197" /></p>
<p>Underneath your states, you can apply the workflow to separate content types. I will be applying it to both the default content types (Page and Story).</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow_content-types.jpg" alt="" title="Workflow content types" width="470" height="181" class="alignnone size-full wp-image-1198" /></p>
<p>Next to the Moderation workflow, click the <strong>Edit</strong> link.</p>
<p>This page may seem a little daunting at first, but don&#8217;t panic. The first set of checkboxes allow you to set out which roles can transition the node between certain states. You will also see the extra &#8220;author&#8221; role that I refered to earlier.</p>
<p>The first row is for the original creation of the node.  This is the transition from the <strong>(creation)</strong> state to the <strong>in draft</strong> state. The only role we are giving access to this is the Workflow defined author, note that this is not the author role that we created.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-creation_to_draft.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-creation_to_draft-300x64.jpg" alt="" title="Workflow: Creation to draft" width="300" height="64" class="alignnone size-medium wp-image-1206" /><br /><small>Click for larger version</small></a></p>
<p>The next transition is from being <strong>in draft</strong> to <strong>in moderation</strong>. For this transition, we want to set this to our author role as opposed to the workflow defined author.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-draft_to_moderation.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-draft_to_moderation-300x64.jpg" alt="" title="Workflow: Draft to moderation" width="300" height="64" class="alignnone size-medium wp-image-1207" /><br /><small>Click for larger version</small></a></p>
<p>The next transition is from <strong>in moderation</strong> to <strong>is moderated</strong>.  This is our moderation step where the content is moderated prior to being sent back to the author for further amends or to the publisher for final approval and publishing. We want to set the moderator role under <strong>in draft</strong> and <strong>is moderated</strong>.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-moderation_to_moderated.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-moderation_to_moderated-300x64.jpg" alt="" title="Workflow: Moderation to moderated" width="300" height="64" class="alignnone size-medium wp-image-1208" /><br /><small>Click for larger version</small></a></p>
<p>Next is the step from being moderated to going to the publisher.  There are some optional transitions that you can put in here, depending on how you want to work.  The one that everyone would need is the transition from <strong>is moderated</strong> to <strong>live</strong>. The one that will differ is for rejections. Some people will want it to go back to draft, whereas others will want it to go back to moderator, others will want both options. This way if there isn&#8217;t a major problem, the content can be sent back to the moderator for further moderation rather than having to go back to the author only to be sent back to the moderator.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-moderated_to_live.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-moderated_to_live-300x64.jpg" alt="" title="Workflow: Moderated to live" width="300" height="64" class="alignnone size-medium wp-image-1209" /><br /><small>Click for larger version</small></a></p>
<p>The final transition is from the <strong>live</strong> state. The only role that needs this is our author role (not the workflow author role) to be able to take the content back to <strong>in draft</strong>. This will not change the live copy, but create an unpublished revision which we will set up in the next part of the tutorial.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-live.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-live-300x64.jpg" alt="" title="Workflow: Live" width="300" height="64" class="alignnone size-medium wp-image-1210" /><br /><small>Click for larger version</small></a></p>
<p>After the checkboxes, in the Comment for Workflow Log section, make sure both boxes are ticked to show a comment form in the Workflow and node edit screens to allow the roles to add their comments for the next role to read to understand why the amends were rejected or what was changed.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-comments.jpg" alt="" title="Workflow: Comments" width="507" height="214" class="alignnone size-full wp-image-1213" /></p>
<p>In the <strong>Workflow tab permissions</strong>, check our three roles.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-tab_permissions.jpg" alt="" title="Workflow: Tab permissions" width="507" height="250" class="alignnone size-full wp-image-1214" /></p>
<p>Next we have the Access control section.  These permissions allow you to set permissions to certain roles based on the state of the content (in draft, in moderation, is moderated, live). Take in to account that these permissions will be overridden by some of the permissions in the User management &gt; Permissions page which we will get on to later.</p>
<p>In the sections for each state, the <em>anonymous user</em> and <em>authenticated user</em> should stay ticked under <strong>Roles who can view posts in this state</strong>.</p>
<p>Under <strong>in draft</strong>, check our <strong>author role</strong> for <strong>Roles who can edit posts in this state</strong>.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-in_draft.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-in_draft-300x118.jpg" alt="" title="Workflow: Access control: In draft" width="300" height="118" class="alignnone size-medium wp-image-1215" /><br /><small>Click for larger version</small></a></p>
<p>Under <strong>in moderation</strong>, check our <strong>moderator role </strong>for <strong>Roles who can edit posts in this state</strong>.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-in_moderation.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-in_moderation-300x118.jpg" alt="" title="Workflow: Access control: In moderation" width="300" height="118" class="alignnone size-medium wp-image-1216" /><br /><small>Click for larger version</small></a></p>
<p>Under <strong>is moderated</strong>, check our <strong>publisher role</strong> for <strong>Roles who can edit posts in this state</strong>.<br />
<a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-is_moderated.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-access-is_moderated-300x118.jpg" alt="" title="Workflow: Access control: Is moderated" width="300" height="118" class="alignnone size-medium wp-image-1217" /><br /><small>Click for larger version</small></a></p>
<p>Leave the live state with only the default view options checked.</p>
<p>Press <strong>Save</strong>.<br />

<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<h3>Configure content types</h3>
<p>Go to Administer &gt; Content management &gt; Content types (admin/content/types).</p>
<p>Click the <strong>Edit</strong> link next to the content type you wish you apply the moderation workflow.</p>
<p>Under the <strong>Workflow settings</strong>, uncheck the <strong>Published</strong> box as we don&#8217;t want to publish the content until it has been moderated and approved.</p>
<p>Check both the <strong>Create new revision</strong> and <strong>New revision in draft, pending moderation (requires &#8220;Create new revision&#8221;)</strong> boxes to create a revision for each modification of the content.</p>
<p>Under <strong>Create new revision</strong>, it is up to you what setting you use, but remember to read the description text below the options.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-settings.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/workflow-settings-300x217.jpg" alt="" title="Content types: Workflow settings" width="300" height="217" class="alignnone size-medium wp-image-1218" /><br /><small>Click here for larger version</small></a></p>
<p>If you have the Diff module enabled, you will get the additional option <strong>Show Preview changes button on node edit form</strong> which will allow you to see the difference between the current edits and the current revision.</p>
<p>Repeat this step for all content types that you wish to have moderation enabled for.<br />

<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<h3>Set up user permissions</h3>
<p>Go to Administer &gt; User management &gt; Permissions (admin/user/permissions).</p>
<p>Under the <strong>module_grants_monitor module</strong> section. Tick the boxes <strong>access All tab</strong>, <strong>access I Can Edit tab</strong> and <strong>access I Can View tab</strong> for the <strong>moderator role</strong>. For the publisher role, you can tick the same boxes plus <strong>access Published tab</strong> and <strong>access Unpublished tab</strong>.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-module_grants_monitor.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-module_grants_monitor-300x109.jpg" alt="" title="Permissions: Module_grants_monitor" width="300" height="109" class="alignnone size-medium wp-image-1221" /><br /><small>Click for larger version</small></a></p>
<p>Under <strong>node module</strong>, make sure <strong>anonymous user</strong> and <strong>authenticated user</strong> are both checked for <strong>access content</strong>.</p>
<p>For <strong>author role</strong>, tick the boxes to allow them to create content of selected content types as well as being able to edit their own content.</p>
<p>For the <strong>moderator</strong> and <strong>publisher roles</strong>, allow them to edit any content as well as view or revert any revisions, but if you want further control over this, you can set this later on in the revisioning section.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-node.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-node-300x215.jpg" alt="" title="Permissions: Node" width="300" height="215" class="alignnone size-medium wp-image-1222" /><br /><small>Click for larger version</small></a></p>
<p>Under <strong>revisioning module</strong>, give the <strong>author role</strong> the ability to <strong>view revision status messages</strong> and to <strong>edit revisions of their own content</strong>. Moderators should have permission to <strong>access Pending tab</strong>, <strong>edit revisions</strong> and <strong>view revision status messages</strong>. The <strong>publisher role</strong> should have the same permissions as the <strong>moderator role</strong>, but should also have <strong>unpublish current revisio</strong>n and <strong>publish revisions</strong>.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-revisioning.jpg" rel="shadowbox[post-1189];player=img;"><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/permissions-revisioning-300x173.jpg" alt="" title="Permissions: Revisioning" width="300" height="173" class="alignnone size-medium wp-image-1226" /><br /><small>Click for larger version</small></a></p>
<p>Press Save.</p>
<h3>Set up email triggers</h3>
<p>For information on setting up and using <a href="http://drupal.org/node/199254">Triggers and Actions in Drupal 6</a>, it is best to read the excellent page on the Drupal.org website at <a href="http://drupal.org/node/199254">http://drupal.org/node/199254</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-06-30/create-a-multi-step-moderation-process-in-drupal-6/1189/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>New Drupal module &#8211; Block API</title>
		<link>http://jamestombs.co.uk/2010-06-30/new-drupal-module-block-api/1245</link>
		<comments>http://jamestombs.co.uk/2010-06-30/new-drupal-module-block-api/1245#comments</comments>
		<pubDate>Wed, 30 Jun 2010 13:25:31 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[block api]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1245</guid>
		<description><![CDATA[I have created a new module for Drupal 6 called Block API which is available on Drupal.org. Block API is a new module I have developed for Drupal 6 which gives greater control over block templates much like you do with nodes. More information is available on my Block API page under Projects. Developer information [...]]]></description>
			<content:encoded><![CDATA[<p>I have created a new module for Drupal 6 called <a href="http://drupal.org/project/block_api">Block API</a> which is available on <a href="http://drupal.org/project/block_api">Drupal.org</a>.</p>
<blockquote><p>Block API is a new module I have developed for Drupal 6 which gives greater control over block templates much like you do with nodes.</p></blockquote>
<p>More information is available on my <a href="http://jamestombs.co.uk/projects/block-api-module-drupal">Block API</a> page under <a href="http://jamestombs.co.uk/projects">Projects</a>.</p>
<p>Developer information on how to use the module is available on the <a href="http://jamestombs.co.uk/projects/block-api-module-drupal/block-api-developers-information">Block API Developer information</a> page.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-06-30/new-drupal-module-block-api/1245/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Creating a Drupal multisite enviroment using Drupal 6</title>
		<link>http://jamestombs.co.uk/2010-06-22/creating-a-drupal-multisite-enviroment-using-drupal-6/1135</link>
		<comments>http://jamestombs.co.uk/2010-06-22/creating-a-drupal-multisite-enviroment-using-drupal-6/1135#comments</comments>
		<pubDate>Tue, 22 Jun 2010 09:35:27 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1135</guid>
		<description><![CDATA[This guide will show you how to create a multisite environment using a shared user system with the user only needing to log in once, to be logged in to all the sites. I will be doing this using WAMP on a Windows XP machine, so some of the steps won&#8217;t work if you are [...]]]></description>
			<content:encoded><![CDATA[<p>This guide will show you how to create a multisite environment using a shared user system with the user only needing to log in once, to be logged in to all the sites.</p>
<p>I will be doing this using WAMP on a Windows XP machine, so some of the steps won&#8217;t work if you are using IIS or will differ if you are using a different setup.</p>
<p>The result we will be aiming for is a shared user system allowing the user to log in/out of 3 sites which I will use the following domains:</p>
<ul>
<li>http://www.local.com</li>
<li>http://community.local.com</li>
<li>http://support.local.com</li>
</ul>
<p><span id="more-1135"></span></p>
<h3>WAMP installation</h3>
<p>Download and install the latest version of <a href="http://www.wampserver.com/en/download.php">WAMP</a> from the <a href="http://www.wampserver.com/en/download.php">WAMP website</a>. The latest version comes with PHP 5.3 which has problems with Drupal 6, so you will also need to download and install PHP 5.2.x from the <a href="http://www.wampserver.com/en/addons_php.php">WAMP Addons page</a> once WAMP is installed.</p>
<p>Once WAMP and PHP 5.2.x have been installed and WAMP has restarted, left click the WAMP icon in the system tray and go to PHP > PHP Version and select the 5.2.x version you downloaded.</p>
<p><img src="http://jamestombs.co.uk/wp-content/uploads/2010/06/php5.jpg" alt="" title="Select PHP 5.2.x from the versions list" width="312" height="240" class="alignnone size-full wp-image-1136" /></p>
<p>Left click the WAMP icon again and this time select <strong>Apache</strong> > <strong>Apache Modules</strong> and scroll down and select <strong>rewrite_module</strong> and <strong>vhost_alias_module</strong>.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<h3>WAMP Virtual Hosts set up</h3>
<p>Again, left click the WAMP icon and go to Apache then select <strong>httpd.conf</strong>.</p>
<p>Scroll down to the bottom of this file and look for the following lines:<br />
<code># Virtual hosts<br />
# Include conf/extra/httpd-vhosts.conf</code></p>
<p>Remove the comment from the beginning of the second line to end up with this:<br />
<code># Virtual hosts<br />
Include conf/extra/httpd-vhosts.conf</code></p>
<p>Save and close the file.</p>
<p>Now in Explorer, navigate to the <em>WAMP directory\bin\bin\apache\Apache2.2.11\conf\extra\</em> directory.</p>
<p>Open the <strong>httpd-vhosts.conf</strong> file with your favourite text editor.</p>
<p>Replace the contents of this file with the following:</p>
<p><code>NameVirtualHost *:80<br />
#<br />
# VirtualHost example:<br />
# Almost any Apache directive may go into a VirtualHost container.<br />
# The first VirtualHost section is used for all requests that do not<br />
# match a ServerName or ServerAlias in any &lt;VirtualHost&gt; block.<br />
#<br />
&lt;VirtualHost *:80&gt;<br />
    ServerAdmin webmaster@localhost<br />
    DocumentRoot &quot;c:/wamp/www/&quot;<br />
    ServerName www.local.com<br />
    ErrorLog &quot;logs/local-www-error.log&quot;<br />
    CustomLog &quot;logs/local-www-access.log&quot; common<br />
    &lt;directory &quot;c:/wamp/www/&quot;&gt;<br />
        Options Indexes FollowSymLinks<br />
        AllowOverride all<br />
        Order Deny,Allow<br />
        Deny from all<br />
        Allow from 127.0.0.1<br />
    &lt;/directory&gt;<br />
&lt;/VirtualHost&gt;<br />
&lt;VirtualHost *:80&gt;<br />
    ServerAdmin webmaster@localhost<br />
    DocumentRoot &quot;c:/wamp/www/&quot;<br />
    ServerName community.local.com<br />
    ErrorLog &quot;logs/local-com.localhost-error.log&quot;<br />
    CustomLog &quot;logs/local-com.localhost-access.log&quot; common<br />
    &lt;directory &quot;c:/wamp/www/&quot;&gt;<br />
        Options Indexes FollowSymLinks<br />
        AllowOverride all<br />
        Order Deny,Allow<br />
        Deny from all<br />
        Allow from 127.0.0.1<br />
    &lt;/directory&gt;<br />
&lt;/VirtualHost&gt;<br />
&lt;VirtualHost *:80&gt;<br />
    ServerAdmin webmaster@localhost<br />
    DocumentRoot &quot;c:/wamp/www/&quot;<br />
    ServerName support.local.com<br />
    ErrorLog &quot;logs/local-sup.localhost-error.log&quot;<br />
    CustomLog &quot;logs/local-sup.localhost-access.log&quot; common<br />
    &lt;directory &quot;c:/wamp/www/&quot;&gt;<br />
        Options Indexes FollowSymLinks<br />
        AllowOverride all<br />
        Order Deny,Allow<br />
        Deny from all<br />
        Allow from 127.0.0.1<br />
    &lt;/directory&gt;<br />
&lt;/VirtualHost&gt;</code></p>
<p>This sets up 3 virtual hosts all using the same directory for the files, as we are using a shared codebase. This is also set up to only allow traffic from the localhost. To make the site public to all, change the line:</p>
<p><code>Allow from 127.0.0.1</code></p>
<p>To:</p>
<p><code>Allow from all</code></p>
<p>Save and close the file.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<h3>HOSTS set up</h3>
<p>The local.com domain already exist, so we need to overwrite the IP address where it points to be the local computer in the HOSTS file. We do this by editing the HOSTS file which on Windows is located in the following directory:</p>
<p><em>C:\WINDOWS\system32\drivers\etc</em></p>
<p>The HOSTS file has no file extension. So open it up in Notepad and add the following line at the very bottom:</p>
<p><code>127.0.0.1 www.local.com community.local.com support.local.com</code></p>
<p>Save the file, but make sure you don’t add a .txt extension.</p>
<p>You will need to close all your browser windows and in some cases restart the computer for the changes to take effect.</p>
<p>Open a new browser window and try to navigate to www.local.com, you should now get the WAMP welcome screen.</p>
<h3>Create a database in MySQL</h3>
<p>Using which ever MySQL admin tool you prefer, create a new database to use for Drupal. If using WAMP, you can use PHPMyAdmin by navigating to http://localhost/phpmyadmin/</p>
<p>By default MySQL has no password in WAMP.</p>
<h3>Download and set up Drupal</h3>
<p>Download the latest version of Drupal 6 which at the time of writing is <a href="http://drupal.org/drupal-6.17">Drupal 6.17</a>.</p>
<p>Extract the files and subfolders to the <em>C:\wamp\www</em> directory overwriting the existing <strong>index.php</strong> when asked. If you are not asked to overwrite the <strong>index.php</strong> file, you have tried to extract the files at the wrong directory level.</p>
<p>Navigate to the <em>/sites/</em> directory and copy the default directory twice and rename the 2 new directories <strong>support.local.com</strong> and <strong>community.local.com</strong>.</p>
<p>Navigate in your browser to <em>www.local.com</em>, you should get the Drupal installation screen. Follow the screens through and install Drupal how you normally would. Once installation has finished and you are at the Welcome screen, navigate to <em>support.local.com</em>.</p>
<p>During installation, add a database prefix as <strong>support_</strong> and continue with installation.</p>
<p>Once at the welcome screen, do the same with <em>community.local.com</em> but this time using the prefix <strong>comm_</strong>.</p>
<h3>Configure Drupal for multisite by modifying settings.php</h3>
<p>In the /sites/ directory there are now 4 directories.</p>
<p>- all<br />
- community.local.com<br />
- default<br />
- support.local.com</p>
<p>The default directory is used for www.local.com, the other 2 xxx.local.com directories should be self explanitory and the all directory is present for modules and themes.</p>
<p>Open up the settings.php file in the default directory.</p>
<p>Around a quater of the way down the file (around line 93 for most people) there is a line for $db_prefix, if you didn’t set one it should just say:</p>
<p><code>$db_prefix = '';</code></p>
<p>Scroll 3 quaters down (around line 169) and uncomment the line:</p>
<p><code># $cookie_domain = 'example.com';</code></p>
<p>And change to:</p>
<p><code>$cookie_domain = '.local.com';</code></p>
<p>This will share the session cookie across all subdomains of local.com</p>
<p>Save and close the file.</p>
<p>Now open up <strong>settings.php</strong> from within the community.local.com directory.</p>
<p>Scroll down to line 93 and replace with the following:</p>
<p><code>$db_prefix = array(<br />
  'default' => 'comm_',<br />
  'users' => '',<br />
  'sessions' => '',<br />
  'role' => '',<br />
  'authmap' => '',<br />
  'users_roles' => '',<br />
  'profile_fields' => '',<br />
  'profile_values' => '',<br />
);</code></p>
<p>Save and close the file.</p>
<p>And again, scroll 3 quaters down (around line 169) and uncomment the line:</p>
<p><code># $cookie_domain = 'example.com';</code></p>
<p>And change to:</p>
<p><code>$cookie_domain = '.local.com';</code></p>
<p>Repeat the same for support.local.com, although this time set the default $db_prefix to <strong>support_</strong>.</p>
<p>Save and close the file.</p>
<p>Navigate to each site in the browser and log out of each site. Now log in to <em>www.local.com</em>. Now if you navigate to <em>support.local.com</em>, you should be logged in, same with <em>community.local.com</em>.</p>
<p>We now have 3 sites with a shared user base and a single signon. As you may be able to tell from the $db_prefix array above, we are sharing the users table as well as sessions which keeps the user data and log in data the same across all the sites. We also share the role and users_roles tables to be able to set multi-sitewide roles as well as the profile tables so that the user doesn’t have to type any information over and over again.</p>
<p>
<!-- Begin Google Adsense code -->
<script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<!-- End Google Adsense code -->
</p>
<h3>Cleaning up unneeded MySQL tables</h3>
<p>Now in our database, we have redundant tables which aren’t doing anything and aren’t being used. We can now delete these to keep the database a bit tidier. Delete the following tables:</p>
<ul>
<li>support_users</li>
<li>support_sessions</li>
<li>support_role</li>
<li>support_authmap</li>
<li>support_users_roles</li>
<li>support_profile_fields</li>
<li>support_profile_values</li>
<li>comm_users</li>
<li>comm_sessions</li>
<li>comm_role</li>
<li>comm_authmap</li>
<li>comm_users_roles</li>
<li>comm_profile_fields</li>
<li>comm_profile_values</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-06-22/creating-a-drupal-multisite-enviroment-using-drupal-6/1135/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a grid of images for an album in Drupal 6 with pagination</title>
		<link>http://jamestombs.co.uk/2010-03-10/creating-a-grid-of-images-for-an-album-in-drupal-6-with-pagination/1106</link>
		<comments>http://jamestombs.co.uk/2010-03-10/creating-a-grid-of-images-for-an-album-in-drupal-6-with-pagination/1106#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:12:27 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1106</guid>
		<description><![CDATA[Following on from the original tutorial on creating a grid of images for an album in Drupal 6, a few people asked how to add pagination on to this for large albums. Unfortunately from what I can tell Drupal&#8217;s pagination function only works with SQL queries so we are unable to use the existing data [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from the original tutorial on <a href="http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-album-in-drupal/1046">creating a grid of images for an album in Drupal 6</a>, a few people asked how to add pagination on to this for large albums.</p>
<p>Unfortunately from what I can tell Drupal&#8217;s pagination function only works with SQL queries so we are unable to use the existing data available in the node object.  But due to Drupal&#8217;s nice database schema, it is very simple to write some simple SQL to give us the pager.</p>
<p><span id="more-1106"></span></p>
<p>Below is the full code and below the code I will explain what each part does.</p>
<pre class="brush: php">&lt;?php
$count = count($node-&gt;field_images);
if ($count &gt; 0):
	$images_per_page = 9;
	$sql = &quot;SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = &quot;. $node-&gt;nid;
	$count = &quot;SELECT COUNT(f.fid) FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = &quot;. $node-&gt;nid;
	$query = pager_query($sql, $images_per_page, 0, $count);
	while ($data = db_fetch_object($query)) {
		$images[$data-&gt;fid] = array(
			&#039;filepath&#039; =&gt; $data-&gt;filepath,
			&#039;data&#039; =&gt; unserialize($data-&gt;field_images_data),
		);
	}
	$rows = array();
	$images_per_row = 3;
	$i = 0;
	$row = 0;
	foreach ($images as $image) {
		$rows[$row][$i] = &#039;&lt;a class=&quot;gallery-thumbs&quot; title=&quot;&#039;. htmlspecialchars($image[&#039;data&#039;][&#039;description&#039;]) .&#039;&quot; rel=&quot;lightbox[photo_gallery-&#039;. $node-&gt;nid .&#039;]&quot; href=&quot;&#039;. imagecache_create_url(&#039;lightbox&#039;, $image[&#039;filepath&#039;]) .&#039;&quot;&gt;&#039;. theme(&#039;imagecache&#039;, &#039;thumbnail&#039;, $image[&#039;filepath&#039;], $image[&#039;data&#039;][&#039;title&#039;], $image[&#039;data&#039;][&#039;title&#039;]) .(trim($image[&#039;data&#039;][&#039;description&#039;]) != &#039;&#039; ? &#039;&lt;br /&gt;&lt;small&gt;&#039;. $image[&#039;data&#039;][&#039;description&#039;] .&#039;&lt;/small&gt;&lt;/a&gt;&#039; : &#039;&#039;);
		$i++;
		if ($i == $images_per_row) {
			$row++;
			$i = 0;
		}
	}
	?&gt;
  &lt;table class=&quot;views-view-grid&quot;&gt;
    &lt;tbody&gt;
      &lt;?php foreach ($rows as $row_number =&gt; $columns): ?&gt;
        &lt;?php
          $row_class = &#039;row-&#039; . ($row_number + 1);
          if ($row_number == 0) {
            $row_class .= &#039; row-first&#039;;
          }
          elseif (count($rows) == ($row_number + 1)) {
            $row_class .= &#039; row-last&#039;;
          }
        ?&gt;
        &lt;tr class=&quot;&lt;?php print $row_class; ?&gt;&quot;&gt;
          &lt;?php foreach ($columns as $column_number =&gt; $item): ?&gt;
            &lt;td class=&quot;&lt;?php print &#039;col-&#039;. ($column_number + 1); ?&gt;&quot;&gt;
              &lt;?php print $item; ?&gt;
            &lt;/td&gt;
          &lt;?php endforeach; ?&gt;
        &lt;/tr&gt;
      &lt;?php endforeach; ?&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
  &lt;?php print theme(&#039;pager&#039;, array(), $images_per_page, 0); ?&gt;
&lt;?php else: ?&gt;
  &lt;p&gt;No images in album&lt;/p&gt;
&lt;?php endif; ?&gt;</pre>
<p>First thing we do is check to see if there are any images.  Rather than doing a SQL query to get the result, I have chosen to use the already existing array of images in the node object.</p>
<pre class="brush: php">$count = count($node-&gt;field_images);</pre>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
/* 336x280, created 3/31/10 */
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>Then as before we check to make sure we have images, then create our query to generate the pager.</p>
<pre class="brush: php">$images_per_page = 9;
	$sql = &quot;SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = &quot;. $node-&gt;nid;
	$count = &quot;SELECT COUNT(f.fid) FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = &quot;. $node-&gt;nid;
	$query = pager_query($sql, $images_per_page, 0, $count);
	while ($data = db_fetch_object($query)) {
		$images[$data-&gt;fid] = array(
			&#039;filepath&#039; =&gt; $data-&gt;filepath,
			&#039;data&#039; =&gt; unserialize($data-&gt;field_images_data),
		);
	}</pre>
<p>In the query, we are gathering the file id (fid) of each individual image, the field_images_data which is a serializd array of the title, description and alt text of the image from when it was uploaded and the filepath of the image.  The count isn&#8217;t necessarily needed, but I have found the pager can act oddly when the $count part of <em>pager_query()</em> is missing.</p>
<p><em>pager_query()</em> also requires 2 other elements. The first after $sql, is the amount of rows to be taken out the database.  The next number is the element number.  This is needed for pages with multiple pagers on them.  If you have got multiple pagers and experience trouble then you will need to change this.</p>
<p>Then from this we recreate the $images array that we had before, although it is missing some information which is provided through the $node object, it provides everything that we need to display the image on the page.</p>
<p>The whole table HTML section remains untouched, but it is followed by an extra line:</p>
<pre class="brush: php">&lt;?php print theme(&#039;pager&#039;, array(), $images_per_page, 0); ?&gt;</pre>
<p>This prints out the Drupal pager below out table of images.  This can be used multiple times on a page, so you can have some pagination below and above the table of images.</p>
<p>If the page you are displaying the albums on already has pagers, you may need to change the 0 in both the <em>theme_pager()</em> and <em>pager_query()</em>.</p>
<p>You should now have a fully working grid with pagination.</p>
<p><strong>Edit:</strong> As pointed out by dukat in the comments, you can change the original SQL query to the following to keep the images in the order defined in the node.</p>
<pre class="brush: php">$sql = &quot;SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = &quot;. $node-&gt;nid .&quot; ORDER BY i.delta ASC&quot;;</pre>
<p>Obviously you can change the order between ASC or DESC.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-03-10/creating-a-grid-of-images-for-an-album-in-drupal-6-with-pagination/1106/feed</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Create a Drupal 6 theme based on the Zen starter theme</title>
		<link>http://jamestombs.co.uk/2010-01-11/create-a-drupal-6-theme-based-on-the-zen-starter-theme/1083</link>
		<comments>http://jamestombs.co.uk/2010-01-11/create-a-drupal-6-theme-based-on-the-zen-starter-theme/1083#comments</comments>
		<pubDate>Mon, 11 Jan 2010 21:08:55 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1083</guid>
		<description><![CDATA[What is Zen? Taken from the Zen project page: Zen is the ultimate starting theme for Drupal. If you are building your own standards-compliant theme, you will find it much easier to start with Zen than to start with Garland or Bluemarine. This theme has fantastic online documentation and tons of code comments for both [...]]]></description>
			<content:encoded><![CDATA[<h3>What is Zen?</h3>
<p>Taken from the <a href="http://drupal.org/project/zen">Zen project page</a>:</p>
<blockquote><p><strong>Zen is the ultimate <em>starting theme</em> for Drupal.</strong> If you are building your own standards-compliant theme, you will find it much easier to start with Zen than to start with Garland or Bluemarine. This theme has <a href="http://drupal.org/node/193318">fantastic online documentation</a> and tons of code comments for both the PHP (template.php) and HTML (page.tpl.php, node.tpl.php).</p>
</blockquote>
<h3>Why use Zen?</h3>
<p>Zen gives a great framework for you to work from as a lot of the hard work in making the default Drupal CSS rules easier to customise as well as having a starter kit for you to modify giving you the basics to create your own theme without needed to mess around with the in&#8217;s and out&#8217;s of Drupals theming system.<br />
<span id="more-1083"></span></p>
<h3>Where do I get Zen?</h3>
<p>You can download Zen from the project page on <a href="http://drupal.org/project/zen">Drupal.org</a>. As of writing there are 2 versions available for Drupal 6; Zen 6.x-1.1 and Zen 6.x-2.0-beta1.  We will be using Zen 6.x-1.1 as it isn&#8217;t a good idea to use modules or themes that are in alpha, beta or RC on a production site.</p>
<h3>How do I install Zen?</h3>
<p>Once you have downloaded the file from Drupal.org you will need to extract the zen folder and place it in your /sites/all/themes directory.  You will need to create a directory called themes within the /sites/all directory if it doesn&#8217;t already exist. </p>
<p>If you need a program to extract the file from Drupal.org, I recommend you use <a href="http://www.7-zip.org/download.html">7-zip</a> which is a freeware application.</p>
<h3>How do I start using Zen?</h3>
<p>Within the Zen directory is a directory called STARTERKIT.  Copy this folder and return to the /sites/all/themes directory.  Paste the STARTERKIT directory from your clipboard into this directory. You should have a tree structure like the below:</p>
<pre>+ sites
|-+ all
| |-+ themes
| | |-- zen
| | |-- STARTERKIT</pre>
<p>Rename the STARTERKIT directory to the name you wish to give your theme.  This is the machine name that is used in the backend so you have to use lowercase characters and use underscores (_) instead of spaces.</p>
<p>For this tutorial we will name the theme drupal_theme, which gives us the following tree structure.</p>
<pre>+ sites
|-+ all
| |-+ themes
| | |-- zen
| | |-- drupal_theme</pre>
<p>Navigate within your drupal_theme directory and rename the file STARTERKIT.info.txt to yourthemename.info, in my case it will be drupal_theme.info.</p>
<p>Open the file in your editing program.</p>
<p>Change the name from <em>name = Zen Sub-theme Starter Kit</em> to <em>name = Your Theme Name</em> and change the description to a description of your theme.</p>
<p>Also change the <em>STARTERKIT.css</em> text to <em>yourthemename.css</em>, in my case it will be drupal_theme.css.</p>
<p>Save and close the file.</p>
<p>You need to make a choice as to whether you would like your theme to be a liquid layout, i.e. it will stretch the width of the browser so there is no whitespace on either side of the site or a fixed layout site where the site is a fixed width dependant of the browser window.</p>
<blockquote><p><strong>Liquid/adaptive width</strong></p>
<p>Copy the file <em>layout-liquid.css</em> from the /sites/all/themes/zen/zen directory to the /sites/all/themes/yourthemename directory. Then rename the file <em>layout.css</em></p>
<p><strong>Fixed width</strong></p>
<p>Copy the file <em>layout-fixed.css</em> from the /sites/all/themes/zen/zen directory to the /sites/all/themes/yourthemename directory. Then rename the file <em>layout.css</em></p></blockquote>
<p>Copy over the following CSS files from /sites/all/themes/zen/zen to your /sites/all/themes/yourthemename directory.</p>
<ul>
<li>zen.css</li>
<li>print.css</li>
<li>html-elements.css</li>
</ul>
<p>Rename the <em>zen.css</em> to <em>yourthemename.css</em>, in my case it will be <em>drupal_theme.css</em>.</p>
<p>In your theme folder, open and edit the files template.php and theme-settings.php, replacing all instanced of <em>STARTERKIT</em> with your theme name, so I replaced all instances of <em>STARTERKIT</em> with <em>drupal_theme</em>.</p>
<p>While logged in as a user with rights to the admin pages, navigate to Administer > Site building > Themes (admin/build/themes) and set your theme to default and save.</p>
<h3>How do I customise the theme?</h3>
<p>The structure of the page as in the way the sidebar, header, content, footer is layed out is mostly in the php files within the Zen theme and the CSS files we copied over to our theme folder allows us to change the styling of these items to make them appear the way we want.</p>
<h4>Change the font size</h4>
<p>The default font size is defined in the <em>html-elements.css</em> file.</p>
<pre class="brush: css">
  #page
  {
    /*
     * To use a 12px font size on the page, delete the 14px declarations.
     * to use a 14px font size on the page, delete the 12px declarations.
     */

    /* Use a 12px base font size with a 16px line height */
    font-size: 0.75em; /* 16px x .75 = 12px */
    line-height: 1.333em; /* 12px x 1.333 = 16px */

    /* Use a 14px base font size with a 18px line height */
    font-size: 0.875em; /* 16px x .875 = 14px */
    line-height: 1.286em; /* 14px x 1.286 = 18px */
  }
</pre>
<p>The #page rule is the wrapper that surrounds all the code.  So anything we apply to this will be applied to all elements under it unless they are overwritten later on in the CSS file.  By default the font size is set to 14px as it is the latter rule of the two. If you wish to reduce the font size to 12px, simply delete the last three lines (you can also delete the additional comments at the top of the rule), so you get the following:</p>
<pre class="brush: css">
  #page
  {
    /* Use a 12px base font size with a 16px line height */
    font-size: 0.75em; /* 16px x .75 = 12px */
    line-height: 1.333em; /* 12px x 1.333 = 16px */
  }
</pre>
<h4>How do I change the background colour?</h4>
<p>In the <em>yourthemename.css</em> file, change the body rule from:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
  }</pre>
<p>To:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
    background-color: #c00;
  }</pre>
<p>Where you change the colour to what ever you want. If you don&#8217;t know the hex value for the colour you want to use, you can use the RGB colour in the following format:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
    background-color: rgb(204, 0, 0);
  }</pre>
<p>Or you can find the hex colour in this <a href="http://www.webmonkey.com/reference/Color_Charts">hex colour reference chart</a>.</p>
<h4>How do I add an image to use as my background?</h4>
<p>In the <em>yourthemename.css</em> file, change the body rule from:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
  }</pre>
<p>To:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
    background: #fff url(background.jpg) top center repeat;
  }</pre>
<p>Place the image in your theme folder.  Alternatively if you want to keep your theme folder as tidy as possible, you can create a folder called images within your theme folder and change the CSS code to:</p>
<pre class="brush: css">
body
  {
    margin: 0;
    padding: 10px;
    background: #fff url(images/background.jpg) top center repeat;
  }</pre>
<p>If you chose a background image that makes the text hard to read, you can change the background colour of the #main element, which is the wrapper of all the main content excluding the header and footer, to white.</p>
<pre class="brush: css">
#main
  {
    background-color: #fff;
  }</pre>
<p>You can continue editing your theme by editing the CSS rules within the main CSS file (<em>yourthemename.css</em>).  For more references on CSS, check out the <a href="http://jamestombs.co.uk/2010-01-07/top-htmlcss-resources-for-beginners/1066">Top HTML/CSS resources for beginners</a> post.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2010-01-11/create-a-drupal-6-theme-based-on-the-zen-starter-theme/1083/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[Drupal] An error occured while attempting to process add Content Modal form</title>
		<link>http://jamestombs.co.uk/2009-07-16/drupal-an-error-occured-while-attempting-to-process-add-content-modal-form/1053</link>
		<comments>http://jamestombs.co.uk/2009-07-16/drupal-an-error-occured-while-attempting-to-process-add-content-modal-form/1053#comments</comments>
		<pubDate>Thu, 16 Jul 2009 10:21:07 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1053</guid>
		<description><![CDATA[When trying to add some content new a pane in Panels in Drupal 5 you may get this message. In my case it was caused by the Secure Pages module. To fix this add the following line to your Secure Pages configuration under Ignore pages: *ajax*]]></description>
			<content:encoded><![CDATA[<p>When trying to add some content new a pane in <a href="http://drupal.org/project/panels">Panels</a> in <a href="http://drupal.org/project/drupal">Drupal 5</a> you may get this message.</p>
<p>In my case it was caused by the <a href="http://drupal.org/project/securepages">Secure Pages</a> module.  To fix this add the following line to your <a href="http://drupal.org/project/securepages">Secure Pages</a> configuration under Ignore pages:</p>
<p><code>*ajax*</code></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-07-16/drupal-an-error-occured-while-attempting-to-process-add-content-modal-form/1053/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>No add button in IMCE in Drupal when using the Secure Pages module</title>
		<link>http://jamestombs.co.uk/2009-07-06/no-add-button-in-imce-in-drupal-when-using-the-secure-pages-module/1052</link>
		<comments>http://jamestombs.co.uk/2009-07-06/no-add-button-in-imce-in-drupal-when-using-the-secure-pages-module/1052#comments</comments>
		<pubDate>Mon, 06 Jul 2009 15:46:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1052</guid>
		<description><![CDATA[There may be cases where you are using IMCE with Drupal and have the IMCE appear on node add/edit pages which use a secure URL. You need to add the following to the ignore section of the Secure Pages module. imce* Go back to your node add/edit page and you should now have the add [...]]]></description>
			<content:encoded><![CDATA[<p>There may be cases where you are using IMCE with Drupal and have the IMCE appear on node add/edit pages which use a secure URL.  You need to add the following to the ignore section of the Secure Pages module.</p>
<p><code>imce*</code></p>
<p>Go back to your node add/edit page and you should now have the add button in IMCE.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-07-06/no-add-button-in-imce-in-drupal-when-using-the-secure-pages-module/1052/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Add a publish button on node edit forms in Drupal 6 using a custom module</title>
		<link>http://jamestombs.co.uk/2009-06-25/add-a-publish-button-on-node-edit-forms-in-drupal-6-using-a-custom-module/1050</link>
		<comments>http://jamestombs.co.uk/2009-06-25/add-a-publish-button-on-node-edit-forms-in-drupal-6-using-a-custom-module/1050#comments</comments>
		<pubDate>Thu, 25 Jun 2009 13:14:14 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1050</guid>
		<description><![CDATA[This tutorial assumes you have a reasonable knowledge of Drupal such as being able to create a custom module. It also requires an understanding of PHP and jQuery. Create a new module, I will call mine node_publish. The first thing I will do is create a callback function that will be used to publish the [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial assumes you have a reasonable knowledge of Drupal such as being able to create a custom module. It also requires an understanding of PHP and jQuery.</p>
<p><span id="more-1050"></span></p>
<p>Create a new module, I will call mine node_publish.</p>
<p>The first thing I will do is create a callback function that will be used to publish the node.  To do this, I will first create a menu item using hook_menu().</p>
<pre class="brush: php">
function node_publish_menu() {
  $items[&#039;node/%/publish&#039;] = array(
    &#039;title&#039; =&gt; &#039;Node published&#039;,
    &#039;page callback&#039; =&gt; &#039;node_publish_publish&#039;,
    &#039;page arguments&#039; =&gt; array(1),
    &#039;access arguments&#039; =&gt; array(&#039;administer nodes&#039;),
    &#039;type&#039; =&gt; MENU_CALLBACK,
  );
  return $items;
}
</pre>
<p>This uses the menu path of node/&lt;nid&gt;/publish, much the same way that node/&lt;nid&gt;/delete and node/&lt;nid&gt;/edit work. This will call the function node_publish_publish.</p>
<pre class="brush: php">
function node_publish_publish($nid) {
  if (is_numeric($nid)) {
    db_query(&quot;UPDATE {node} SET status = 1 WHERE nid = %d&quot;, $nid);
  }
  if (isset($_REQUEST[&#039;destination&#039;])) {
    drupal_goto($_REQUEST[&#039;destination&#039;]);
  }
  else {
    drupal_goto(&#039;node/&#039;. $nid);
  }
}
</pre>
<p>This function takes the nid out of the path and checks to make sure it is numeric, if it is we set the status to published for that node.</p>
<p>Once the node is published, we will redirect the user to another page.  In this case I have looked to see if a destination is already set, if so go to it, otherwise return to the node view.</p>
<p>Now you can create a link to node/&lt;nid&gt;/publish in any of your other modules or views which will publish the node.  But this tutorial is going to expand to adding a button on to the node edit form to allow you to publish, rather than having to check the Published box then press Submit.</p>
<pre class="brush: php">
function node_publish_form_alter(&amp;$form, $form_state, $form_id) {
  global $user;
  global $base_url;
  if (strstr($form_id, &#039;_node_form&#039;) &amp;&amp; $form[&#039;nid&#039;][&#039;#value&#039;] != &#039;&#039; &amp;&amp; $form[&#039;options&#039;][&#039;status&#039;][&#039;#default_value&#039;] == 0) {
    if (user_access(&#039;administer nodes&#039;)) {
      $form[&#039;buttons&#039;][&#039;publish&#039;] = array(
        &#039;#type&#039; =&gt; &#039;button&#039;,
        &#039;#value&#039; =&gt; &#039;Publish&#039;,
        &#039;#submit&#039; =&gt; FALSE,
        &#039;#attributes&#039; =&gt; array(
          &#039;onclick&#039; =&gt; &#039;return false;&#039;,
          &#039;style&#039; =&gt; &#039;display:none;&#039;,
        ),
      );
      drupal_add_js(&#039;$(document).ready(function() {
        $(&quot;#edit-publish&quot;).show();
        $(&quot;#edit-publish&quot;).click(function() {
          window.location = &quot;&#039;. $base_url .&#039;/node/&#039;. arg(1) .&#039;/publish&quot;;
          return false;
        });
      });&#039;, &#039;inline&#039;, &#039;footer&#039;);
    }
  }
}
</pre>
<p>The above should be self explanatory to most people, but for those that it isn&#8217;t:</p>
<p>First we get the data for the $user object and the $base_url of the site.  Then we check to make sure the form_id ends with _node_form as this will cover all nodes.  We then make sure that the $form array doesn&#8217;t have an empty nid value, if it does then the form is for a new node and shouldn&#8217;t feature the publish button.  We then check to make sure that the node isn&#8217;t already published, if it is there is no point in showing the publish button.</p>
<p>We then perform a check to make sure the user has access to publish nodes. If they have then we add in a simple button with an onclick attribute of return false, which will stop it acting like a submit button for users with javascript.  For users without javascript the style attribute will remove the button from view allowing the user to use the checkbox and press submit.</p>
<p>The jQuery that we have firsts shows the button, as it is hidden by default, then set up a click function for the button.  We direct the user to the publish page which will then take them to the node view.  Alternatively you can modify the jQuery to do a POST action and publish the node in the background and also check the published box allowing further modification of the node.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-06-25/add-a-publish-button-on-node-edit-forms-in-drupal-6-using-a-custom-module/1050/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a grid of images for an album in Drupal 6</title>
		<link>http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-album-in-drupal/1046</link>
		<comments>http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-album-in-drupal/1046#comments</comments>
		<pubDate>Thu, 25 Jun 2009 09:53:42 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=1046</guid>
		<description><![CDATA[Following on from the tutorial of creating an album based gallery in Drupal 6. This tutorial will teach you how to create a basic grid of the images in the node. Update: I have written an updated tutorial with code to allow you to have pagination on your grid of images. In your content type, [...]]]></description>
			<content:encoded><![CDATA[<p>Following on from the tutorial of <a href="http://jamestombs.co.uk/2009-05-12/create-an-album-based-image-gallery-in-drupal-6-using-cck-and-views/1045">creating an album based gallery in Drupal 6</a>. This tutorial will teach you how to create a basic grid of the images in the node.</p>
<p><strong>Update:</strong>  I have written an updated tutorial with code to allow you to have <a href="http://jamestombs.co.uk/2010-03-10/creating-a-grid-of-images-for-an-album-in-drupal-6-with-pagination/1106">pagination on your grid of images</a>.</p>
<p><span id="more-1046"></span></p>
<p>In your content type, go to Display fields and set the Full node to &lt;Hidden&gt;. This will take the images out of the <strong>$content</strong> variable.</p>
<p>Then in your theme, copy the existing node.tpl.php and create a new identical file called node-album.tpl.php (the album part with be the content type name that you used from the tutorial.)</p>
<p>Below the content section, add the following PHP code:</p>
<pre class="brush: php">&lt;?php
$images = $node-&gt;field_images;
if (count($images) &gt; 0):
  $rows = array();
  $images_per_row = 3;
  $i = 0;
  $row = 0;
  foreach ($images as $image) {
    $rows[$row][$i] = &#039;&lt;a class=&quot;gallery-thumbs&quot; title=&quot;&#039;. htmlspecialchars($image[&#039;data&#039;][&#039;description&#039;]) .&#039;&quot; rel=&quot;lightbox[photo_gallery-&#039;. $node-&gt;nid .&#039;]&quot; href=&quot;&#039;. imagecache_create_url(&#039;lightbox&#039;, $image[&#039;filepath&#039;]) .&#039;&quot;&gt;&#039;. theme(&#039;imagecache&#039;, &#039;thumbnail&#039;, $image[&#039;filepath&#039;], $image[&#039;data&#039;][&#039;title&#039;], $image[&#039;data&#039;][&#039;title&#039;]) .(trim($image[&#039;data&#039;][&#039;description&#039;]) != &#039;&#039; ? &#039;&lt;br /&gt;&lt;small&gt;&#039;. $image[&#039;data&#039;][&#039;description&#039;] .&#039;&lt;/small&gt;&lt;/a&gt;&#039; : &#039;&#039;);
    $i++;
    if ($i == $images_per_row) {
      $row++;
      $i = 0;
    }
  }
?&gt;
&lt;table class=&quot;views-view-grid&quot;&gt;
  &lt;tbody&gt;
    &lt;?php foreach ($rows as $row_number =&gt; $columns): ?&gt;
      &lt;?php
        $row_class = &#039;row-&#039; . ($row_number + 1);
        if ($row_number == 0) {
          $row_class .= &#039; row-first&#039;;
        }
        elseif (count($rows) == ($row_number + 1)) {
          $row_class .= &#039; row-last&#039;;
        }
      ?&gt;
      &lt;tr class=&quot;&lt;?php print $row_class; ?&gt;&quot;&gt;
        &lt;?php foreach ($columns as $column_number =&gt; $item): ?&gt;
          &lt;td class=&quot;&lt;?php print &#039;col-&#039;. ($column_number + 1); ?&gt;&quot;&gt;
            &lt;?php print $item; ?&gt;
          &lt;/td&gt;
        &lt;?php endforeach; ?&gt;
      &lt;/tr&gt;
    &lt;?php endforeach; ?&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;?php else: ?&gt;
  &lt;p&gt;No images in album&lt;/p&gt;
&lt;?php endif; ?&gt;
</pre>
<p>The table code is a direct copy from views-view-grid.tpl.php so the code should look identical to the Album view.</p>
<p>Replace the following with your own settings:</p>
<pre class="brush: php">imagecache_create_url(&#039;lightbox&#039;, $image[&#039;filepath&#039;])</pre>
<p>Change lightbox for the name of the imagecache preset that should open up within the lightbox.</p>
<pre class="brush: php">theme(&#039;imagecache&#039;, &#039;thumbnail&#039;, $image[&#039;filepath&#039;], $image[&#039;title&#039;], $image[&#039;title&#039;])</pre>
<p>Change thumbnail to the name of the imagecache preset that should be displayed.</p>
<p>To add more columns to your grid, change the <strong>$images_per_row</strong> variable.</p>
<p><strong>Update:</strong>  I have written an updated tutorial with code to allow you to have <a href="http://jamestombs.co.uk/2010-03-10/creating-a-grid-of-images-for-an-album-in-drupal-6-with-pagination/1106">pagination on your grid of images</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-album-in-drupal/1046/feed</wfw:commentRss>
		<slash:comments>75</slash:comments>
		</item>
		<item>
		<title>Create an album based image gallery in Drupal 6 using CCK and views</title>
		<link>http://jamestombs.co.uk/2009-05-12/create-an-album-based-image-gallery-in-drupal-6-using-cck-and-views/1045</link>
		<comments>http://jamestombs.co.uk/2009-05-12/create-an-album-based-image-gallery-in-drupal-6-using-cck-and-views/1045#comments</comments>
		<pubDate>Tue, 12 May 2009 21:32:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/2009-05-12/create-an-album-based-image-gallery-in-drupal-6-using-cck-and-views/1045</guid>
		<description><![CDATA[This tutorial is an addition to my previous tutorial on creating a simple gallery in Drupal 6 using CCK and views.&#160; This tutorial will enable users to create galleries containing multiple images per node with each album being listed within a view presented by one of the node’s images. This tutorial was written with the [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial is an addition to my previous tutorial on <a href="http://jamestombs.co.uk/2009-03-18/create-a-simple-image-gallery-in-drupal-6-using-cck-and-views/996">creating a simple gallery in Drupal 6 using CCK and views</a>.&#160; This tutorial will enable users to create galleries containing multiple images per node with each album being listed within a view presented by one of the node’s images.</p>
<p>This tutorial was written with the following versions of Drupal and module:</p>
<ul>
<li><a href="http://drupal.org/drupal-6.11">Drupal 6.11</a> </li>
<li><a href="http://drupal.org/project/cck">CCK (Content Construction Kit) 6.x-2.2</a> </li>
<li><a href="http://drupal.org/project/views">Views 6.x-2.5</a> </li>
<li><a href="http://drupal.org/project/filefield">Filefield 6.x-3.0</a> </li>
<li><a href="http://drupal.org/project/imagefield">Imagefield 6.x-3.0</a> </li>
<li><a href="http://drupal.org/project/imageapi">ImageAPI 6.x-1.6</a> </li>
<li><a href="http://drupal.org/project/imagecache">Imagecache 6.x-2.0-beta9</a> </li>
<li><a href="http://drupal.org/project/lightbox2">Lightbox2 6.x-1.9</a> </li>
</ul>
<p><strong>Note:</strong> These were the latest versions as of writing this tutorial.</p>
</p>
<p> <span id="more-1045"></span>
</p>
<h3>Installation</h3>
<p>Install Drupal as normal and extract each of the modules to /sites/all/modules directory.</p>
<p>Navigate to /admin/build/modules and enable the following modules:</p>
<ul>
<li>Content </li>
<li>Filefield </li>
<li>Imagefield </li>
<li>ImageAPI </li>
<li>ImageAPI GD2 (unless your server is configured for Imagemagick, then enable the ImageMagick module instead) </li>
<li>ImageCache </li>
<li>ImageCache UI </li>
<li>Lightbox2 </li>
<li>Views </li>
<li>Views UI </li>
</ul>
<p>Once you have ticked all the modules, press Save configuration.</p>
<h3>Imagecache</h3>
<p>You may wish to create more presets, but for this tutorial we will just create 2, a thumbnail for each image and a larger lightbox image.</p>
<p>Navigate to /admin/build/imagecache and click Add new preset.</p>
<p>Set the preset Namespace to thumbnail. Click Add Scale and Crop, set the width to 300 and the height to 200.</p>
<p>Then create a new imagecache preset with the name lightbox. This time select Add Scale and set the width to 800 and the height to 600.</p>
<h3>CCK Imagefield</h3>
<p>We will need to create a content type that we will use for our albums.&#160; To keep this simple, I am calling mine Album with the machine name album.</p>
<p>Navigate to /admin/content/types and click Add content type.</p>
<p>Under Submission form settings, set the Title field name to Album name and set the Body field label to description.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image.png" width="420" height="144" /></p>
<p>Save the content type.</p>
<p>Next to the Album content type click manage fields. In the Add New field area, set the label to Images and the field name to images (to make it field_images), for the Type of data to store, select File then for Form element select Image.&#160; Press Save.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
/* 336x280, created 3/31/10 */
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image1.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb.png" width="420" height="60" /></a></p>
<p>You may need to set the Permitted upload file extensions.&#160; By default mine was set to <em>txt</em>.&#160; Change this to <em>jpg gif jpeg png</em>.</p>
<p>Under Global settings, tick the Required box and set the Number of values to Unlimited.&#160; Leave the List field disabled and set the Description field to Enabled.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image2.png" width="420" height="295" /></p>
<p>Then press the Save field settings button.</p>
<p>Now click the Display fields tab at the top of the page.</p>
<p>Set the Label to Hidden and set both the Teaser and Full node to Lightbox2: thumbnail-&gt;lightbox.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image3.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb1.png" width="420" height="45" /></a></p>
<p>Now under /node/add/album we can add some images to go in to our album.</p>
<p>For now create 3 or 4 albums.</p>
<p>Under /admin/content/node you should now have some nodes.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image4.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb2.png" width="420" height="95" /></a></p>
<h3>Views</h3>
<p>Navigate to /admin/build/views and click the Add tab at the top of the page.&#160; Set the view name to something like albums, leave the View type set to node and click Next.</p>
<p>Set the title to Albums. For Style set to Grid then chose 3 columns and set Alignment to Horizontal.</p>
<p>For Use pager set to Full pager.&#160; Then for Items per page, set to a multiple of 3, I am going to use 9 to give us a 3×3 grid of images. If you wish, you can set Use AJAX to Yes to stop the whole page being loaded on the pager.</p>
<p>Add the following Filters:</p>
<ul>
<li>Node: Published = On </li>
<li>Node: Type = Album </li>
</ul>
<p>Under Fields select Content: Images (field_images), Node: Body and&#160; Node: Title.</p>
<p>Set Label to None and change Format to thumbnail image and set the Show value to 1 value. Tick the box that says Link this field to its node, this will allow the image to be clickable. Press Update.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image5.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb3.png" width="420" height="239" /></a></p>
<p>For node body, delete the text in the Label field and press Update.&#160; If you have used long descriptions for your albums, you may wish to use the Trim this field to maximum length to limit the length of the description.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image6.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb4.png" width="420" height="262" /></a></p>
<p>For title, delete the Label text and tick the box next to Link this field to its node, press Update.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image7.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb5.png" width="420" height="163" /></a></p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
/* 336x280, created 3/31/10 */
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></p>
<p>At the moment Drupal has these fields in the wrong order, so you will need to click the up and down arrow next to the + button on fields.</p>
<p>And reorder the fields in to the following order: Image –&gt; Title –&gt; Body or if you wish you can keep them how they are.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image8.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb6.png" width="420" height="90" /></a></p>
<p>Under Relationships, click the + button and select Content: Images (field_images) – fid.</p>
<p>Tick the box that says Require this relationship and set the Delta to 1.&#160; This will check to make sure that the album contains at least 1 image.&#160; Setting Delta to all will result in odd behaviour in the album due to duplicates.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image9.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb7.png" width="420" height="126" /></a></p>
<p>If you wish you can add some sort criteria so that the newest albums appear first etc.</p>
<p>On the left select Page from the drop down and click Add display.</p>
<p>Under Path set to albums.</p>
<p>Press Save.</p>
<p>Now if you navigate to /albums you can see your gallery in action.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/05/image10.png" rel="shadowbox[post-1045];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://jamestombs.co.uk/wp-content/uploads/2009/05/image-thumb8.png" width="420" height="253" /></a></p>
<p>For your album nodes, you can modify them however you want to get the display you are looking for, whether you use Panels or create a custom node-album.tpl.php is up to you.</p>
<p><strong>Update:</strong> I have now written a tutorial on <a href="http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-album-in-drupal/1046">creating a grid of images within an album using the node-album.tpl.php method</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-05-12/create-an-album-based-image-gallery-in-drupal-6-using-cck-and-views/1045/feed</wfw:commentRss>
		<slash:comments>143</slash:comments>
		</item>
		<item>
		<title>Fatal error: Unsupported operand types in email_registration.module on line 61</title>
		<link>http://jamestombs.co.uk/2009-04-22/fatal-error-unsupported-operand-types-in-cxampphtdocsdrupalsitesallmodulesemail_registrationemail_registrationmodule-on-line-61/1023</link>
		<comments>http://jamestombs.co.uk/2009-04-22/fatal-error-unsupported-operand-types-in-cxampphtdocsdrupalsitesallmodulesemail_registrationemail_registrationmodule-on-line-61/1023#comments</comments>
		<pubDate>Wed, 22 Apr 2009 21:01:38 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/2009-04-22/fatal-error-unsupported-operand-types-in-cxampphtdocsdrupalsitesallmodulesemail_registrationemail_registrationmodule-on-line-61/1023</guid>
		<description><![CDATA[You will get this error if you have logintoboggan and email_registration installed within Drupal 5 and visit the site as an anonymous user with the user login block enabled.&#160; This is caused by the modifications made to the user login block by the logintoboggan module. You can fix this without hacking the email_registration.module file. Fix [...]]]></description>
			<content:encoded><![CDATA[<p>You will get this error if you have <a href="http://drupal.org/project/logintoboggan">logintoboggan</a> and <a href="http://drupal.org/project/email_registration">email_registration</a> installed within Drupal 5 and visit the site as an anonymous user with the user login block enabled.&#160; This is caused by the modifications made to the user login block by the <a href="http://drupal.org/project/logintoboggan">logintoboggan</a> module.</p>
<p>You can fix this without hacking the email_registration.module file.</p>
<p> <span id="more-1023"></span><br />
<h3>Fix</h3>
<p>While logged in as an admin (if you can’t get in to the site to login, go to <a href="http://www.domain.com/user">http://www.domain.com/user</a>, as this will only load up the main user login form and not the block), go to Admin –&gt; Site Building –&gt; Blocks.&#160; Click Configure next to User login.&#160; Under Block type, select the radio button that says Standard. Then save the block.&#160; Now try to visit the site as an anonymous user and it should be working.</p>
<h3>Hack fix</h3>
<p>Within the email_registration.module file, you will need to add some code to the module.</p>
<p>On lines 59-62, you will find the following:</p>
<p><code>case 'user_login_block':     <br />&#160; $form['name']['#title'] = t('E-mail');       <br />&#160; </code><code>$form['#validate'] = array('email_registration_user_login_validate' =&gt; array()) + $form['#validate'];      <br />&#160; </code><code>break;</code></p>
<p>You need to change it to this:</p>
<p><code>case 'user_login_block':     <br />&#160; if (!empty($form[‘#validate’)) {</code><code>     <br />&#160;&#160;&#160; $form['name']['#title'] = t('E-mail');       <br />&#160;&#160;&#160; </code><code>$form['#validate'] = array('email_registration_user_login_validate' =&gt; array()) + $form['#validate'];     <br />&#160; }      <br />&#160; </code><code>break;</code></p>
<p>Save the module and it should work as expected.</p>
<h3>The problem</h3>
<p>Logintoboggan adds the ability to change the appearance of the user login block to show just a link rather than the form that Drupal usually ships with, this in turn means that there are no $form array elements for hook_form_alter to use.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-04-22/fatal-error-unsupported-operand-types-in-cxampphtdocsdrupalsitesallmodulesemail_registrationemail_registrationmodule-on-line-61/1023/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;HTTP request status&#8221; in Drupal 6.x on localhost</title>
		<link>http://jamestombs.co.uk/2009-04-20/http-request-status-in-drupal-6x-on-localhost/1021</link>
		<comments>http://jamestombs.co.uk/2009-04-20/http-request-status-in-drupal-6x-on-localhost/1021#comments</comments>
		<pubDate>Mon, 20 Apr 2009 18:30:11 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PCs]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/2009-04-20/http-request-status-in-drupal-6x-on-localhost/1021</guid>
		<description><![CDATA[I just set up XAMPP on my Vista x64 PC and found that after installing Drupal 6 that the status report was throwing up an error. HTTP request status Your system or network configuration does not allow Drupal to access web pages, resulting in reduced functionality. This could be due to your webserver configuration or [...]]]></description>
			<content:encoded><![CDATA[<p>I just set up XAMPP on my Vista x64 PC and found that after installing Drupal 6 that the status report was throwing up an error.</p>
<blockquote><p><code>HTTP request status</code></p>
<p><code>Your system or network configuration does not allow Drupal to access web pages, resulting in reduced functionality. This could be due to your webserver configuration or PHP settings, and should be resolved in order to download information about available updates, fetch aggregator feeds, sign in via OpenID, or use other network-dependent services.</code></p>
</blockquote>
<p>It took a while to find the solution, but I eventually found it on <a href="http://drupal.org/node/222454#comment-1233805">drupal.org</a>. The solution was posted by <a href="http://drupal.org/user/425613">mrSjoerd</a>.</p>
<ol>
<li>Open up the hosts file which is located at C:\Windows\System32\drivers\etc in notepad</li>
<li>You should find a line like the following at the bottom:     <br /><em>::1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; localhost</em></li>
<li>Add a <strong>#</strong> in front of it to make it look like this:      <br /><em>#::1&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; localhost</em></li>
<li>Save the file and close notepad.</li>
<li>Refresh the status page in Drupal and the error should be gone.&#160; This should work without a restart, but if it doesn’t work without a restart it is worth a try.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-04-20/http-request-status-in-drupal-6x-on-localhost/1021/feed</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Create a simple image gallery in Drupal 6 using CCK and Views</title>
		<link>http://jamestombs.co.uk/2009-03-18/create-a-simple-image-gallery-in-drupal-6-using-cck-and-views/996</link>
		<comments>http://jamestombs.co.uk/2009-03-18/create-a-simple-image-gallery-in-drupal-6-using-cck-and-views/996#comments</comments>
		<pubDate>Wed, 18 Mar 2009 21:29:31 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/2009-03-18/create-a-simple-image-gallery-in-drupal-6-using-cck-and-views/996</guid>
		<description><![CDATA[This tutorial will guide you through how to create a simple gallery within Drupal 6 using CCK, Views and a few more custom modules. You can see an example of what the tutorial will create by visiting http://gallery.jamestombs.co.uk/ This tutorial was written with the following versions of Drupal and modules: Drupal 6.10 CCK (Content Construction [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will guide you through how to create a simple gallery within Drupal 6 using CCK, Views and a few more custom modules. You can see an example of what the tutorial will create by visiting <a href="http://gallery.jamestombs.co.uk/">http://gallery.jamestombs.co.uk/</a></p>
<p>This tutorial was written with the following versions of Drupal and modules:</p>
<ul>
<li><a href="http://drupal.org/drupal-6.10">Drupal 6.10</a> </li>
<li><a href="http://drupal.org/project/cck">CCK (Content Construction Kit) 6.x-2.1</a> (6.x-2.2) </li>
<li><a href="http://drupal.org/project/views">Views 6.x-2.3</a> (6.x-2.5) </li>
<li><a href="http://drupal.org/project/filefield">Filefield 6.x-3.0-beta1</a> (6.x-3.0-rc1) </li>
<li><a href="http://drupal.org/project/imagefield">Imagefield 6.x-3.0-beta1</a> (6.x-3.0-rc1) </li>
<li><a href="http://drupal.org/project/imageapi">ImageAPI 6.x-1.5</a> (6.x-1.6) </li>
<li><a href="http://drupal.org/project/imagecache">Imagecache 6.x-2.0-beta8</a> (6.x-2.0-beta9) </li>
<li><a href="http://drupal.org/project/lightbox2">Lightbox2 6.x-1.9</a> </li>
</ul>
<p><strong>Update:</strong> Modules have been updated to the latest versions as of 20 April 2009, version numbers are in brackets after the links above.</p>
</p>
<p> <span id="more-996"></span>
</p>
<h3>Installation</h3>
<p>Install Drupal as you normally would and extract each of the modules to the /sites/all/modules directory. You should have a directory structure like the following:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="directory_structure" border="0" alt="directory_structure" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/directory-structure.jpg" width="251" height="361" /></p>
<p>When logged in go to /admin/build/modules and enable the following modules:</p>
<ul>
<li>Content </li>
<li>Filefield </li>
<li>Imagefield </li>
<li>ImageAPI </li>
<li>ImageAPI GD2 (unless your server is configured for Imagemagick, then enable the ImageMagick module instead) </li>
<li>ImageCache </li>
<li>ImageCache UI </li>
<li>Lightbox </li>
<li>Views </li>
<li>Views UI </li>
</ul>
<p>Once you have ticked the modules, press Save configuration.</p>
<h3>Imagecache</h3>
<p>We need to create 2 presets for our images, one will be a thumbnail to show in the gallery and a second to show within the lightbox.</p>
<p>Navigate to /admin/build/imagecache and click Add new preset.</p>
<p>Set the preset Namespace to thumbnail. Click Add Scale and Crop, set the width to 180 and the height to 120.</p>
<p>Then create a new imagecache preset with the name lightbox. This time select Add Scale and set the width to 800 and the height to 600.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
/* 336x280, created 3/31/10 */
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />
<h3>CCK Imagefield</h3>
<p>First we will set up a new content type for our images which we will call Image. Navigate to /admin/content/types and click Add content type.</p>
<p>Set the name to Image and the type to image.&#160; You may enter a description if you wish.</p>
<p>Under Submission form settings, delete the text from the Body field.</p>
<p>Depending on how you want to set up the gallery, you can change the Workflow settings so that images aren’t automatically added but are added to an approval list, for this tutorial we will make all images published, so untick Promoted to frontpage and leave Published ticked.</p>
<p>Under Comment settings, set comments to disabled.</p>
<p>Save the content type.</p>
<p>Next to the Image content type click manage fields. In the Add New field area, set the label to Image and the field name to image (to make it field_image), for the Type of data to store, select File then for Form element select Image.&#160; Press Save.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/content-type.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="content_type" border="0" alt="content_type" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/content-type-thumb.jpg" width="420" height="122" /></a></p>
<p>Under Global settings, tick the Required box and set the Number of values to 1.&#160; Leave the List field and Description field to Disabled.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/imagefield.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="imagefield" border="0" alt="imagefield" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/imagefield-thumb.jpg" width="420" height="180" /></a></p>
<p>Then press the Save field settings button.</p>
<p>Now click the Display fields tab at the top of the page.</p>
<p>Set the Label to Hidden and set both the Teaser and Full node to Lightbox2: thumbnail-&gt;lightbox.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/imagedisplay.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="imagedisplay" border="0" alt="imagedisplay" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/imagedisplay-thumb.jpg" width="420" height="39" /></a></p>
<p>Now under /node/add/image we can add an image to go in to our gallery.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/newimage.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="newimage" border="0" alt="newimage" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/newimage-thumb.jpg" width="420" height="192" /></a></p>
<p>For now create 3 or 4 images.</p>
<p>Under /admin/content/node you should now have some nodes.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/nodes.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="nodes" border="0" alt="nodes" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/nodes-thumb.jpg" width="420" height="88" /></a></p>
<p>Now we will set up a view to display these nodes in a gallery.</p>
<h3>Views</h3>
<p>Navigate to /admin/build/views and click the Add tab at the top of the page. Set the view name to something like gallery. Leave View type set to Node.</p>
<p>Set the title to Gallery. For Style set to Grid then chose 4 columns and set Alignment to Horizontal.</p>
<p>For Use pager set to Full pager.&#160; Then for Items per page, set to a multiple of 4, I am going to use 16 to give us a 4&#215;4 grid of images. If you wish, you can set Use AJAX to Yes to stop the whole page being loaded on the pager.</p>
<p>Add the following Filters:</p>
<ul>
<li>Node: Published = On </li>
<li>Node: Type = Image </li>
</ul>
<p>Under Fields select Content: Image (field_image). Set Label to None and change Format to Lightbox2: thumbnail-&gt;lightbox.</p>
<p><script type="text/javascript"><!--
google_ad_client = "pub-8190774722923642";
/* 336x280, created 3/31/10 */
google_ad_slot = "1689935941";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script><br />
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<p>Under Sort criteria you can set this to what you want.&#160; I am going to set them to newest first. Select Node: Post date and set to Descending.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/galleryunsaved.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="galleryunsaved" border="0" alt="galleryunsaved" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/galleryunsaved-thumb.jpg" width="420" height="186" /></a></p>
<p>On the left select Page from the drop down and click Add display.</p>
<p>Under Path set to gallery.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/viewpage.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="viewpage" border="0" alt="viewpage" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/viewpage-thumb.jpg" width="420" height="186" /></a></p>
<p>Press Save.</p>
<p>Now if you navigate to /gallery you can see your gallery in action.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/gallery.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="gallery" border="0" alt="gallery" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/gallery-thumb.jpg" width="420" height="141" /></a></p>
<p>Once you upload more than 16 images which we set our Items per page to, a pager will appear.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/03/full-gallery.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="full_gallery" border="0" alt="full_gallery" src="http://jamestombs.co.uk/wp-content/uploads/2009/03/full-gallery-thumb.jpg" width="420" height="266" /></a></p>
<p>You can see a working example of the gallery in action at <a href="http://gallery.jamestombs.co.uk/gallery">http://gallery.jamestombs.co.uk/gallery</a></p>
<p><strong>Update:</strong> There may be cases where the image isn&#8217;t uploaded to the image type when a user submits the node add form without uploading the image. This will show up as an empty section within the gallery and the node will be submitted with no image, but Imagefield will not tell the user that this is a problem even if it is a required field.</p>
<p>To stop these empty image types showing in the gallery, you will need to add a relationship for the image and set it to a required relationship. This way the image node will not appear in the gallery unless there is an image attached. You could then set up an additional view to find out which image nodes don&#8217;t have an image attached.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2009/04/relationship.jpg" rel="shadowbox[post-996];player=img;"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="relationship" border="0" alt="relationship" src="http://jamestombs.co.uk/wp-content/uploads/2009/04/relationship-thumb.jpg" width="420" height="313" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-03-18/create-a-simple-image-gallery-in-drupal-6-using-cck-and-views/996/feed</wfw:commentRss>
		<slash:comments>222</slash:comments>
		</item>
		<item>
		<title>www.i-wax.co.uk &#8211; Home of valeting and detailing good offers</title>
		<link>http://jamestombs.co.uk/2009-02-09/wwwi-waxcouk-home-of-valeting-and-detailing-good-offers/967</link>
		<comments>http://jamestombs.co.uk/2009-02-09/wwwi-waxcouk-home-of-valeting-and-detailing-good-offers/967#comments</comments>
		<pubDate>Mon, 09 Feb 2009 19:38:52 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/2009-02-09/wwwi-waxcouk-home-of-valeting-and-detailing-good-offers/967</guid>
		<description><![CDATA[About www.i-wax.co.uk www.i-wax.co.uk was founded in January 2009 as a place for consumers to freely share deals for valeting and detailing products while saving you and others money. The purpose of the site is to escape from the marketing messages and ads and collate all the best that the web has to offer and get [...]]]></description>
			<content:encoded><![CDATA[<h3>About www.i-wax.co.uk</h3>
<p><a href="http://www.i-wax.co.uk">www.i-wax.co.uk</a> was founded in January 2009 as a place for consumers to freely share deals for valeting and detailing products while saving you and others money. The purpose of the site is to escape from the marketing messages and ads and collate all the best that the web has to offer and get us genuine deals.</p>
<h3>Self-promotion</h3>
<p>The basis of the site is that it is for best deals from other people who don&#8217;t stand to gain. But merchants who are self-promoting are also welcome as long as it’s a genuine deal where the consumers will save £££’s.(items may be removed without notice)</p>
<h3>Anyone can share, public or trade</h3>
<p><a href="http://www.i-wax.co.uk">www.i-wax.co.uk</a> has no-registration and open to everyone. The more users we have sharing and contributing their savings on detailing and valeting equipment, the more everyone gains! You can help build this community by sharing deals you&#8217;ve found.</p>
<p>The site is displaying offers on:</p>
<p>Meguiars, Pinnacle, polish, glaze, wax, Poorboys, Menzerna, Sonus, Swissol, Swizol, Zymol, pakshak, Chemical Guys, Collinite, Einszett, Gliptone, P21s, Sonus, Clearkote, Harley wax, Klasse, Mothers, Autoglym, Belgom, Wheelwax, Renovo, Eurow, Muc off, 3m, Bilt Hamber, Smartwax, Wolfgang, Four star, Optimum, Dp, 303, Lexol, Corbra, Oxo, Blackfire, Lake Country, Jeffs Werkstatt, Zaino, Concept chemicals, Dominique France Concours, Visomax, Duragloss, Prima, Hosecoil, Car cleaning, Carwash, Shampoo, Victoria wax and many more.</p>
<p>All can be seen at <a href="http://www.i-wax.co.uk">www.i-wax.co.uk</a>.</p>
<p><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="wwwiwaxcoukfe9" border="0" alt="wwwiwaxcoukfe9" src="http://jamestombs.co.uk/wp-content/uploads/2009/02/wwwiwaxcoukfe9.png" width="420" height="149" /></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2009-02-09/wwwi-waxcouk-home-of-valeting-and-detailing-good-offers/967/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Drupal] Deleting node content of a certain type in bulk</title>
		<link>http://jamestombs.co.uk/2008-10-27/drupal-deleting-node-content-of-a-certain-type-in-bulk/944</link>
		<comments>http://jamestombs.co.uk/2008-10-27/drupal-deleting-node-content-of-a-certain-type-in-bulk/944#comments</comments>
		<pubDate>Mon, 27 Oct 2008 10:48:39 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=944</guid>
		<description><![CDATA[On occasions you may need to bulk delete all nodes of a certain type. The following code requires 2 variables, the amount of rows to delete each time and the content type. $amount = 100; $type = &#039;node_type&#039;; $result = db_query(&#34;SELECT nid FROM {node} WHERE type = &#039;%s&#039; LIMIT %d&#34;, $type, $amount); if (db_num_rows($result) &#38;&#38; [...]]]></description>
			<content:encoded><![CDATA[<p>On occasions you may need to bulk delete all nodes of a certain type.</p>
<p>The following code requires 2 variables, the amount of rows to delete each time and the content type.</p>
<pre class="brush: php">$amount = 100;
$type = &#039;node_type&#039;;
$result = db_query(&quot;SELECT nid FROM {node} WHERE type = &#039;%s&#039; LIMIT %d&quot;, $type, $amount);
if (db_num_rows($result) &amp;&amp; user_access(&#039;administer nodes&#039;)) {
  $n = 0;
  while ($data = db_fetch_object($result)) {
    set_time_limit(5);
    node_delete($data-&gt;nid);
    $n++;
  }
  if ($n == $amount) {
    drupal_goto($_GET[&#039;q&#039;]);
  }
}else {
  drupal_set_message(t(&#039;No entries found for node type @type, or you do not have permission to modify nodes.&#039;, array(&#039;@type&#039; =&gt; $type)));
}</pre>
<p>This will go through all the nodes of the type you define and delete the node.  Once finished doing the batch, the page is then redirected back to the same page to delete another batch.</p>
<p>This can be placed in a node with an Input format of PHP code or through a module.</p>
<pre class="brush: php">function modulename_menu($may_cache) {
  $items = array();
  if (!$may_cache) {
    $items[] = array(
      &#039;path&#039; =&gt; &#039;this/is/the/path&#039;,
      &#039;callback&#039; =&gt; &#039;modulename_delete&#039;,
      &#039;access&#039; =&gt; user_access(&#039;administer nodes&#039;),
      &#039;title&#039; =&gt; t(&#039;Delete Nodes&#039;),
    );
  }
  return $items;
}</pre>
<p>Then wrap the above deletion code into a function such as:</p>
<pre class="brush: php">function modulename_delete($type = &#039;node_type&#039;, $limit = 100) { }</pre>
<p>Then you can navigate to the path in the hook_menu function and start the batch deletion.  To delete other types of nodes, add the content type to the end of the url. For events it would be:</p>
<p>http://www.domain.com/<strong>this/is/the/path/event</strong></p>
<p>Depending on what modules you have enabled, this can take a long time as the node_delete function calls a module_invoke function for any module to interact with it.  If you have a lot of modules this will take a long time.</p>
<p>Alternatively you can download and install the <a href="http://drupal.org/project/delete_all">Delete all module</a> which serves the same function.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2008-10-27/drupal-deleting-node-content-of-a-certain-type-in-bulk/944/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>[FPSS] Front Page Slideshow for Drupal Update</title>
		<link>http://jamestombs.co.uk/2008-10-24/fpss-front-page-slideshow-for-drupal-update/927</link>
		<comments>http://jamestombs.co.uk/2008-10-24/fpss-front-page-slideshow-for-drupal-update/927#comments</comments>
		<pubDate>Fri, 24 Oct 2008 17:31:59 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[demo]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=927</guid>
		<description><![CDATA[I have updated my Front Page Slideshow for Drupal module with some new features and some fixes. New Features: Change language text within DrupalWithin the admin screen of FPSS you can now add the language text for the slideshow within Drupal which is stored in variables. By default the module has the English text in. [...]]]></description>
			<content:encoded><![CDATA[<p>I have updated my Front Page Slideshow for Drupal module with some new features and some fixes.</p>
<p><strong>New Features:</strong></p>
<ul>
<li>Change language text within Drupal<br />Within the admin screen of FPSS you can now add the language text for the slideshow within Drupal which is stored in variables.  By default the module has the English text in.  If you want the French text, then you will have to open up the french.php file and copy paste each item in to the form and save it.</li>
<li>Change javascript location<br />Within the admin screen as well as being able to turn off the javascript library and optimize the javascript you can now selected if you want the javascript to be inserted in to the footer of the page rather than the header.  This is tested and works on a default Drupal installation of 5.12.</li>
</ul>
<p><strong>Fixes</strong></p>
<ul>
<li>Optimize JS and Disable JS both work as expected now and any configuration of the 2 settings should work, although some javascript packages may conflict causing problems.</li>
<li>Fixed the admin settings access, missing array item in hook_perm.</li>
</ul>
<p>You can download the <a href="http://code.google.com/p/fpss-drupal/">fpss for drupal module</a> at the <a href="http://code.google.com/p/fpss-drupal/">Google Code</a> site and you can view the demo of the <a href="http://drupal.jamestombs.co.uk">Front Page Slideshow for Drupal demo</a> at <a href="http://drupal.jamestombs.co.uk">http://drupal.jamestombs.co.uk</a>.</p>
<p>If you have any problems or find any bugs please submit them on the <a href="http://code.google.com/p/fpss-drupal/issues/list">FPSS for Drupal Issue Queue</a> on the Google Code site. Alternatively leave a comment to this post or email at jtombs1987@gmail.com.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2008-10-24/fpss-front-page-slideshow-for-drupal-update/927/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Frontpage Slideshow for Drupal</title>
		<link>http://jamestombs.co.uk/2008-10-16/frontpage-slideshow-for-drupal/913</link>
		<comments>http://jamestombs.co.uk/2008-10-16/frontpage-slideshow-for-drupal/913#comments</comments>
		<pubDate>Thu, 16 Oct 2008 15:33:29 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Other]]></category>
		<category><![CDATA[drupal]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=913</guid>
		<description><![CDATA[I have begun coding a module to allow the Frontpage Slideshow to be displayed within a block or a panel. Frontpage slideshow is a script by Joomlaworks. The module requires that the script is purchased from Joomlaworks as it contains important files for it to work. The module which is currently in development can be [...]]]></description>
			<content:encoded><![CDATA[<p>I have begun coding a module to allow the Frontpage Slideshow to be displayed within a block or a panel.</p>
<p>Frontpage slideshow is a script by Joomlaworks.</p>
<p>The module requires that the script is purchased from Joomlaworks as it contains important files for it to work.</p>
<p>The module which is currently in development can be found at <a href="http://code.google.com/p/fpss-drupal/">http://code.google.com/p/fpss-drupal/</a>.</p>
<p>The code is still in an early stage but is working and usable, but I would recommend not using it on a production site.</p>
<p>There are a few issues with the module at the moment.</p>
<ul>
<li>Module depends on jquery_update</li>
<li>Module uses the upload module to upload the image for the slide, but this allows any file to be uploaded, so requires some further work.</li>
</ul>
<h2>How does it work</h2>
<p>The module adds in 2 new node types (slide, slideshow).  Each slideshow node creates a new block which can be used anywhere in your site.</p>
<p>Slides are then assigned to a slideshow.  The slideshow node contains most of the important settings such as dimensions and timings but as well as this there is an admin settings page which controls the default settings across the whole site such as the language of the text and the javascript engine.</p>
<p>I have developed the module purely with jQuery in mind.  Mootools may work, but is likely to be unstable and buggy.</p>
<h2>Where can I download this module?</h2>
<p>Go to <a href="http://code.google.com/p/fpss-drupal/">http://code.google.com/p/fpss-drupal/</a> and download it from the right hand side.  If you find any issues with the module please do so by leaving an issue on the Google Code site.</p>
<div class="amazon"><a href="http://www.amazon.co.uk/Pro-Drupal-Development-2nd/dp/1430209895%3FSubscriptionId%3D02E5W5871AJF7PMMMS82%26tag%3Djamestombs-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1430209895"><img src="http://ecx.images-amazon.com/images/I/51ygqAHbDkL._SL75_.jpg" /></a></div>
<h3>Useful Drupal Module Development Book</h3>
<p>Pro Drupal Development is a very good book published by Apress.  The new second edition covers Drupal 6.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2008-10-16/frontpage-slideshow-for-drupal/913/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Drupal] Get a list of other nodes that are related by taxonomy terms</title>
		<link>http://jamestombs.co.uk/2008-09-24/drupal-get-a-list-of-other-nodes-that-are-related-by-taxonomy-terms/659</link>
		<comments>http://jamestombs.co.uk/2008-09-24/drupal-get-a-list-of-other-nodes-that-are-related-by-taxonomy-terms/659#comments</comments>
		<pubDate>Wed, 24 Sep 2008 11:07:29 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=659</guid>
		<description><![CDATA[Building on this snippet from Drupal to get related node items sharing the same taxonomy terms for 4.7, I have made it work for multiple terms.  This snippet is for Drupal 5 and has been tested to work on 5.10. The code will return a list view of 5 (changeable with $num_nodes) in an unordered [...]]]></description>
			<content:encoded><![CDATA[<p>Building on this <a href="http://drupal.org/node/76923">snippet</a> from Drupal to get related node items sharing the same taxonomy terms for 4.7, I have made it work for multiple terms.  This snippet is for Drupal 5 and has been tested to work on 5.10.</p>
<p>The code will return a list view of 5 (changeable with $num_nodes) in an unordered list in a random format.</p>
<p>If you want to order the items you can edit the code to order the data in the SQL statement and take out lines 18 and 19.</p>
<pre class="brush: php">$num_nodes = 5;
$nid = arg(1);
$terms = taxonomy_node_get_terms($nid);
$items = array();
foreach($terms as $term) {
  $sql = &quot;SELECT DISTINCT n.title, n.nid
    FROM {node} n
    INNER JOIN {term_node} tn ON n.nid = tn.nid
    WHERE n.status =1
    AND tn.tid =&quot;.$term-&amp;gt;tid.&quot;
    AND n.nid !=&quot;.$nid.&quot;
    LIMIT $num_nodes&quot;;
  $result = db_query(db_rewrite_sql($sql));
  while ($node = db_fetch_object($result)) {
    $items[$node-&amp;gt;nid] = l($node-&amp;gt;title, &#039;node/&#039;. $node-&amp;gt;nid);
  }
}
srand((float)microtime() * 1000000);
shuffle($items);
return theme(&#039;node_list&#039;, $items);</pre>
<p>For Drupal 6, although I haven&#8217;t tried this code, it should be the same except for line 3 which should be like this:</p>
<pre class="brush: php">$terms = taxonomy_node_get_terms(node_load($nid));</pre>
<p>In Drupal 6, taxonomy_node_get_terms requires the whole node object rather than just the node ID (nid).</p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2008-09-24/drupal-get-a-list-of-other-nodes-that-are-related-by-taxonomy-terms/659/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Drupal] Installation</title>
		<link>http://jamestombs.co.uk/2008-09-22/drupal-installation/630</link>
		<comments>http://jamestombs.co.uk/2008-09-22/drupal-installation/630#comments</comments>
		<pubDate>Mon, 22 Sep 2008 20:00:45 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[drupal planet]]></category>

		<guid isPermaLink="false">http://jamestombs.co.uk/?p=630</guid>
		<description><![CDATA[You will need to have set up an IIS or Apache webserver with PHP 5.2 or greater and a Mysql/PostgreSQL database before you can work on Drupal. For more requirements see [Drupal] Overview. If you do not have a webserver yet but wish to set up your personal computer as a testing environment, please read [...]]]></description>
			<content:encoded><![CDATA[<p>You will need to have set up an IIS or Apache webserver with PHP 5.2 or greater and a Mysql/PostgreSQL database before you can work on Drupal. For more requirements see <a href="http://jamestombs.co.uk/2008-09-22/drupal-overview/628">[Drupal] Overview</a>.</p>
<p>If you do not have a webserver yet but wish to set up your personal computer as a testing environment, please read through and complete the following guide on <a href="http://jamestombs.co.uk/2008-09-22/set-up-your-pc-as-a-test-environment-using-apache-php-and-mysql/634">Setting up your PC as a test environment using Apache, PHP and MySQL</a>.</p>
<h2>Download Drupal</h2>
<p>For this tutorial we will be using Drupal 6.  You will be able to follow through a fair amount using Drupal 5 but some features may be new.</p>
<p>Go to the <a href="http://drupal.org/">Drupal website</a> and click the link on the right hand side to download <a href="http://drupal.org/drupal-6.4">Drupal 6</a>.  As of writing the latest version is <a href="http://ftp.drupal.org/files/projects/drupal-6.4.tar.gz">Drupal 6.4</a>.</p>
<p>Once downloaded, right click the file and extract.  This should produce a folder called <strong>drupal-6.4</strong>.  Rename this folder to <strong>drupal</strong>. Move this folder to the public web folder of your web server set up (<em>public_html</em>, <em>www</em>, <em>htdocs</em>, <em>httpdocs</em>).</p>
<h2>Setup MySQL server</h2>
<p>Depending on the setup that you are using, you will have to create a database using whatever tools are available to you.</p>
<p><strong>PHPMyAdmin</strong></p>
<p>The most common bit of software is PHPMyAdmin which is generally accessible through <em>http://www.domain.com/phpmyadmin/</em>.</p>
<p>On the homepage, type the name of the new database in the box and press <strong>Create</strong>. I will call my database <strong>drupal</strong>, although on a public website it is best to give the database an obscure name.</p>
<p><strong>Command Line</strong></p>
<p>Open up a command prompt, change directory to the <strong>mysql/bin</strong> folder. Type the following to login to the MySQL server:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;">mysql <span style="color: #CC0099;">-</span>h localhost <span style="color: #CC0099;">-</span>u root <span style="color: #CC0099;">-</span>p</pre></div></div>

<p>Then type your password in.</p>
<p>Then type the following:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">create</span> <span style="color: #990099; font-weight: bold;">database</span> drupal<span style="color: #000033;">;</span></pre></div></div>

<p><img class="alignnone size-full wp-image-645" title="command-line" src="http://jamestombs.co.uk/wp-content/uploads/2008/09/command-line.gif" alt="" width="500" height="247" /></p>
<p>The database is now set up.</p>
<h2>Drupal Installation</h2>
<p>In your browser navigate to <em>http://localhost/drupal/</em>. This should present you with the Choose language screen of the Drupal installer.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install.jpg" rel="shadowbox[post-630];player=img;"><img class="alignnone size-full wp-image-646" title="drupal_install" src="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install.jpg" alt="" width="500" height="387" /></a></p>
<p>Click <strong>Install Drupal in English</strong>.</p>
<p>If you get an error like the following:</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install1.jpg" rel="shadowbox[post-630];player=img;"><img class="alignnone size-full wp-image-647" title="drupal_install1" src="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install1.jpg" alt="" width="500" height="387" /></a></p>
<p>Then you need to navigate to the <strong>drupal/sites/default</strong> folder. Copy the file <strong>default.settings.php</strong> and paste it, rename it to <strong>settings.php</strong>. Then click <strong>try again</strong>.</p>
<p>Now the installer will ask you for your database settings.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install2.jpg" rel="shadowbox[post-630];player=img;"><img class="alignnone size-full wp-image-648" title="drupal_install2" src="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install2.jpg" alt="" width="500" height="387" /></a></p>
<p>Fill these in and press <strong>Save and continue</strong>.</p>
<p>On the next page fill in all of the required information and press <strong>Save and continue</strong>.</p>
<p>If you are on a local test environment you may get a message about being unable to send an email, ignore this message, it will be OK once put on a proper server.  Just remember that no emails will be sent from the server from this point unless you fix it.</p>
<p>Then click the link to view the site. You will then see the frontpage to your new website.</p>
<p><a href="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install3.jpg" rel="shadowbox[post-630];player=img;"><img class="alignnone size-full wp-image-649" title="drupal_install3" src="http://jamestombs.co.uk/wp-content/uploads/2008/09/drupal_install3.jpg" alt="" width="500" height="387" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://jamestombs.co.uk/2008-09-22/drupal-installation/630/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
