<?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>bjorsq</title>
	<atom:link href="http://bjorsq.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://bjorsq.net</link>
	<description></description>
	<lastBuildDate>Fri, 11 May 2012 13:17:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Chocolate cake</title>
		<link>http://bjorsq.net/blog/2010/09/23/chocolate-cake/</link>
		<comments>http://bjorsq.net/blog/2010/09/23/chocolate-cake/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 22:04:37 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[cakes]]></category>
		<category><![CDATA[recipes]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=1128</guid>
		<description><![CDATA[This makes a rich fudgey chocolate cake which is made mainly from sugar and butter, and keeps gooey for a week or so (if it lasts that long). I couldn't believe how little flour was in the recipe!]]></description>
			<content:encoded><![CDATA[<p><strong>Ingredients</strong></p>
<ul>
<li> 200g good quality dark chocolate , about 60% cocoa solids</li>
<li> 200g butter , cut in pieces</li>
<li> 1 tbsp instant coffee granules</li>
<li> 85g self-raising flour</li>
<li> 85g plain flour</li>
<li> 1â„4 tsp bicarbonate of soda</li>
<li> 200g light muscovado sugar</li>
<li> 200g golden caster sugar</li>
<li> 25g cocoa powder</li>
<li>3 eggs</li>
<li> 75ml milk</li>
<li> grated chocolate or curls, to decorate</li>
</ul>
<p><strong>Ganache</strong></p>
<ul>
<li>200g good-quality dark chocolate , as above</li>
<li>284ml carton double cream (pouring type)</li>
<li>2 tbsp golden caster sugar</li>
</ul>
<p><strong>Method</strong></p>
<ol>
<li>Butter a 20cm round cake tin (7.5cm deep) and line the base.</li>
<li>Preheat the oven to fan 140C/conventional 160C/ gas 3.</li>
<li>Break the chocolate in pieces into a medium, heavy-based pan. Tip in the butter, then mix the coffee granules into 125ml/4fl oz cold water and pour into the pan. Warm through over a low heat just until everything is melted &#8211; don&#8217;t overheat.</li>
<li> While the chocolate is melting, mix the two flours, bicarbonate of soda, sugars and cocoa in a big bowl, mixing with your hands to get rid of any lumps. Beat the eggs in a bowl and stir in the milk.</li>
<li> Now pour the melted chocolate mixture and the egg mixture into the flour mixture, stirring just until everything is well blended and you have a smooth, quite runny consistency. Pour this into the tin and bake for 1 hour 30 minutes &#8211; if you push a skewer in the centre it should come out clean and the top should feel firm (don&#8217;t worry if it cracks a bit).</li>
<li>Leave to cool in the tin (don&#8217;t worry if it dips slightly), then turn out onto a wire rack to cool completely.</li>
<li> When the cake is cold, cut it horizontally into three.</li>
<li>Make the ganache: chop the chocolate into small pieces and tip into a bowl. Pour the cream into a pan, add the sugar, and heat until it is about to boil. Take off the heat and pour it over the chocolate. Stir until the chocolate has melted and the mixture is smooth.</li>
<li> Sandwich the layers together with just a little of the ganache. Pour the rest over the cake letting it fall down the sides and smoothing to cover with a palette knife. Decorate with grated chocolate or a pile of  chocolate curls.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/09/23/chocolate-cake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Embedding a Twitter feed using jQuery</title>
		<link>http://bjorsq.net/blog/2010/09/03/embedding-a-twitter-feed-using-jquery/</link>
		<comments>http://bjorsq.net/blog/2010/09/03/embedding-a-twitter-feed-using-jquery/#comments</comments>
		<pubDate>Fri, 03 Sep 2010 13:54:35 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=1122</guid>
		<description><![CDATA[This is based on some code at: http://www.myphpetc.com/2009/11/jquery-twitter-streaming-widget-in-30.html but has been modified to enable embedding twitter feeds in multiple locations (using different search terms) on the same page. First, include jquery in the &#60;head&#62; of your page &#8211; here I&#8217;m using the google hosted version: &#60;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&#62;&#60;/script&#62; The following script will scan the page [...]]]></description>
			<content:encoded><![CDATA[<p>This is based on some code at:</p>
<p><a href="http://www.myphpetc.com/2009/11/jquery-twitter-streaming-widget-in-30.html">http://www.myphpetc.com/2009/11/jquery-twitter-streaming-widget-in-30.html</a></p>
<p>but has been modified to enable embedding twitter feeds in multiple locations (using different search terms) on the same page.</p>
<p>First, include jquery in the <code>&lt;head&gt;</code> of your page &#8211; here I&#8217;m using the google hosted version:</p>
<pre class="brush:js">
&lt;script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
</pre>
<p>The following script will scan the page for <code>&lt;div&gt;</code> tags with the class <code>twitter_feed</code>, extract the search term from the <code>title</code> attribute, and query the twitter API using JSON for tweets matching the query. It will then add the first 5 tweets to the <code>&lt;div&gt;</code> and query twitter at 10 second intervals for updates, showing 20 tweets at a time.</p>
<pre class="brush:js">
&lt;script type="text/javascript"&gt;
jQuery(function($){
    /* twitter feed loader */
    function load_tweets()
    {
        if (jQuery(".twitter_feed").length) {
            jQuery(".twitter_feed").each(function(){
                /* extract the term from the title of the div */
                var term = jQuery(this).attr("title");
                if (term) {
                    var last_ID = $(".tweet_result:first", this).attr("ID");
                    /* check for ID of last tweet */
                    if (last_ID) {
                        last_ID = last_ID.replace("tweet", "");
                        /* load all results added after last_ID */
                        var url = "http://search.twitter.com/search.json?q="+encodeURIComponent(term)+"&#038;since_id=" + last_ID + "&#038;callback=?";
                    } else {
                        var url = "http://search.twitter.com/search.json?q="+encodeURIComponent(term)+"&#038;rpp=5&#038;callback=?";
                    }
                    /* store a reference to the tweet container div to use in the getJSON callback */
                    var feedArea = this;
                    /* retrieve the results from twitter */
                    jQuery.getJSON(url, function(json) {
                        var results = '';
                        jQuery(json.results).each(function() {
                            if (this.id == undefined) return;
                            /* make the HTML for each tweet and add to results */
                            results += "
<p class='tweet_result' id='tweet" + this.id + "'><a href='http://twitter.com/" + this.from_user + "' class='tweet_user'><img width='16' height='16' alt='" + this.from_user + " on Twitter' src='" + this.profile_image_url + "' /></a>" + linkify(this.text) + "

";
                        });
                        /* add to feed area */
                        if (last_ID) {
                            jQuery(feedArea).prepend(results);
                        } else {
                            jQuery(feedArea).append(results);
                        }
                    });
                    /* clear results if there are more than 20 */
                    jQuery(".tweet_result:gt(20)", this).remove();
                }
        	});
          }
    }
    function linkify(text) {
    	text = text.replace(/(https?:\/\/\S+)/gi, function (s) {
    	    return '<a href="' + s + '">' + s + '</a>';
    	});
        text = text.replace(/(^|)@(\w+)/gi, function (s) {
            return '<a href="http://twitter.com/' + s + '">' + s + '</a>';
        });
        text = text.replace(/(^|)#(\w+)/gi, function (s) {
	    return '<a href="http://search.twitter.com/search?q=' + s.replace(/#/,'%23') + '">' + s + '</a>';
	});
	return text;
    }
    if ($(".twitter_feed").length) {
        load_tweets();
        setInterval(load_tweets, 10000);
    }
});
&lt;/script&gt;
</pre>
<p>Now, to embed a tweet on a page, all you need to do is add the following (i.e. for a search on the hashtag #rgs10):</p>
<pre class="brush:js">
&lt;div class="twitter_feed" title="#rgs10"&gt;&lt;/div&gt;
</pre>
<p>I also added a bit of CSS to float the twitter image to the left of the tweet:</p>
<pre class="brush:js">
/* twitter feed */
.tweet_result a img {
	border:none;
	float:left;
	margin:0 1em 1em 0;}
.tweet_result {
	clear:both;}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/09/03/embedding-a-twitter-feed-using-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MODx ManagerLogin snippet redirection</title>
		<link>http://bjorsq.net/blog/2010/07/01/login-redirection/</link>
		<comments>http://bjorsq.net/blog/2010/07/01/login-redirection/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 11:55:27 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[MODx]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=259</guid>
		<description><![CDATA[Do you use LoginLogoutLink and ManagerLogin to have a nicely formatted login page? This hack will ensure that when you login, you remain on the page you came from.]]></description>
			<content:encoded><![CDATA[<h2><strong>Problem:</strong></h2>
<p>I get an email from someone with a page URL saying &#8220;Can you please correct a typo on this page?&#8221; with a URL to the page. I click on the link in the email, see the typo and hit the login link at the bottom of the page so I can edit the page, but when I&#8217;m logged in I have to navigate back to the page in question (usually by clicking on the link in the email again).</p>
<h2><strong>Solution:</strong></h2>
<p>What I need is to be able to log in when I&#8217;m on a page, then be redirected back to that page so I can edit it. I&#8217;m using <a href="http://modxcms.com/extras/package/245">LoginLogoutLink</a> to produce the links at the bottom of the page, and <a href="http://modxcms.com/extras/package/?package=254">ManagerLogin</a> to manage the login process.</p>
<h3><strong>Steps:</strong></h3>
<p>First, make sure these two snippets are installed and working correctly, then first edit the LoginLogoutLink snippet in the manager</p>
<p><strong>Change:</strong></p>
<pre class="brush:php">$login_args = '';
$logout_args = '&amp;action=logout';
</pre>
<p><strong>To:</strong></p>
<pre class="brush:php">$login_args = '&amp;from_page_id=' . $modx-&gt;documentIdentifier;
$logout_args = '&amp;action=logout&amp;from_page_id=' . $modx-&gt;documentIdentifier;
</pre>
<p>This will add an extra parameter to the link containing the ID of the page the link is added to, so it can be communicated to ManagerLogin.</p>
<p>Second, edit the ManagerLogin snippet file (assets/snippets/managerlogin/inc/managerlogin.inc.php) &#8211; there are a few edits to this file, so starting near the top:</p>
<p><strong>Under the line containing:</strong></p>
<pre class="brush:php; first-line: 55">if(!($action = $_POST['action'])) { $action = $_GET['action']; }
</pre>
<p><strong>Add:</strong></p>
<pre class="brush:php; first-line: 56">$from_page = false;
if (isset($_POST["from_page_id"])) {
&#09;$from_page = $modx-&gt;getDocument($_POST["from_page_id"], '*', 1);
} elseif (isset($_GET["from_page_id"])) {
&#09;$from_page = $modx-&gt;getDocument($_GET["from_page_id"], '*', 1);
}
</pre>
<p>This will populate the variable <code>$from_page</code> with the document details in an associative array (if the document exists and is published). If <code>$_POST["from_page_id"]</code> or <code>$_GET["from_page_id"]</code> are not set, or if they are but the id given does not correspond to a valid document, then <code>$from_page</code> will be <code>false</code>.</p>
<p><strong>Scroll down to where the code for a successful login is to find:</strong></p>
<pre class="brush:php; first-line: 192">  if($_SESSION['mgrValidated']) {
   // check if we should redirect user to a web page
</pre>
<p><strong>Add this block under the comment:</strong></p>
<pre class="brush:php; first-line: 194">    if ($from_page) {
      $url = $modx-&gt;makeUrl($from_page["id"]);
      header("Location: {$url}");
    }
</pre>
<p>This is the part which performs the redirection. While you still have this block on your clipboard, paste it in the code which deals with logouts, so that it will work here as well.</p>
<p><strong>Under:</strong></p>
<pre class="brush:php; first-line: 219">session_destroy();
</pre>
<p><strong>Paste:</strong></p>
<pre class="brush:php; first-line: 220">    if ($from_page) {
      $url = $modx-&gt;makeUrl($from_page["id"]);
      header("Location: {$url}");
    }
</pre>
<p>The login form now needs some way of communicating the ID of the page you have come from to the login process, so you need to add a hidden field to the login form. This is done by adding a placeholder to managerlogin.inc.php:</p>
<pre class="brush:php; first-line: 253>$modx-&gt;setPlaceholder('ml.from_page_id', $from_page["id"]);
</pre>
<p>You also need to add the placeholder to whatever you are using as a template. ManagerLogin uses the file <code>assets/snippets/managerlogin/inc/templates.inc.php</code> by default, or you can use a chunk.</p>
<p><strong>In templates.inc.php under:</strong></p>
<pre class="brush:php; first-line: 9">. 'Â  &lt;input type="hidden" name="[+ml.action_name+]" value="[+ml.action_val+]" /&gt;' . "\n"</pre>
<p><strong>Add:</strong></p>
<pre class="brush:php; first-line: 10">. 'Â  &lt;input type="hidden" name="from_page_id" value="[+ml.from_page_id+]" /&gt;' . "\n"
</pre>
<p>Now you have your hidden field (or an empty string if the ID wasn&#8217;t passed to ManagerLogin, or wasn&#8217;t valid), which you can add to the login form by pasting <code>$from_page_html</code> into it between the openeing and closing <code>&lt;form&gt;</code> tags.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/07/01/login-redirection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing users from Ning to WordPress MU</title>
		<link>http://bjorsq.net/blog/2010/06/18/ning-to-wordpress/</link>
		<comments>http://bjorsq.net/blog/2010/06/18/ning-to-wordpress/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 12:38:28 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=252</guid>
		<description><![CDATA[Moving from Ning to wordpress? In the absence of an import script, here is a way to get those ning users from the csv dump into wordpress (NOT buddypress).]]></description>
			<content:encoded><![CDATA[<p>I had the good fortune the other day of porting an existing Ning Network to a WordPress blog &#8211; one of the more difficult steps along the way was getting the users from one system to another. If you are the owner of a Ning network, you can get a dump of all your member data as a CSV file, so this is where I started. I loaded the CSV into a spreadsheet (I&#8217;m using OpenOffice 3 calc in this example) and typed this formula into Cell P2 and copied it down the column for all users:</p>
<pre class="brush:js">="INSERT INTO `wp_users` (`user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `display_name`) VALUES ('"&amp;C2&amp;"', '$P$BjjzrX8sSIa0pu.wzQK9BJQleqaxnb/', '" &amp; SUBSTITUTE(SUBSTITUTE(TRIM(C2);"@";"");".";"") &amp; "', '" &amp; C2 &amp; "', '" &amp; IF(O2="";"";"http://" &amp; O2) &amp; "', '" &amp; TEXT(J2;"yyyy-mm-dd") &amp; " 12:00:00', '" &amp; SUBSTITUTE(TRIM(A2);"'";"\'") &amp; "');"</pre>
<p>N.B. You can use the same formula in Excel, but you will need to replace the semicolons in the SUBSTITUTE, IF and TEXT functions with commas.</p>
<p>This will generate the SQL you need to add your users with the following properties:</p>
<ul>
<li>they will all have emails as usernames</li>
<li> their nice_names are generated from the username by stripping the @ and . from the email</li>
<li> display_name will be the full name</li>
<li> user_registered will be noon on the day they registered at ning.com</li>
<li> all passwords will be set to &#8220;password&#8221;</li>
</ul>
<p>NOTE: nice_names may not be correct &#8211; when these are generated by wordpress from the login name, it checks for escape characters and sequences (no such check is done here, but it should be safe as the source is an email address). If you want to set a different password, try resetting your own WP password, then copy how it is stored in wp_users into the formula above.</p>
<p>There are some data fields in Ning which we wanted to port over to the WordPress profile, namely <em>Town, County/State/Region, Country</em>, <em>Institution/Organisation</em>, <em>Occupation/Position</em> and <em>Interests</em>. This can be done by pasting the following code either into a WordPress plugin, or into the theme functions.php file you are using:</p>
<pre class="brush:php;smart-tabs:true">/**
 * custom profile fields
 */
add_action( 'show_user_profile', 'custom_show_extra_profile_fields' );
add_action( 'edit_user_profile', 'custom_show_extra_profile_fields' );
function custom_show_extra_profile_fields( $user ) { ?&gt;
&lt;h3&gt;Extra profile information&lt;/h3&gt;
    &lt;table class="form-table"&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;label for="location"&gt;Town, County/State/Region, Country&lt;/label&gt;&lt;/th&gt;
            &lt;td&gt;
                &lt;input type="text" name="location" id="location" value="&lt;?php echo esc_attr( get_the_author_meta( 'location', $user-&gt;ID ) ); ?&gt;" class="regular-text" /&gt;&lt;br /&gt;
                &lt;span class="description"&gt;Please enter your Geographical Location.&lt;/span&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;label for="organisation"&gt;Institution/Organisation&lt;/label&gt;&lt;/th&gt;
            &lt;td&gt;
                &lt;input type="text" name="organisation" id="organisation" value="&lt;?php echo esc_attr( get_the_author_meta( 'organisation', $user-&gt;ID ) ); ?&gt;" class="regular-text" /&gt;&lt;br /&gt;
                &lt;span class="description"&gt;Please enter your Institution/Organisation name.&lt;/span&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;label for="position"&gt;Occupation/Position&lt;/label&gt;&lt;/th&gt;
            &lt;td&gt;
                &lt;input type="text" name="position" id="position" value="&lt;?php echo esc_attr( get_the_author_meta( 'position', $user-&gt;ID ) ); ?&gt;" class="regular-text" /&gt;&lt;br /&gt;
                &lt;span class="description"&gt;Please enter your Occupation/Position within your Institution/Organisation.&lt;/span&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;label for="interests"&gt;Interests&lt;/label&gt;&lt;/th&gt;
            &lt;td&gt;
                &lt;textarea name="interests" id="interests" rows="5" cols="30"&gt;&lt;?php echo esc_attr( get_the_author_meta( 'interests', $user-&gt;ID ) ); ?&gt;&lt;/textarea&gt;&lt;br /&gt;
                &lt;span class="description"&gt;Please enter your academic interests.&lt;/span&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;th&gt;&lt;label for="twitter"&gt;Twitter&lt;/label&gt;&lt;/th&gt;
            &lt;td&gt;
                &lt;input type="text" name="twitter" id="twitter" value="&lt;?php echo esc_attr( get_the_author_meta( 'twitter', $user-&gt;ID ) ); ?&gt;" class="regular-text" /&gt;&lt;br /&gt;
                &lt;span class="description"&gt;Please enter your Twitter username.&lt;/span&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/table&gt;
&lt;?php }

add_action( 'personal_options_update', 'custom_save_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'custom_save_extra_profile_fields' );
function custom_save_extra_profile_fields( $user_id ) {
    if ( !current_user_can( 'edit_user', $user_id ) ) {
        return false;
    }
    update_usermeta( $user_id, 'location', $_POST['location'] );
    update_usermeta( $user_id, 'organisation', $_POST['organisation'] );
    update_usermeta( $user_id, 'position', $_POST['position'] );
    update_usermeta( $user_id, 'interests', $_POST['interests'] );
    update_usermeta( $user_id, 'twitter', $_POST['twitter'] );
}
</pre>
<p>Now we need to add all th data for the users, and then add all the metadata for themâ€¦</p>
<p>First make a note of the highest user_id you have in the wp_users table, then run the SQL query on it using phpMyAdmin. Now you need a lookup to insert the user_meta, so run the following query on MySQL, inserting your highest user_id:</p>
<pre class="brush:sql">SELECT `user_email`, `ID` FROM `wp_users` WHERE `ID` &gt; [highest_user_id_before_import] ORDER BY `user_email` ASC</pre>
<p>Export this as a csv and get it into another worksheet to act as a lookup table. What this is for is to look up the newly minted wordpress user_ids using the email address as a key. This is done using the VLOOKUP function in the spreadsheet. In my case the formula to do this was <code>=VLOOKUP(C1;Sheet2.$A$1:$B$156;2)</code> &#8211; I had pasted my email addresses and IDs into Sheet2, and there were 156 of them, so the cell range was A1:B156 &#8211; the dollar signs fix this cell range when you copy the formula &#8211; the 2 denotes the column we need to return from the lookup. Paste this formula into Q2 and copy it down the column and you should see your wordpress IDs.</p>
<p>The next part is importing all the user metadata &#8211; for this we will need to split the Full Name field fron Ning into a first_name and second_name &#8211; the formulae for these (paste into R2 and S2) are:</p>
<pre class="brush:js">=TRIM(MID(A2;1;SEARCH(" ";A2;1)))
=TRIM(MID(A2;SEARCH(" ";A2;1);100))
</pre>
<p>Copy these formulae down the R and S columns, and clean up any values which look incorrect. Now paste the following formula into T2 and copy it down the column &#8211; you will need to edit the formula to insert the correct values for the primary blog, source_domain, capabilities and user_level (for some pointers on what to put in these last two fields, read my previous post on importing users from WordPress):</p>
<pre class="brush:js">="INSERT INTO `wp_usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES (" &amp; Q2 &amp; ", 'rich_editing', 'true'), (" &amp; Q2 &amp; ", 'admin_color', 'fresh'), (" &amp; Q2 &amp; ", 'primary_blog', '[primary_blog_id]'), (" &amp; Q2 &amp; ", 'source_domain', '[domain of primary blog]'), (" &amp; Q2 &amp; ", 'wp_[primary_blog_id]_user_level', '2'),(" &amp; Q2 &amp; ", 'wp_[primary_blog_id]_capabilities', 'a:1:{s:6:""author"";b:1;}'), (" &amp; Q2 &amp; ", 'nickname', '" &amp; SUBSTITUTE(SUBSTITUTE(TRIM(A2);"'";"\'");" ";"") &amp; "'), (" &amp; Q2 &amp; ", 'first_name', '" &amp; SUBSTITUTE(TRIM(R2);"'";"\'") &amp; "'), (" &amp; Q2 &amp; ", 'last_name', '" &amp; SUBSTITUTE(TRIM(S2);"'";"\'") &amp; "'), (" &amp; Q2 &amp; ", 'location', '" &amp; SUBSTITUTE(TRIM(K2);"'";"\'") &amp; "'), (" &amp; Q2 &amp; ", 'organisation', '" &amp; SUBSTITUTE(TRIM(L2);"'";"\'") &amp; "'), (" &amp; Q2 &amp; ", 'position', '" &amp; SUBSTITUTE(TRIM(M2);"'";"\'") &amp; "'), (" &amp; Q2 &amp; ", 'interests', '" &amp; SUBSTITUTE(TRIM(N2);"'";"\'") &amp; "');"
</pre>
<p>Now you should have a list of INSERTs for the user meta table &#8211; copy the column contents and run the statements in phpMyAdmin.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/06/18/ning-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Redirecting users to their primary blog in WordPress MU</title>
		<link>http://bjorsq.net/blog/2010/06/17/redirect-to-primary-blog/</link>
		<comments>http://bjorsq.net/blog/2010/06/17/redirect-to-primary-blog/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 22:02:04 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=250</guid>
		<description><![CDATA[Using the login_redirect filter in Wordpress isn't as intuitive as it may seem...]]></description>
			<content:encoded><![CDATA[<p>I wanted to find a way of redirecting users to their primary blog in WordPress MU, so checked out this forum topic:</p>
<p><a href="http://mu.wordpress.org/forums/topic/13452?replies=22">http://mu.wordpress.org/forums/topic/13452?replies=22</a></p>
<p>Got a few pointers here, and also from theÂ  source for the &#8216;login_redirect&#8217; hook:</p>
<p><a href="http://adambrown.info/p/wp_hooks/hook/login_redirect?version=2.9&amp;file=wp-login.php">http://adambrown.info/p/wp_hooks/hook/login_redirect?version=2.9&amp;file=wp-login.php</a></p>
<p>After pulling my hair out for about an hour using the filter, it seemed that the $redirect_to variable it is supposed to alter was either being ignored or altered later in the execution of wp_login.php. From the source, you can see that the login_redirect filters are applied prior to a bit of processing which redirects users to their profile, so it is neccessary to redirect logins within the filter function itself to get it to work. This is the bit of code I arrived at which eventually worked (using WPMU 2.9.2):</p>
<pre class="brush:js">
&lt;?php
// redirect users to their primary blog
function change_login_redirect($redirect_to, $request_redirect_to, $user)
{
    if ($user-&gt;ID != 0) {
        $user_info = get_userdata($user-&gt;ID);
        if ($user_info-&gt;primary_blog) {
            $primary_url = get_blogaddress_by_id($user_info-&gt;primary_blog);
            if ($primary_url) {
                //redirect to primary blog
                wp_redirect($primary_url);
                die();
            }
        }
    }
    return $redirect_to;
}
// add filter with low priority (100), filter takes (3) parameters
add_filter('login_redirect','change_login_redirect', 100, 3);
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/06/17/redirect-to-primary-blog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress MU User Capabilities Plugin</title>
		<link>http://bjorsq.net/blog/2010/06/13/user-capabilities-plugin/</link>
		<comments>http://bjorsq.net/blog/2010/06/13/user-capabilities-plugin/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 12:32:49 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=245</guid>
		<description><![CDATA[WPMU plugin which lists all blogs and users and lets you set the capability of each user on each blog.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just released the first version of a plugin I developed for WordPress MU at <a href="http://wpmudev.org/">http://wpmudev.org</a>.</p>
<p>The plugin lists all blogs and users and lets you set the capability of each user on each blog. It was written to help me in a project where a set of five blogs were used to allow 5 groups to communicate with each other. Each group had its own blog, but all five were tightly integrated with the same theme.</p>
<p>The plugin creates a new Admin page under the Users menu which outputs a table containing each user in the system as a row, and each (public) blog as a column. You can then assign Roles to each user for each blog using a drop-down menu.</p>
<p>It is only currently suitable for installations where a limited number of users are present and a limited number of blogs are used.</p>
<p><strong>Development</strong></p>
<p>This plugin was developed for a specific purpose, so its use in some WPMU installations may be impractical. I will be developing this plugin so that:</p>
<ul>
<li>The blogs displayed in columns can be filtered/configured</li>
<li>The table is paged for systems with a large number of users</li>
<li>Capabilities can be set for all users on a blog simultaneously</li>
</ul>
<p><strong>Installation</strong></p>
<p>Upload the plugin file to the mu-plugins directory.</p>
<p><strong>Download</strong></p>
<p><a href="http://bjorsq.net/wp-content/uploads/2010/06/user_capabilities_manager-1.0.zip">Version 1.0, released 13th June 2010</a></p>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/06/13/user-capabilities-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Date and Walnut Cake</title>
		<link>http://bjorsq.net/blog/2010/04/29/date-and-walnut-cake/</link>
		<comments>http://bjorsq.net/blog/2010/04/29/date-and-walnut-cake/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 08:30:09 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[cakes]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=239</guid>
		<description><![CDATA[Made this cake for Bob's birthday - adapted from a recipe by delia with addition of buttercream filling.]]></description>
			<content:encoded><![CDATA[<p><strong>Ingredients</strong></p>
<ul>
<li>6 oz (175 g) dates, stoned and chopped</li>
<li>1 level teaspoon bicarbonate of soda</li>
<li>1 oz (25 g) butter</li>
<li>8 oz (225 g) self-raising flour</li>
<li>Â¼ teaspoon salt</li>
<li>1 level teaspoon mixed spice</li>
<li>1 level teaspoon ground cinnamon</li>
<li>Â½ teaspoon ground cloves</li>
<li>Â½ teaspoon nutmeg</li>
<li>2 eggs</li>
<li>5 oz (150 g) soft dark brown sugar</li>
<li>1 teaspoon vanilla extract</li>
<li>3 oz (75 g) ground almonds</li>
<li>3 oz (75 g) chopped walnuts</li>
</ul>
<p><em>For the buttercream:</em></p>
<ul>
<li>2 oz (55 g) icing sugar</li>
<li>4 oz butter</li>
<li>rind from 1Â½ lemons</li>
<li>1 tablespoon lemon juice</li>
</ul>
<p><em>For the icing:</em></p>
<ul>
<li>4 oz (110 g) icing sugar, sifted</li>
<li>the grated rind of Â½ lemon</li>
<li>1 tablespoon lemon juice</li>
<li>Â½ oz (10 g) melted butter</li>
<li>1 dessertspoon single cream</li>
</ul>
<p><strong>Method</strong></p>
<p>Pre-heat the oven to gas mark 4, 350Â°F (180Â°C).</p>
<p>In a small bowl, pour 8 fl oz (225 ml) boiling water over the dates. Add the bicarbonate of soda, then the butter and stir until the butter has melted. Leave to cool.</p>
<p>Sift the flour with the salt and spices.</p>
<p>Beat the egg in a large bowl, add the sugar and beat well again, then add the cooled date mixture and all the other cake ingredients.</p>
<p>Stir well to mix everything thoroughly together, then pour the mixture into the tin, and put it in the oven just below the centre shelf. Cook for about an hour, or until the top is nicely browned and the centre feels springy. Let the cake stand for a couple of minutes and then turn it out on to a wire rack to cool.</p>
<p>When cool, cut the cake in half and fill with the lemon buttercream.</p>
<p>For the icing, mix all the ingredients well together, then cover the top of the cake and add a few walnut halves arranged round the top.</p>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/04/29/date-and-walnut-cake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bread and butter pudding</title>
		<link>http://bjorsq.net/blog/2010/04/01/bread-and-butter-pudding/</link>
		<comments>http://bjorsq.net/blog/2010/04/01/bread-and-butter-pudding/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 20:58:13 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[cakes]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=222</guid>
		<description><![CDATA[Overdone the bread shop? Use your spare stale (or fresh) bread, bagels etc. to make a deliciously light pudding.]]></description>
			<content:encoded><![CDATA[<p><strong>Ingredients</strong></p>
<ul>
<li>25g/1oz butter, plus extra for greasing</li>
<li>8 thin slices bread</li>
<li>50g/2oz sultanas</li>
<li>2 tsp cinnamon powder</li>
<li>350ml/12fl oz whole milk</li>
<li>50ml/2fl oz double cream</li>
<li>3 free-range eggs</li>
<li>25g/1oz granulated sugar</li>
<li>nutmeg, grated, to taste</li>
</ul>
<p><strong>Method</strong></p>
<ol>
<li>Grease a 1 litre pie dish with butter.</li>
<li>Cut the crusts off the bread. Spread each slice with on one side with butter, then cut into triangles.</li>
<li>Arrange a layer of bread, buttered-side up, in the bottom of the dish, then add a layer of sultanas. Sprinkle with a little cinnamon, then repeat the layers of bread and sultanas, sprinkling with cinnamon, until you have used up all of the bread. Finish with a layer of bread, then set aside.</li>
<li>Crack the eggs into a bowl, add the milk, cream and three quarters of the sugar and lightly whisk until pale.</li>
<li>Pour the mixture over the prepared bread layers and sprinkle with nutmeg and the remaining sugar and leave to stand for 30 minutes.</li>
<li>Preheat the oven to 180C/355F/Gas 4.</li>
<li>Place the dish into the oven and bake for 30-40 minutes, or until the custard has set and the top is golden-brown.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/04/01/bread-and-butter-pudding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Importing WordPress users into WordPress MU</title>
		<link>http://bjorsq.net/blog/2010/04/01/import-wp-users-into-wpmu/</link>
		<comments>http://bjorsq.net/blog/2010/04/01/import-wp-users-into-wpmu/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 20:53:31 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=214</guid>
		<description><![CDATA[Of course, this is no longer required for version 3.0, but here is how to do it anyway...]]></description>
			<content:encoded><![CDATA[<p>This should cover a situation where you have a single wordpress installation with subscribers/contributors/editors, and you want to import all users into a WordPress MU installation.</p>
<p><strong>Adding the users</strong></p>
<p>The first part of the process is importing the users from one blog to the other, along with their usernames and passwords. Care should be taken to ensure that there are no duplicate usernames or email addresses imported</p>
<ol>
<li>First, you need to export the users and usermeta tables from the WordPress database using phpMyAdmin &#8211; export both sets of data as comma-delimited CSV files, and check the box &#8220;Put fields names in the first row&#8221;.</li>
<li>Open the two CSV files as two different worksheets in a spreadsheet (I used <a href="http://www.openoffice.org/product/calc.html" target="_blank">OpenOffice Calc</a>).</li>
<li>Now export the WordPress blog using Tools-&gt;Export, create a new blog in your WordPress MU installation, and import the blog using Tools-&gt;Import on the new WordPress MU blog&#8217;s dashboard. You may notice at this point that, although some users have been imported along with the content of the blog, they may have incorrect usernames, lack an email address and most of the usermeta stuff. The users imported here are attached to the posts and comments on the blog, whereas subscribers and non-contributors are absent completely.</li>
<li>Go to phpMyAdmin for the WordPress MU installation, and browse the users table. Make a note of the IDs of the users who were imported with the data from the blog. Now go to the worksheet with the exported users table from the WordPress installation, and substitute the WPMU IDs for the ones corresponding to the users you&#8217;re importing (this ensures that authorship of their posts is kept consistent). In my case, I had only four authors imported, and the rest were subscribers, so I only had to do 4 substitutions here, and re-number the others accordingly.</li>
<li>Still in the spreadsheet, scroll to column L (or the first free column) and paste this into L1:
<pre class="brush: sql">INSERT INTO `wp_users` (`ID`, `user_login`, `user_pass`, `user_nicename`, `user_email`, `user_url`, `user_registered`, `user_activation_key`, `user_status`, `display_name`, `spam`, `deleted`) VALUES</pre>
</li>
<li>In L2, paste this formula:
<pre class="brush: plain">="("&amp;A2&amp;", '"&amp;SUBSTITUTE(B2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(C2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(D2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(E2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(F2;"'";"\'")&amp;"', STR_TO_DATE('"&amp;G2&amp;"', '%d/%m/%Y %H:%i:%s'), '"&amp;SUBSTITUTE(H2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(I2;"'";"\'")&amp;"', '"&amp;SUBSTITUTE(J2;"'";"\'")&amp;"', 0, 0"&amp;"),"</pre>
<p>Now copy the formula down the column, and select the bottom cell &#8211; replace the end of the formula &#8220;),&#8221; with &#8220;);&#8221;. To get this working in OpenOffice Calc, I first had to put an apostrophe in front of the dates in the `user_registered` column (to force it to treat the cells as text rather than dates). Copy the column onto the clipboard.</li>
<li>Back over in phpMyAdmin, delete the imported users from the table. Click the SQL tab, and paste in the Query from the spreadsheet. Click &#8220;Go&#8221; and all your users are instantly registered.</li>
</ol>
<p><strong>Adding metadata and assigning permissions</strong></p>
<p>The second part of this process is assigning the users metadata from the usermeta table.</p>
<ol>
<li> Open the worksheet with the usermeta table export in it, and change any user_id fields in the same way you did in step 4.</li>
<li>Sort the data in the worksheet by the meta_key field and delete any you don&#8217;t want to import (like those relating to plugins, and others which are serialized data structures). I imported &#8216;admin_color&#8217;, &#8216;comment_shortcuts&#8217;, &#8216;first_name&#8217;, &#8216;last_name&#8217;, &#8216;nickname&#8217; and &#8216;rich editing&#8217;.</li>
<li>Now flick over to the users worksheet, and copy the user IDs from the first column. Go back to the usermeta worksheet, and scroll to the bottom. To add new key/value pairs for all users, first paste in the user IDs in the user_id column, then type in the meta_key and meta_value in their respective columns (and copy down to all cells). we need to add the following key/values for all users:
<ol>
<li>&#8220;source_domain&#8221; &#8211; domain of the WordPress MU blog</li>
<li>&#8220;primary_blog&#8221; &#8211; blog ID of the WordPress MU blog</li>
<li>&#8220;wp_[x]_capabilities&#8221;Â  &#8211; where [x] is the blog ID &#8211; values for this key are explained below</li>
<li>&#8220;wp_[x]_user_level&#8221;Â  &#8211; where [x] is the blog ID &#8211; values for this key are explained below</li>
</ol>
</li>
<li>The wp_[x]_capabilities key is serialized data and has different values for different roles &#8211; see the table below for the values to choose from:<br />
<table class="withborders">
<thead>
<tr>
<th>wp_[x]_user_level</th>
<th>wp_[x]_capabilities</th>
</tr>
</thead>
<tbody>
<tr>
<td>10</td>
<td>a:1:{s:13:&#8221;administrator&#8221;;b:1;}</td>
</tr>
<tr>
<td>7</td>
<td>a:1:{s:6:&#8221;editor&#8221;;b:1;}</td>
</tr>
<tr>
<td>2</td>
<td>a:1:{s:6:&#8221;author&#8221;;b:1;}</td>
</tr>
<tr>
<td>1</td>
<td>a:1:{s:11:&#8221;contributor&#8221;;b:1;}</td>
</tr>
<tr>
<td>n/a</td>
<td>a:1:{s:10:&#8221;subscriber&#8221;;b:1;}</td>
</tr>
</tbody>
</table>
</li>
<li>Set the user permissions by copying values from the table above into the usermeta worksheet for each user &#8211; for all users with greater capability than subscribers, you need to add a &#8220;wp_[x]_user_level&#8221; key as well. It may be a good idea here to set any capabilities for the main blog (I want all users to be subscribers) &#8211; which is done by adding meta_values for the meta_key &#8220;wp_1_capabilities&#8221;</li>
<li>Now scroll to column E (or the first free column) and paste this into E1:
<pre class="brush: sql">INSERT INTO `wp_usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES</pre>
</li>
<li>In E2, paste this formula:
<pre class="brush: plain">="("&amp;B3&amp;",'"&amp;C3&amp;"','"&amp;D3&amp;"'),"</pre>
<p>Now copy the formula down the column, and select the bottom cell &#8211; replace the end of the formula &#8220;),&#8221; with &#8220;);&#8221;. Copy the column onto the clipboard.</li>
<li>Back over in phpMyAdmin, delete any metadata for the imported users from the wp_usermeta table. Click the SQL tab, and paste in the Query from the spreadsheet. Click &#8220;Go&#8221; and all your users have the correct permission set.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/04/01/import-wp-users-into-wpmu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Social Privacy to create a part-public, part-private WordPress Blog</title>
		<link>http://bjorsq.net/blog/2010/03/02/social-privacy/</link>
		<comments>http://bjorsq.net/blog/2010/03/02/social-privacy/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 16:10:02 +0000</pubDate>
		<dc:creator>pete</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://bjorsq.net/?p=212</guid>
		<description><![CDATA[Using the Social Privacy set of plugins for Wordpress]]></description>
			<content:encoded><![CDATA[<p><strong>Objective:</strong> I needed to be able to restrict access to some content on a WordPress installation to subscribers (users who are logged in), but leave some content public.</p>
<p><strong>First Attempt</strong></p>
<p>I thought I would use the &#8220;make post private&#8221; feature of pages/posts in WordPress itself. This would be ideal, as authors/editors could change the privacy settings on posts and pages in the Quick Edit form (which I tend to over-use). However, posts/pages marked as private are only visible to Editors and Administrators of the blog, as well as the author of the post/page. I wanted all members to have access to them without making the default user role an Editor. Back to the drawing board&#8230;</p>
<p><strong>Social Privacy</strong></p>
<p>This set of plugins looked quite promising, in that it appears to do exactly what I want:</p>
<p>http://wordpress.org/extend/plugins/social-privacy/</p>
<p>However, I found that it restricts access to categories, and my pages didn&#8217;t have categories, so I installed a plugin which allows you to assign categories to pages:</p>
<p>http://www.amit.me/assign-categories-to-pages-in-wordpress/545/</p>
<p>Still no luck though, and when I took a peek at the Social Privacy plugin code, it was obvious why &#8211; all static pages (set in Settings-&gt;Reading) and other, normal pages are filtered out from the result set before the privacy settings are applied.</p>
<p><strong>Solution</strong></p>
<p>This required a quick re-think of how I wanted my pages to work &#8211; basically the two static pages (Home and News) would be public, along with any other posts which weren&#8217;t in my magic &#8220;private&#8221; category (which the Social Privacy plugin filtered on, as well as &#8220;uncategorized&#8221;, so users couldn&#8217;t inadvertently make anything public). The other pages I had identified for the site needed to be changed so they became category pages, i.e. rather than having a static page for content, you create a category page for it and list all posts in that category. This way, all the content was managed as posts (rather than pages, apart from my two static pages), and so all content could be secured by the use of the Social Privacy plugin. I also created a &#8220;Public&#8221; category so posts could be shown for non-members (but hidden from members).</p>
]]></content:encoded>
			<wfw:commentRss>http://bjorsq.net/blog/2010/03/02/social-privacy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

