<?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>nemrod.se</title>
	<atom:link href="http://nemrod.se/feed/" rel="self" type="application/rss+xml" />
	<link>http://nemrod.se</link>
	<description>Various guides and experiments</description>
	<lastBuildDate>Wed, 01 Feb 2012 19:09:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Lists with section signs (§) using CSS counters and content</title>
		<link>http://nemrod.se/guides/lists-with-section-signs-%c2%a7-using-css-counters-and-content/</link>
		<comments>http://nemrod.se/guides/lists-with-section-signs-%c2%a7-using-css-counters-and-content/#comments</comments>
		<pubDate>Fri, 06 Jan 2012 09:36:10 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=351</guid>
		<description><![CDATA[When listing rules or statutes you might want to have a section sign in front of each number. I found myself in that situation the other day but found absolutely nothing about it on Google, so here&#8217;s me publishing my way to do it just to alleviate the blatant lack of information on the net. [...]]]></description>
			<content:encoded><![CDATA[<p>When listing rules or statutes you might want to have a section sign in front of each number. I found myself in that situation the other day but found absolutely nothing about it on Google, so here&#8217;s me publishing my way to do it just to alleviate the blatant lack of information on the net.</p>
<p>The way I did it was using the <a rel="external" target="_blank" href="http://www.w3.org/TR/CSS21/generate.html#before-after-content">:before pseudo class</a>, <a rel="external" target="_blank" href="http://www.w3.org/TR/CSS21/generate.html#content">content property</a>, <a rel="external" target="_blank" href="http://www.w3.org/TR/CSS21/generate.html#counters">CSS counters</a> and finally <a rel="external" target="_blank" href="http://www.w3.org/TR/CSS2/text.html#indentation-prop">text-indent</a> to make up for lost indentation.</p>
<p>The final code looks something like this:
<pre>ol#statutes {
	counter-reset: section; # resets the counter
	margin-left: 23px; # modify this according to your layout
}
ol#statutes > li { # > so as to not affect nested lists
	list-style-type: none; # or we'd have 1. §1.
	text-indent: -23px; # adjust this for your font and size
}
ol#statutes > li:before {
	content: '§' counter(section) '. '; # here's where the magic happens
	counter-increment: section; # increment counter for next time
}
ol#statutes > li li {
	text-indent: 0; # because it's inherited
}</pre>
<p>It&#8217;s possible to create several counters so you can change the way subsections look and all sorts of nice things.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/guides/lists-with-section-signs-%c2%a7-using-css-counters-and-content/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Install RPM packages on Arch Linux</title>
		<link>http://nemrod.se/guides/install-rpm-packages-on-arch-linux/</link>
		<comments>http://nemrod.se/guides/install-rpm-packages-on-arch-linux/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 23:47:47 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=328</guid>
		<description><![CDATA[I recently found myself wanting to upload music to Google Music from my computer with Arch Linux but found that they only had RPM and APT (.deb) packages available for download. It&#8217;s fairly straightforward to install an RPM on Arch: Download the RPM for your architecture (64- or 32-bit) Install rpmextract for extracting the RPM [...]]]></description>
			<content:encoded><![CDATA[<p>I recently found myself wanting to upload music to Google Music from my computer with Arch Linux but found that they only had RPM and APT (.deb) packages available for download. It&#8217;s fairly straightforward to install an RPM on Arch:</p>
<ol>
<li>Download the RPM for your architecture (64- or 32-bit)</li>
<li>Install rpmextract for extracting the RPM and any dependencies the program has (libidn for Google Music Manager for example) with pacman</li>
<li>Now create a new folder, move the RPM file to it and go there</li>
<li>Run rpmextract.sh and you&#8217;ll get a directory structure based on the root (/) in the current directory</li>
<li>Copy the files to where they belong in your own file hierarchy</li>
</ol>
<p>There are some downsides to this, though. For example you won&#8217;t be able to easily uninstall the program, nor will it warn you if you remove any of the dependencies. That&#8217;s why I thought it would be a better idea to create an Arch package out of it.</p>
<p>To create an Arch package basically all you need is to create a PKGBUILD file which contains all of the information about the package you&#8217;re about to create. Here are their own <a href="https://wiki.archlinux.org/index.php/Creating_Packages" rel="external" target="_blank">instructions</a> (which contains a lot more information but also takes longer to figure out if all you want to do is convert an RPM package) and here&#8217;s a <a href="https://wiki.archlinux.org/index.php/PKGBUILD" rel="external" target="_blank">reference</a> for the different variables you can use in a PKGBUILD file.</p>
<p>This is what my PKGBUILD file ended up like:</p>
<pre># Maintainer: Anders Mårtensson &lt;anders@nemrod.se&gt;
pkgname=google-musicmanager-beta
pkgver=current
pkgrel=2
pkgdesc="A program necessary to upload audio files to your Google Music library."
arch=('x86_64')
url="https://music.google.com/"
license=('unknown')
depends=('libidn')
makedepends=('rpmextract')
options=('emptydirs')
source=("http://dl.google.com/linux/direct/google-musicmanager-beta_current_x86_64.rpm")
md5sums=('6c05f087f9cd77563b7d001584e3b2d8')

build() {
  cd "$pkgdir"
  rpmextract.sh ../google-musicmanager-beta_current_x86_64.rpm
}</pre>
<p>As you can see it&#8217;s pretty straight-forward:</p>
<ul>
<li>Name of the program (lowercase, no spaces, etc.)</li>
<li>Version (Google says &#8220;current&#8221; and I couldn&#8217;t bother figuring out the actual version number so I went with it)</li>
<li>An internal version number that should increment by one for every change to the package</li>
<li>A short description (less than about 80 characters)</li>
<li>The architecture (i686, x86_64, both or any)</li>
<li>A URL to the official site of the package (optional)</li>
<li>License (GPL, BSD, unknown, etc.)</li>
<li>Any dependencies the program might have (separated by space, no comma)</li>
<li>Dependencies only required to build but not run the program</li>
<li>Any options (in this case there were some empty directories after extraction which I found unnecessary so I used the emptydirs option)</li>
<li>A list of source files (these will be downloaded when installing if they&#8217;re URLs, but you can also provide local files putting them in the same folder as the PKGBUILD file)</li>
<li>A list of md5sums for the files (you can get these by running &#8220;makepkg -g&#8221; in the folder with the files).</li>
<li>Finally there&#8217;s the build script which does the extracting</li>
</ul>
<p>Once you&#8217;ve created the PKGBUILD file run &#8220;makepkg&#8221; in the folder and watch it create the .pkg.tar.xz file for use with pacman! Install it with pacman -U and you&#8217;re done. It will complain if you are missing dependencies and you can remove the package with pacman -R just like when installing with pacman -S. Simple, huh?</p>
<p>How a session of doing this might look:</p>
<pre>mkdir package # might want a more descriptive folder ;)
cd package
cp /usr/share/pacman/PKGBUILD.proto PKGBUILD # it's a prototype file to save a lot of keypresses
vim PKGBUILD # modify it to fit your package
makepkg -g # will download any files specified and spit back an md5sum line, copy it
vim PKGBUILD # paste in the md5sums returned from the previous command
makepkg # you may get complaints about dependencies you don't have installed, install them and run until it goes till the end
pacman -U *.pkg.tar.xz # and it's installed!</pre>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/guides/install-rpm-packages-on-arch-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clock Icon</title>
		<link>http://nemrod.se/chrome-extensions/clock-icon/</link>
		<comments>http://nemrod.se/chrome-extensions/clock-icon/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 05:43:15 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Chrome Extensions]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=319</guid>
		<description><![CDATA[This extension, requested by an acquaintance, quite simply displays the current time (and date on hover) next to the omnibox in Chrome. Really nothing more to it. Technically it displays the current time in a HH:MM format in the badge of a browser action. The badge is specified to fit four characters or less according [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nemrod.se/site/wp-content/uploads/2011/11/icon1281.png"><img src="http://nemrod.se/site/wp-content/uploads/2011/11/icon1281.png" alt="Clock Icon" title="" width="128" height="128" class="alignleft size-full wp-image-320" style="box-shadow: none; margin: 5px 10px 10px 0;" /></a>This extension, requested by an acquaintance, quite simply displays the current time (and date on hover) next to the omnibox in Chrome. Really nothing more to it. Technically it displays the current time in a HH:MM format in the badge of a browser action. The badge is specified to fit four characters or less according to the developer docs, but at least for me it&#8217;s working just fine with five (HH:MM). Report in if it doesn&#8217;t for you. :)</p>
<p><a class="button" href="https://chrome.google.com/webstore/detail/blpgdogcjmmkhendjpiilidbllpainfh">Clock Icon on Chrome Web Store</a></p>
<p>Just for fun here&#8217;s the source:<br />
<em>manifest.json</em></p>
<pre>{
	"name": "Clock Icon",
	"version": "1.0",
	"description": "Shows the time (hours and minutes) next to the omnibox.",
	"icons": { "128": "icon128.png" },
	"background_page": "background.html",
	"browser_action": {
		"default_icon": "icon128.png",
		"default_title": "dd/mm/yyyy hh:mm"
	}
}</pre>
<p><em>background.html</em></p>
<pre>&lt;html>
	&lt;script>
		chrome.browserAction.setBadgeBackgroundColor({"color": [0,0,0,255]});

		function pad(s, n) {
			s = '' + s;
			while(s.length < n) {
				s = '0' + s;
			}
			return s;
		}

		function updateTime() {
			dateobj = new Date();

			year = pad(dateobj.getFullYear(), 4);
			month = pad(dateobj.getMonth(), 2);
			day = pad(dateobj.getDate(), 2);
			hour = pad(dateobj.getHours(), 2);
			minute = pad(dateobj.getMinutes(), 2);

			badge = hour + ':' + minute;
			title = day + '/' + month + '/' + year + ' ' + badge;
			chrome.browserAction.setBadgeText({"text": badge});
			chrome.browserAction.setTitle({"title": title});

			var t = setTimeout("updateTime()", 10000);
		}

		updateTime();
	&lt;/script>
&lt;/html></pre>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/chrome-extensions/clock-icon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disable F12 from opening the Developer Console in Chrome</title>
		<link>http://nemrod.se/chrome-extensions/disable-f12-developer-console-chrome/</link>
		<comments>http://nemrod.se/chrome-extensions/disable-f12-developer-console-chrome/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 03:01:43 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Chrome Extensions]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=307</guid>
		<description><![CDATA[Linus Torvalds made a post on Google+ asking if there was a convenient way of disabling F12 from opening the developer console in Chrome (because apparently he&#8217;s &#8220;totally spastic and uncontrolled&#8221; when going for backspace ;)). I, of course, had to oblige by creating a Chrome extension: Disable F12 on Chrome Web Store It can [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://nemrod.se/site/wp-content/uploads/2011/11/icon128.png" alt="F12 key" title="" width="128" height="128" class="alignleft size-full wp-image-313" style="margin: 5px 10px 10px 0; box-shadow: none;" />Linus Torvalds made a <a href="https://plus.google.com/102150693225130002912/posts/7PsYYeavcA9" rel="external" target="_blank">post on Google+</a> asking if there was a convenient way of disabling F12 from opening the developer console in Chrome (because apparently he&#8217;s &#8220;totally spastic and uncontrolled&#8221; when going for backspace ;)).</p>
<p>I, of course, had to oblige by creating a Chrome extension: <a class="button" href="https://chrome.google.com/webstore/detail/kpfnljnhmfhomajodmlepkcoflmbjiaf">Disable F12 on Chrome Web Store</a></p>
<p>It can access &#8220;your data on all websites&#8221; because it needs to inject a JavaScript that captures the F12 keypress and prevents the event from going any further. You can inspect the code in the extension yourself but if you can&#8217;t be bothered here it is:</p>
<p><em>manifest.json</em></p>
<pre>{
	"name": "Disable F12",
	"version": "1.0",
	"description": "An extension to disable F12 opening the dev console.",
	"icons": { "128": "icon128.png" },
	"content_scripts": [
		{
			"matches": ["*://*/*"],
			"js": ["disablef12.js"]
		}
	]
}</pre>
<p><em>disablef12.js</em></p>
<pre>window.addEventListener("keydown", keyListener, false);

function keyListener(e) {
	if(e.keyCode == 123) {
		e.returnValue = false;
	}
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/chrome-extensions/disable-f12-developer-console-chrome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Matches&#8221; WordPress plugin</title>
		<link>http://nemrod.se/wordpress/matches-wordpress-plugin/</link>
		<comments>http://nemrod.se/wordpress/matches-wordpress-plugin/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 14:53:32 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=293</guid>
		<description><![CDATA[This is a WordPress plugin I made when we were making a new website for an ice hockey team. It basically lets you administer teams and matches and display them with a neat little widget. Here&#8217;s a screenshot of what it could look like (ignore the names and logos): Here are the various admin panes: [...]]]></description>
			<content:encoded><![CDATA[<p>This is a WordPress plugin I made when we were making a new website for an ice hockey team. It basically lets you administer teams and matches and display them with a neat little widget. Here&#8217;s a screenshot of what it could look like (ignore the names and logos):<br />
<a href="http://nemrod.se/site/wp-content/uploads/2011/11/matches-1.png"><img src="http://nemrod.se/site/wp-content/uploads/2011/11/matches-1.png" alt="Widget for Matches WordPress plugin" title="matches-1" width="226" height="255" class="alignnone size-full wp-image-300" /></a></p>
<p>Here are the various admin panes:<br />
<a href="http://nemrod.se/site/wp-content/uploads/2011/11/matches-2.png"><img src="http://nemrod.se/site/wp-content/uploads/2011/11/matches-2-300x118.png" alt="Settings for your own team and how many upcoming matches to display in the widget" title="matches-2" width="300" height="118" class="alignnone size-medium wp-image-301" /></a><br />
<a href="http://nemrod.se/site/wp-content/uploads/2011/11/matches-3.png"><img src="http://nemrod.se/site/wp-content/uploads/2011/11/matches-3-300x118.png" alt="Adding, editing and deleting opponents" title="matches-3" width="300" height="118" class="alignnone size-medium wp-image-302" /></a><br />
<a href="http://nemrod.se/site/wp-content/uploads/2011/11/matches-4.png"><img src="http://nemrod.se/site/wp-content/uploads/2011/11/matches-4-300x118.png" alt="The most important thing of all, administering the matches between you and your opponent" title="matches-4" width="300" height="118" class="alignnone size-medium wp-image-303" /></a></p>
<p>You can see a live example at <a href="http://www.krif-hockey.net">http://www.krif-hockey.net</a> in the sidebar to the left.</p>
<p>And finally, if you&#8217;re interested in trying it, here it is:<br />
<a class="button" href="http://wordpress.org/extend/plugins/matches/">Matches in the WordPress Plugin Directory</a></p>
<p>If you&#8217;re an awfully generous person and like this plugin, any donations (<a href="#donate">there&#8217;s a button in the sidebar</a>) are terribly appreciated. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/wordpress/matches-wordpress-plugin/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Page 2 of The One Page Per Person Project</title>
		<link>http://nemrod.se/misc/one-page-per-person-page-2/</link>
		<comments>http://nemrod.se/misc/one-page-per-person-page-2/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 11:42:46 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=276</guid>
		<description><![CDATA[This is page 2 of a collaborative novel where each participant (open to anyone) writes about one page or 250 words. For more background information I advise you to read &#8220;The Most Novel Blog Novel&#8221; by my friend and colleague Fredrik. If you want to read the whole story make sure to start at the [...]]]></description>
			<content:encoded><![CDATA[<p>This is page 2 of a collaborative novel where each participant (open to anyone) writes about one page or 250 words. For more background information I advise you to read <a href="http://cbsmth.se/misc/the-most-novel-blog-novel/">&#8220;The Most Novel Blog Novel&#8221;</a> by my friend and colleague Fredrik. If you want to read the whole story make sure to <a href="http://cbsmth.se/misc/one-page-per-person-page-1/">start at the first page</a>.</p>
<blockquote><p>Frozen stiff he stared in silence, thoughts coming and going like flashes of lightning through his mind. Friend? Foe? He didn’t have particularly many enemies that he knew of, but he had no clue what he had done, or who he had met, during the several hours long gaping hole in his memory. What had he been running from? Long seconds passed, the only noise coming from the rain still smashing against the window he had previously stared out of, the only one in the room.</p>
<p>Another series of loud bangs. He couldn’t stay idle, whoever they were they didn’t show any sign of going away. Besides, chances were they could tell him a lot of things he desperately wanted to know. He quickly and stealthily moved over the dirty floor, avoiding the junk littered all over the place, towards the shabby door with grey, previously white paint peeling while wishing that whoever it belonged to had had the common decency to install a peephole. He stood right next to the door listening. Whoever was outside made no sound. Had they gone away?</p>
<p>Several more, this time even louder, bangs. Jared, being only centimeters from the door, recoiled, fell and found himself on the floor with a clank and a bang! He had just enough time to make a mental note to give a real scolding to the owner of the apartment for leaving junk right inside the door, would he ever get the chance, before the door flung up with a thud and a crash!</p>
<p>In the doorway, whose door was now crooked and on one hinge, stood a large character, black and with fuzzy edges against the strong fluorescent lights in the hallway. “Hollow core door. Typical.” thought Jared while he let his eyes adjust, heart beating like jungle drums, escape plans rushing through his mind. Neither of them said anything. Neither of them moved. His eyes soon adjusted and Jared let out a sigh of relief and almost started laughing as all the tension left his body. He knew this man.</p>
<p><em>Written 2011/07/26 by Anders Mårtensson of <a href="http://nemrod.se">nemrod.se</a>.<br />
Distributed under a <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons BY-NC-SA Licence</a>.</em></p></blockquote>
<p>It&#8217;s certainly not easy to keep it at 250 words &#8211; Fredrik exceeded it by 35 and I by almost a hundred and it sure is harsh not to be able to keep writing right when it&#8217;s gotten to the interesting part. Oh well.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/misc/one-page-per-person-page-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Custom page listing with thumbnails for WordPress [PHP]</title>
		<link>http://nemrod.se/wordpress/custom-page-listing-with-thumbnails-for-wordpress-php/</link>
		<comments>http://nemrod.se/wordpress/custom-page-listing-with-thumbnails-for-wordpress-php/#comments</comments>
		<pubDate>Mon, 30 May 2011 13:13:42 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=268</guid>
		<description><![CDATA[I have run into several cases where I need to list subpages to a certain page in a neat little list with thumbnails, mostly for listing products. Since I&#8217;ve had to reuse it several times I thought I might as well share it since others might be looking for something similar. To see it in [...]]]></description>
			<content:encoded><![CDATA[<p>I have run into several cases where I need to list subpages to a certain page in a neat little list with thumbnails, mostly for listing products. Since I&#8217;ve had to reuse it several times I thought I might as well share it since others might be looking for something similar. To see it in action here are two examples (both in Swedish, but you get the idea from the visuals): <a href="http://www.ramonadesign.se/brudklanningar/atelier-diagonal/">Bröllopsklänningar</a> and <a href="http://www.batcenter.se/begagnade-batar/">Begagnade båtar</a>. As you can see they list them differently, the first lists them in a grid while the second lists them in a list with excerpts attached. The code below is the first, but it&#8217;s easily customisable, tell me if you want any help!</p>
<pre>&lt;?php
    $children = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_parent = $post->ID AND post_type = 'page' AND post_status = 'publish' ORDER BY menu_order", 'OBJECT');
    if($children) {
        echo '&lt;table>&lt;tr>';
        $j = 0;
        foreach($children as $child) {
            setup_postdata($child);
            $attachment = get_posts("post_type=attachment&#038;orderby=menu_order&#038;order=ASC&#038;post_parent=$child->ID");
            if($attachment) {
                $i = 0;
                for($i = 0; $i &lt; sizeof($attachment); $i++) {
                    if('application/pdf' != $attachment[$i]->post_mime_type) {
                        $image = wp_get_attachment_thumb_url($attachment[$i]->ID);
                        break;
                    }
                }
            }
            if($j &#038;&#038; $j % 4 == 0) {
                echo '&lt;/tr>&lt;tr>';
            }
            echo '&lt;td>';
            echo '&lt;h2>&lt;a href="' . get_permalink($child->ID) . '">' . $child->post_title . '&lt;/a>&lt;/h2>';
            if($image) {
                echo '&lt;a href="' . get_permalink($child->ID) . '">&lt;img src="' . $image . '" />&lt;/a>';
            }
            echo '&lt;/td>';
            unset($image);
            $j++;
        }
        echo '&lt;/tr>&lt;/table>';
    }
?></pre>
<p>There are some minor improvements that can be made to pretty up the code &#8211; the $j variable for example I&#8217;d rather have in a for-loop and replace the foreach, but it was an addition to the code where the variable wasn&#8217;t needed at all and I haven&#8217;t been buggered to make any such changes. ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/wordpress/custom-page-listing-with-thumbnails-for-wordpress-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Breadcrumb function with heading structure for WordPress [PHP]</title>
		<link>http://nemrod.se/wordpress/breadcrumb-function-with-heading-structure-for-wordpress-php/</link>
		<comments>http://nemrod.se/wordpress/breadcrumb-function-with-heading-structure-for-wordpress-php/#comments</comments>
		<pubDate>Wed, 23 Mar 2011 10:28:09 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=254</guid>
		<description><![CDATA[My coworker wanted breadcrumbs where the ancestry went from h1 all the way down to as deep as you are for one of our clients&#8217; website, and so I wrote this little function for him: &#60;?php function hawt_breadcrumb() { global $post; $pages = array(); $pages[] = array(get_permalink(), get_the_title()); $parent = $post->post_parent; while($parent) { $pages[] = [...]]]></description>
			<content:encoded><![CDATA[<p>My coworker wanted breadcrumbs where the ancestry went from h1 all the way down to as deep as you are for one of our clients&#8217; website, and so I wrote this little function for him:</p>
<pre>&lt;?php
    function hawt_breadcrumb() {
        global $post;

        $pages = array();

        $pages[] = array(get_permalink(), get_the_title());

        $parent = $post->post_parent;
        while($parent) {
            $pages[] = array(get_permalink($parent), get_the_title($parent));
            $parent = get_post($parent)->post_parent;
        }   

        $i = 1;
        foreach(array_reverse($pages) as $page) {
            echo "&lt;h$i&gt;$page[1]&lt;/h$i&gt;";
            $i++;
        }
    }
?&gt;</pre>
<p>Might as well share it in case someone is in the need of something similar. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/wordpress/breadcrumb-function-with-heading-structure-for-wordpress-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automatic Daily Backup of Files &amp; Database to USB stick</title>
		<link>http://nemrod.se/guides/automatic-backup-of-files-database-to-usb-stick/</link>
		<comments>http://nemrod.se/guides/automatic-backup-of-files-database-to-usb-stick/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 19:54:54 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=234</guid>
		<description><![CDATA[On a development project I&#8217;m working on I was challenged with the task of setting up a daily backup of code and database until the project is completed and everything is moved to a production server that has a more proper backup system in place. The customer, with physical access to the development server, suggested [...]]]></description>
			<content:encoded><![CDATA[<p>On a development project I&#8217;m working on I was challenged with the task of setting up a daily backup of code and database until the project is completed and everything is moved to a production server that has a more proper backup system in place.</p>
<p>The customer, with physical access to the development server, suggested daily backups to a USB stick. He also suggested that the USB stick is switched with an identical one weekly with the other one being locked up in a safe place in case of fire or theft.</p>
<p>My first thought was to simply create a script that copies everything to a folder where I&#8217;ve mounted the USB stick, but it didn&#8217;t take long before I realised this would mean trouble when the USB sticks are switched once a week. I considered simply adding a check to see if it&#8217;s mounted and if not mount /dev/sdb1 in the correct folder, but after switching them once I noticed that the USB stick was actually assigned to /dev/sdc this time. Solution? udev. udev, an accompanying script to mount and finally the backup script.</p>
<p>What udev does is react to physical devices, identified by a set of rules, being connected or disconnected from the computer with things such as creating symlinks to the device and running scripts upon detection. It&#8217;s perfect for what I want to do &#8211; create a symlink (/dev/usbackup1) so it doesn&#8217;t matter what device name the stick gets assigned, sdb or sdc, and run a script to mount it where I want (/mnt/usbackup/)!</p>
<p>Here&#8217;s how the new udev rules file (/etc/udev/rules.d/10-usbackup.rules) look:</p>
<pre>KERNEL=="sd*", SUBSYSTEMS=="scsi", ATTRS{vendor}=="Verbatim", SYMLINK+="usbackup%n", RUN+="/usr/local/bin/mount_usbackup"</pre>
<p>The first three key-value pairs (the pairs are separated by comma) are for matching the device, in this case the kernel name for the device should match &#8220;sd*&#8221;, meaning sd and any letter, it should be in the &#8220;scsi&#8221; subsystem and finally the &#8220;vendor&#8221; attribute should match Verbatim (the maker of the USB stick in this case). There are plenty other attributes to match, such as partition size and model.</p>
<p>The remaining two key-value pairs are the ones that do all the magic &#8211; first of all to create a symlink to the device called /dev/usbackup. The &#8220;%n&#8221; is there to instruct udev to also create symlinks to the separate partitions (/dev/usbackup1 for the first partition etcetera). It then continues to run the script in /usr/local/bin/ called mount_usbackup. All the script does is mount the device where I want it to:</p>
<pre>#! /bin/sh
mount /dev/usbackup1 /mnt/usbackup/</pre>
<p>Finally! We can now be sure that we always have the right device mounted exactly where we want and won&#8217;t have to worry about any switching or manual mounting. What&#8217;s left? To actually create the backup, duh.</p>
<p>I chose to put my script in /etc/cron.daily to run it daily, but if you want to run it on a different schedule feel free to add a new entry to crontab or any other way you see fit. My script looks like this:</p>
<pre>#! /bin/sh
tar -C /path/to/parent/ -cjf /mnt/usbackup/projectname/code/projectname_`date +'%F'`.tar.bz2 folder/
mysqldump -uuser -ppassword database | bzip2 > /mnt/usbackup/backup/projectname/db/projectname_`date +'%F'`.sql.bz2</pre>
<p>The first line (after the shebang) first changes directory (&#8220;-C /path/to/parent/&#8221;) so we won&#8217;t have the full structure when we unpack and then creates a .tar.bz2 archive where we mounted the USB stick of the folder we want to create a backup of (&#8220;folder/&#8221; in this case).The second line dumps the MySQL database, pipes the output to bzip2 and puts it in a file on the USB stick. Both files are named projectname_&lt;date in Y-m-d format&gt;.ext.bz2 so we know what day the backup was taken.</p>
<p>It&#8217;s really quite simple and the bzip2 makes sure the backups doesn&#8217;t take up much space. In my case the whole thing, code and database, is just under half a megabyte after compression. As you can see it&#8217;s not an incremental backup, it makes a full copy every day, but as the size is so small (in my case at least) and it&#8217;ll be moved to a production server within two months I didn&#8217;t deem it necessary to make anything more complicated.</p>
<p>So yeah, that was my little backup endeavour.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/guides/automatic-backup-of-files-database-to-usb-stick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nemLightBox &#8211; a very simple WordPress plugin</title>
		<link>http://nemrod.se/wordpress/nemlightbox/</link>
		<comments>http://nemrod.se/wordpress/nemlightbox/#comments</comments>
		<pubDate>Wed, 20 Oct 2010 18:35:44 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://nemrod.se/?p=213</guid>
		<description><![CDATA[Today I decided to use an old jQuery lightbox script I wrote long ago for the thumbnails I have in some posts on this site (for example on the MacBook reed switch post or the Password Generator post) and the easiest way to do that (apart from what&#8217;s actually easiest &#8211; just including the code [...]]]></description>
			<content:encoded><![CDATA[<p>Today I decided to use an old jQuery lightbox script I wrote long ago for the thumbnails I have in some posts on this site (for example on the <a href="http://nemrod.se/hardware/macbook-reed-switch">MacBook reed switch</a> post or the <a href="http://nemrod.se/chrome-extensions/password-generator/">Password Generator</a> post) and the easiest way to do that (apart from what&#8217;s actually easiest &#8211; just including the code right in the template) is of course to make it into a WordPress plugin.</p>
<p>The code for the plugin is very short since it&#8217;s got very limited functionality (lightbox all image links and that&#8217;s about it), but both people interested in how a basic WordPress plugin might look and those interested in how you make a lightbox in jQuery might find this interesting nonetheless. :)</p>
<p><strong>wp-content/plugins/nemlightbox/nemlightbox.php</strong></p>
<pre>&lt;?php
    /*
        Plugin Name: nemLightBox
        Plugin URI: http://nemrod.se/wordpress/nemlightbox/
        Description: A very simplistic lightbox plugin - opens all image links in a lightbox
        Version: 0.1
        Author: Anders Mårtensson
        Author URI: http://nemrod.se/about/
        License: BSD
    */

    wp_enqueue_script('jquery');
    $nlb_script_url = WP_PLUGIN_URL . '/nemlightbox/nlb.js';
    $nlb_script_file = WP_PLUGIN_DIR . '/nemlightbox/nlb.js';
    if(file_exists($nlb_script_file)) {
        wp_register_script('nlb', $nlb_script_url);
        wp_enqueue_script('nlb');
    }
?&gt;</pre>
<p><strong>wp-content/plugins/nemlightbox/nlb.js</strong></p>
<pre>$j = jQuery.noConflict();
$j(function() {
    $j('a[href$=".jpg"], a[href$=".png"], a[href$=".gif"]').click(function(event) {
        var html = '&lt;div id="nlb"&gt;&lt;div style="position:fixed;top:0;left:0;height:100%;width:100%;display:block;background:#000;opacity:0.7;"&gt;&lt;/div&gt;&lt;div style="position:fixed;top:0;left:0;height:100%;width:100%;display:table;"&gt;&lt;div style="display:table-cell;vertical-align:middle;text-align:center;"&gt;&lt;div style="display:inline-block;background:#eee;padding:20px 20px 5px;"&gt;&lt;img src=""&gt;&lt;p style="font-size:12px;font-family:sans-serif;color:#333;text-decoration:underline;"&gt;Click anywhere to close&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;';
        $j('body').append(html);
        $j('#nlb img').attr('src', $j(this).attr('href'));
        event.preventDefault();
    });
    $j('#nlb').live('click', function(event) {
        $j('#nlb').remove();
        event.preventDefault();
    });
});</pre>
<p>Click one of the links to the posts above to check it out in action. If anyone against better judgement (it really isn&#8217;t that bad though, just simplistic) wants a .zip of it so they can just install in on their blog/site I don&#8217;t mind making one, just ask and I&#8217;ll update the post.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/wordpress/nemlightbox/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Validera Personnummer (Swedish SSN Validator)</title>
		<link>http://nemrod.se/projects/validera-personnummer-swedish-ssn-validator/</link>
		<comments>http://nemrod.se/projects/validera-personnummer-swedish-ssn-validator/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 08:38:46 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=127</guid>
		<description><![CDATA[This post will be in Swedish since it will mainly be interesting to a Swedish audience. The code will work just the same and shouldn&#8217;t be too hard to figure out. På ett uppdrag jag slutförde för ett tag sedan uppstod problemet att bekräfta att en person inte redan fanns registrerad i databasen. Det är [...]]]></description>
			<content:encoded><![CDATA[<p>This post will be in Swedish since it will mainly be interesting to a Swedish audience. The code will work just the same and shouldn&#8217;t be too hard to figure out.</p>
<p>På ett uppdrag jag slutförde för ett tag sedan uppstod problemet att bekräfta att en person inte redan fanns registrerad i databasen. Det är givetvis rätt lätt att kolla om personnumret redan finns registrerat, men vad är det som säger att personen inte helt enkelt bestämde sig för att skriva in några slumpmässiga siffror i fältet? Inget, om du inte validerar personnumret.</p>
<p>Ett personnummer är uppbyggt av sex siffror för födelsedatumet, två siffror för var man föddes (innan 1990) eller ett löpnummer (efter 1990), en udda siffra för män eller en jämn för kvinnor och till sist en kontrollsiffra, som är den siffra vi måste räkna ut för att bekräfta att personnumret är giltligt utformat. Du kan läsa mer på <a href="http://sv.wikipedia.org/wiki/Personnummer_i_Sverige#Uppbyggnad">Wikipedias artikel om personummer i Sverige</a>.</p>
<p>Så här ser koden jag skrev ut:</p>
<pre>function validateSSN($personnummer = 'yymmddxxxx') {
    $summa = 0;
    for($i = 1; $i < 10; $i++) {
        $del = $personnummer[$i - 1] * ($i % 2 + 1);
        $summa += ($del > 9 ? 1 + $del % 10 : $del);
    }
    return !(($summa + $personnummer[9]) % 10);
}</pre>
<p>Självklart bekräftar inte det här att det är personens riktiga personummer och om han på liknande sätt räknar ut en kontrollsiffra för ett slumpmässigt personnummer eller gissar tillräckligt länge kommer han förmodligen att kunna komma förbi valideringen. Det är ändock en viktig validering då de flesta i min erfarenhet ger upp att &#8220;förfalska&#8221; sitt personummer när de märker att deras första slumpmässiga input inte fungerar.</p>
<p>Uppdatering: gjorde om det till en funktion och kortade ner koden en aning.</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/projects/validera-personnummer-swedish-ssn-validator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>EvoMaxx SEO Quiz</title>
		<link>http://nemrod.se/misc/evomaxx-seo-quiz/</link>
		<comments>http://nemrod.se/misc/evomaxx-seo-quiz/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 07:58:55 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=125</guid>
		<description><![CDATA[A while back I assisted in writing questions for an SEO quiz (in Swedish). It&#8217;s a quite difficult quiz (especially if you don&#8217;t speak Swedish&#8230;), as you can tell from the statistics, so don&#8217;t be offended if you get a low score. I, of course, got 100%. Then again, I did write most of the [...]]]></description>
			<content:encoded><![CDATA[<p>A while back I assisted in writing questions for an SEO quiz (in Swedish). It&#8217;s a quite difficult quiz (especially if you don&#8217;t speak Swedish&#8230;), as you can tell from the statistics, so don&#8217;t be offended if you get a low score. I, of course, got 100%. Then again, I did write most of the questions. ;)</p>
<p><a style="background-image: url('http://www.evomaxx.se/quiz/badges/evomaxx-seoquiz-badge-big-100.png'); height: 117px; width: 247px; border: none; display: block;" href="http://www.evomaxx.se/verktyg/seo-quiz/" title="Sätt dina SEO-kunskaper på prov med EvoMaxx SEO-Quiz" target="_blank"></a></p>
<p>Feel free to comment any suggestions or opinions, or maybe just your score! I&#8217;d love to hear about how you did. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/misc/evomaxx-seo-quiz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Analytics Individual Qualification</title>
		<link>http://nemrod.se/misc/google-analytics-individual-qualification/</link>
		<comments>http://nemrod.se/misc/google-analytics-individual-qualification/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 19:53:40 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=123</guid>
		<description><![CDATA[Today I took the Google Analytics Individual Qualification exam, and passed of course.]]></description>
			<content:encoded><![CDATA[<p>Today I took the Google Analytics Individual Qualification exam, and passed of course.</p>
<div id="attachment_134" class="wp-caption alignnone" style="width: 450px"><a href="https://googlerecords.starttest.com?code=I007CFD5FFC6BF87AF273F664FE6AF0C6356AEB"><img class="size-full wp-image-134 " title="Google Analytics Individual Qualification" src="http://nemrod.se/site/wp-content/uploads/2010/01/gaiq_certificate.png" alt="Google Analytics Individual Qualification" width="440" height="340" /></a><p class="wp-caption-text">Here&#39;s proof that I got the certificate ;)</p></div>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/misc/google-analytics-individual-qualification/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pong in C/ncurses</title>
		<link>http://nemrod.se/projects/pong-in-c-ncurses/</link>
		<comments>http://nemrod.se/projects/pong-in-c-ncurses/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 20:51:57 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=121</guid>
		<description><![CDATA[This is a two players, one keyboard Pong written in C with &#8220;graphics&#8221; using the ncurses library. It was written over a year and a half ago and I haven&#8217;t read the code since, so it&#8217;s likely to be total or at least partial crap. Playing it now I can spot two immediate flaws that [...]]]></description>
			<content:encoded><![CDATA[<p>This is a two players, one keyboard Pong written in C with &#8220;graphics&#8221; using the ncurses library. It was written over a year and a half ago and I haven&#8217;t read the code since, so it&#8217;s likely to be total or at least partial crap.</p>
<p>Playing it now I can spot two immediate flaws that I should&#8217;ve done something about. First of all the ball always moves at the same angle and speed. Second of all if you press and hold a key to move, the opponent can press a key and your movement will stop.</p>
<p>Other than that it&#8217;s pretty straight forward, just compile the C source file and play, against yourself or with a friend, an up and down key pair each.</p>
<p>It&#8217;s free as in free speech (and free beer) so you have no restrictions regarding usage or modifications to it, but it&#8217;s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host any new versions here. :)</p>
<p><a class="button" href="http://nemrod.se/proj/pong/pong.c">pong.c</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/projects/pong-in-c-ncurses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hangman in Python</title>
		<link>http://nemrod.se/projects/hangman-in-python/</link>
		<comments>http://nemrod.se/projects/hangman-in-python/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 15:34:27 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=119</guid>
		<description><![CDATA[This is a refurbished version of a Python script I wrote on Dreamhack many years ago. It&#8217;s pretty simple, there is an array of words that it randomly selects one from and then you can guess. It displays the word with underscores as placeholders for unknown characters, with the real characters where they&#8217;re supposed to [...]]]></description>
			<content:encoded><![CDATA[<p>This is a refurbished version of a Python script I wrote on Dreamhack many years ago. It&#8217;s pretty simple, there is an array of words that it randomly selects one from and then you can guess. It displays the word with underscores as placeholders for unknown characters, with the real characters where they&#8217;re supposed to be if you&#8217;ve guessed them right.</p>
<p>It also displays wrong guesses and ASCII art of the classic hangman scenery according to how many times you&#8217;ve guessed on a wrong letter. You can change the ASCII file without affecting the game, just remember to keep every scene on ten lines. You can add more scenes (10 lines per scene) to the file and the game will adjust accordingly, not letting the game end until you get to the last scene.</p>
<p>It uses a wide range of methods and tricks in Python, such as list comprehension and shorthand if, so it might be fun to learn from. For example, this is how it prints the scenery:</p>
<pre>    file = open('ascii', 'r')
    hangman = file.readlines()
    print ''.join([line for line in hangman[len(wrong) * 10:len(wrong) * 10 + 10]])</pre>
<p>and this is how it prints the word (letter or underscore):</p>
<pre>    for letter in word:
        print letter if letter in right else '_ ',</pre>
<p>It&#8217;s also only about 45 lines of code (30-35 SLOC I guess), so it&#8217;s not very much code to look at. :)</p>
<p>It&#8217;s free as in free speech (and free beer) so you have no restrictions regarding usage or modifications to it, but it&#8217;s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host the new version here. :)</p>
<p><a class="button" href="http://nemrod.se/proj/hangman/hangman.py">hangman.py</a><br />
<a href="http://nemrod.se/proj/hangman/ascii">ascii art of hangman, required to play</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/projects/hangman-in-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Battery level logger</title>
		<link>http://nemrod.se/projects/battery-level-logger/</link>
		<comments>http://nemrod.se/projects/battery-level-logger/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 12:26:49 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=117</guid>
		<description><![CDATA[This is a shell script I wrote on and for a very old laptop (old as in it had a P1 processor) I had. I got the laptop and had heard that the battery was in a bad condition, but after using it for a bit I thought it wasn&#8217;t that shabby. To put it [...]]]></description>
			<content:encoded><![CDATA[<p>This is a shell script I wrote on and for a very old laptop (old as in it had a P1 processor) I had. I got the laptop and had heard that the battery was in a bad condition, but after using it for a bit I thought it wasn&#8217;t that shabby. To put it to the test I had two choices. Sit by the computer and time it, or write a shell script to log the battery level as it went. I obviously went with the shell script.</p>
<p>It has two modes, analyze mode and log mode. They&#8217;re called with &#8216;utp -a FILE&#8217; and &#8216;utp -l FILE&#8217; respectively. The log mode writes the time and the battery level, separated by a comma, to the specified file, sleeps for a second, and repeats. Here is more exactly what it writes:</p>
<pre>echo "$(date +%T), $(apm | cut -d' ' -f5)" | tee -a $OPTARG</pre>
<p>The analyze mode echoes the percent in tens (100-91%, 90-81% etc) and how long those percent took and finally a summary, from what percent it started from to at what percent the last logging took place and how long the whole thing took. Here is an example output (with a faked file so it doesn&#8217;t make much sense):</p>
<pre>Percent:        Time:
100 - 91:       0m10s
90 - 81:        0m10s
80 - 71:        0m10s
70 - 61:        0m10s
60 - 51:        0m10s
50 - 41:        0m10s
40 - 31:        0m10s
30 - 21:        0m10s
20 - 11:        0m10s
10 - 01:        0m10s
The script was logging from 100% to 1% in 1 minutes.</pre>
<p>It&#8217;s free as in free speech (and free beer) so you have no restrictions regarding usage or modifications to it, but it&#8217;s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host the new version here. :)</p>
<p><a class="button" href="http://nemrod.se/proj/utp/utp">utp shell script</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/projects/battery-level-logger/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Password Generator</title>
		<link>http://nemrod.se/chrome-extensions/password-generator/</link>
		<comments>http://nemrod.se/chrome-extensions/password-generator/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 11:41:55 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Chrome Extensions]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=115</guid>
		<description><![CDATA[This is an extension for pure random password generation. You set a length between 5 and 20 characters, if you want it to contain upper-case, lower-case, numbers and special characters and click generate. Since I&#8217;m into the habit of wanting passwords that look good I&#8217;ve made it so you can choose to generate between 1 [...]]]></description>
			<content:encoded><![CDATA[<p>This is an extension for pure random password generation. You set a length between 5 and 20 characters, if you want it to contain upper-case, lower-case, numbers and special characters and click generate. Since I&#8217;m into the habit of wanting passwords that look good I&#8217;ve made it so you can choose to generate between 1 and 5 passwords in one go to make it easier to get those.</p>
<p>Now simply choose the prettiest of the generated passwords and you&#8217;re done! ;)</p>
<h3>Extension information:</h3>
<dl>
<dt>Extension:</dt>
<dd>Password Generator</dd>
<dt>Latest version:</dt>
<dd>v0.2</dd>
<dt>Download link:</dt>
<dd><a class="button" href="https://chrome.google.com/extensions/detail/koebgfmdommchdjodkalonlpjlnbpjap">Password Generator on the Chrome Web Store</a></dd>
<dt>Description:</dt>
<dd>Allows you to generate customisable secure passwords on the fly.</dd>
<dt>Browser compatibility:</dt>
<dd>Chrome build with browser action support</dd>
<dt>Features:</dt>
<dd>
<ul>
<li>Password length between 5 and 20 characters</li>
<li>Generate between 1 and 5 passwords at a time</li>
<li>Choose to include or exclude uppercase characters, lowercase characters, numbers and special characters</li>
<li>Possibility to choose between 3 different themes, or make your own</li>
</ul>
</dd>
<dt>Screenshots:</dt>
<dd>
<div id="attachment_145" class="wp-caption alignnone" style="width: 260px"><a href="http://nemrod.se/site/wp-content/uploads/2009/12/password-generator-dark.png"><img class="size-medium wp-image-145" title="Password Generator dark theme" src="http://nemrod.se/site/wp-content/uploads/2009/12/password-generator-dark-250x300.png" alt="Password Generator dark theme" width="250" height="300" /></a><p class="wp-caption-text">The extension open with the dark theme set.</p></div>
</dd>
</dl>
<h3>Revision history:</h3>
<dl>
<dt>Version 0.1 [05:13, 2009-12-13]:</dt>
<dd>Initial release.</dd>
<dt>Version 0.2 [11:48, 2009-12-20]:</dt>
<dd>Theme support, 3 themes to choose from.</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/chrome-extensions/password-generator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beautiful URLs with mod_rewrite and PHP</title>
		<link>http://nemrod.se/guides/beautiful-urls-with-mod_rewrite-and-php/</link>
		<comments>http://nemrod.se/guides/beautiful-urls-with-mod_rewrite-and-php/#comments</comments>
		<pubDate>Sun, 11 Oct 2009 16:01:33 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=113</guid>
		<description><![CDATA[If you&#8217;re reading this you&#8217;re probably already well aware of the benefits of good URLs &#8211; usability, accessibility and for search engine optimization purposes. In this guide I&#8217;m going to explain how I went from example.com/?p=4&#38;s=12 to nemrod.se/chrome-extensions/pagerank-display using mod_rewrite, PHP and MySQL in the background. Necessary back-end changes If your URLs contain the ID [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re reading this you&#8217;re probably already well aware of the benefits of good URLs &#8211; usability, accessibility and for search engine optimization purposes. In this guide I&#8217;m going to explain how I went from example.com/?p=4&amp;s=12 to <a href="http://nemrod.se/chrome-extensions/pagerank-display">nemrod.se/chrome-extensions/pagerank-display</a> using mod_rewrite, PHP and MySQL in the background.</p>
<h3>Necessary back-end changes</h3>
<p>If your URLs contain the ID of things instead of the titles, you&#8217;re gonna have to do a lot more changes than just mod_rewriting. I don&#8217;t know how others have solved it, but the way I did it was by adding an extra field in my database called sanitized_title or sanitized_name etc. depending on what it is. I then wrote a quick function to sanitize the wanted field when adding new posts, pages or whatever it may be and then add it to the database along with the rest of the data. This is what my function looks like:</p>
<pre>function sanitize($str) {
	$str = strtolower($str);
	$str = strip_tags($str);

	$str = preg_replace('/[^a-z0-9]+/i', ' ', $str);

	$str = preg_replace('/\s+/i', ' ', $str);
	$str = trim($str);

	$str = str_replace(' ', '-', $str);
	return $str;
}</pre>
<p>It first converts the whole string to lower-case and strips it from HTML tags. It then uses regular expression replace to replace everything not a letter or a number with spaces. It then replaces all whitespace with a single space (if the string had &#8220;bla &#8211; bla bla&#8221; that would be three spaces &#8211; now it&#8217;s one) and trims whitespace from the beginning and end of the string. Lastly it replaces the spaces with dashes before returning the string.</p>
<p>If your language has got any additional characters, such as the Swedish å, ä and ö you&#8217;re going to have to add them like this, preferably somewhere near the end:</p>
<pre>	$str = str_replace('å', 'a', $str);
	$str = str_replace('ä', 'a', $str);
	$str = str_replace('ö', 'o', $str);</pre>
<p>Modify the administration interface to add the sanitized string to the database, like this for example:</p>
<pre>$title = mysql_real_escape_string($_POST['title']);
$sanitized_title = sanitize($_POST['title']);
mysql_query('INSERT INTO post (title, sanitized_title) VALUES (\'' . $title . '\', \'' . $sanitized_title . '\')');</pre>
<p>If you&#8217;ve already got a large database without the sanitized field I suggest writing a PHP script that simply loops through all the records in the database, calls the sanitize function on the title, and updates the post. Something like this:</p>
<pre>$result = mysql_query('SELECT * FROM post');
while($row = mysql_fetch_array($result))
	mysql_query('UPDATE post SET sanitized_title=' . sanitize($row['title']) . ' WHERE id=' . $row['id']);</pre>
<p>Now all you have to do is change all the occurences of the ID in the code to the sanitized title. It&#8217;s usually pretty easy since it&#8217;s generated from the database, all you have to do is echo the sanitized_title column instead of the id one! After doing so your site should have URLs similar to example.com/index.php?p=chrome-extensions&amp;s=pagerank-display. It&#8217;s not quite where we want to go, but the hardest part is over!</p>
<h3>mod_rewrite and .htaccess</h3>
<p>Now that we&#8217;re using the sanitized names in the PHP code, the rest is a breeze. All we have to do is make the URLs look pretty for the users with mod_rewrite, modify the PHP code to match, and we&#8217;re done!</p>
<p>The way I used to do my mod_rewrite was using a prefix. In other words, I rewrote the URLs so they looked like example.com/prefix/chrome-extensions/pagerank-display. The reason is because I didn&#8217;t know how to be able to go to other folders on the server, they would all be rewritten if I didn&#8217;t have that prefix! After getting the mission to rewrite the URLs on another site, <a href="http://www.evomaxx.se/">the SEO (search engine optimisation) company I work at</a>, I thought that there has to be a better way than using a prefix and went investigating. I remembered that WordPress had pretty URLs, and went looking in their .htaccess.</p>
<p>What I found was a pretty obvious solution, but something I hadn&#8217;t known could be done with .htaccess files before. What it does is check if the file or folder you&#8217;re trying to go to exists, and if not, it sends you to index.php. No more prefix yet it&#8217;s still possible to get to other files and folders on the server! :)</p>
<p>The code you put in .htaccess looks like this:</p>
<pre>RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php/$i [L,QSA]</pre>
<p>What the lines do:</p>
<ul>
<li>Activates the rewrite engine</li>
<li>Sets the rewrite base, i.e. where we&#8217;re doing the rewriting</li>
<li>Checks if the requested URL is a real file</li>
<li>Checks if the requested URL is a real folder</li>
<li>If it&#8217;s not, we attach the requested URL (the part after the domain name) to index.php, which then further processes the data</li>
</ul>
<p>Now we&#8217;ve successfully sent the pretty URLs to index.php, now we just have to process it and change the links to match!</p>
<h3>The PHP processing</h3>
<p>If you go to <a href="http://nemrod.se/chrome-extensions/pagerank-display">nemrod.se/chrome-extensions/pagerank-display</a> and chrome-extensions/pagerank-display isn&#8217;t a real file or folder the real URL after rewriting will be index.php/chrome-extensions/pagerank-display. The way I process this in PHP is by exploding the REQUEST_URI server variable over / and then setting the appropiate variables to their values. For <a href="http://nemrod.se">nemrod.se</a>, for example, the first variable is the page, and the second is the name of a post. This is how my code looks:</p>
<pre>$uri = explode('/', $_SERVER['REQUEST_URI']);
if(sizeof($uri) &gt; 1 &amp;&amp; !empty($uri[1]))
	$page = $uri[1];
if(sizeof($uri) &gt; 2 &amp;&amp; !empty($uri[2]))
	$post = $uri[2];</pre>
<p>If I echo the $page and $post variables after going to the above URL, they&#8217;ll be chrome-extensions and pagerank-display respectively. The rest is just your ordinary menu generation and stuff, if(!isset($page)) set $page to the first page in the menu generating loop, and so on.</p>
<h3>No error 404?!</h3>
<p>Yes, that&#8217;s right. If the file doesn&#8217;t exist you&#8217;ll be sent to index.php to do all the processing, so you won&#8217;t be getting any error 404! To fix this I added some PHP code to make sure the server returned a 404 if the URL really is a real 404. I&#8217;m sure there are a lot of ways to do it, but in my case I just set a variable to true ($e404 = true;) and if the page was really found when generating the menu etc. I simply set it to false. After the check is done I have an if statement like this:</p>
<pre>if($e404)
	header('HTTP/1.0 404 Not Found');</pre>
<p>Where the content of the page is supposed to be displayed I also have an if, but instead of sending another header I simply inform the visitor that the page he tried to access doesn&#8217;t exist. This also makes for an error 404 with easy access to your site, since it&#8217;ll be displayed right in the middle of it, with the menu accessible and everything. :)</p>
<h4>A tip:</h4>
<p>If you&#8217;ve got URLs with a lot of traffic you might want to do a 301 redirect to your new, pretty, URLs. One of my most visited URLs back when I used prefixes was nemrod.se/n/chrome_extensions/pagerank_display_v1.9. So as to not lose all that traffic this (along with some other URLs) was what I added to my .htaccess:</p>
<pre>RewriteRule ^n/chrome_extensions/pagerank_display_v1.9[\/]?$ http://nemrod.se/chrome-extensions/pagerank-display [R=301,L]</pre>
<p>There are more automated ways to do it, if you&#8217;re already using URLs like index.php?page=name&amp;post=title you can use this, for example (untested):</p>
<pre>RewriteRule ^index.php?page=(.*?)$ http://example.com/$1 [R=301,L]
RewriteRule ^index.php?page=(.*?)&amp;post=(.*?)$ http://example.com/$1/$2 [R=301,L]</pre>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/guides/beautiful-urls-with-mod_rewrite-and-php/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sending mail from outside your network</title>
		<link>http://nemrod.se/guides/sending-mail-from-outside-your-network/</link>
		<comments>http://nemrod.se/guides/sending-mail-from-outside-your-network/#comments</comments>
		<pubDate>Sun, 04 Oct 2009 22:42:07 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=111</guid>
		<description><![CDATA[After having set up a mail server for the company I work at (I&#8217;m a technician at a SEO, PPC and web marketing company) we quickly came across a problem. One of our employees tried to send a mail through our server from outside our network, which resulted in an error. The first problem I [...]]]></description>
			<content:encoded><![CDATA[<p>After having <a href="http://nemrod.se/guides/guide-to-postfix-dovecot-mysql-mail-server">set up a mail server</a> for the company I work at (I&#8217;m a technician at a <a href="http://www.evomaxx.se">SEO, PPC and web marketing company</a>) we quickly came across a problem. One of our employees tried to send a mail through our server from outside our network, which resulted in an error.</p>
<p>The first problem I figured was because pretty much all ISPs in Sweden block port 25 (SMTP). It was quickly solved by routing incoming port 587 to internal port 25 on our server. Yup, it solved the problem. But only the first problem, because after we could actually connect to the server from outside the network we got another problem. An authentication problem. Duh, I should&#8217;ve known.</p>
<p>It&#8217;s supposed to block attempts to spam through our server from outside but I never considered the possibility that it&#8217;ll block legitimate mail as well. What I had to do was obviously set up some kind of authentication, and the way to do it is SASL. I use Dovecot on the server, so Dovecot SASL is what I&#8217;ll be using in this guide. If you followed <a href="http://nemrod.se/guides/guide-to-postfix-dovecot-mysql-mail-server">my guide to Postfix+Dovecot</a> your server should be compiled with support for it already.</p>
<p>First of all we need to enable it in Postfix. To do that simply add the following lines to your Postfix configuration (<em>main.cf</em>) some place appropriate:<br />
<em>broken_sasl_auth_clients = yes<br />
smtpd_sasl_type = dovecot<br />
smtpd_sasl_path = private/auth<br />
smtpd_sasl_auth_enable = yes</em></p>
<p>You will also want to add <em>permit_sasl_authenticated</em> somewhere in the &#8220;<em>smtpd_recipient_restrictions</em>&#8221; list.</p>
<p>Next up is Dovecot, so open up your <em>dovecot.conf</em>. You can start by adding &#8220;<em>login</em>&#8221; to the mechanisms row, so it&#8217;ll look like this:<br />
<em>mechanisms = plain login</em></p>
<p>After that change the client path row to:<br />
<em>path = /var/spool/postfix/private/auth</em><br />
I also changed both user and group to postfix instead of dovecot.</p>
<p>That should be all you need to do to enable SASL for your mail server, now all that&#8217;s left is to test it. Run the following four commands to completely stop and start the mail server:<br />
<em>postfix stop<br />
pkill -9 dovecot<br />
postfix start<br />
dovecot</em></p>
<p>To test the SASL authentication the first thing we have to do is to base64-encode our username and password so we can send it to the server. Normally the mail client does this, but since we&#8217;re telneting we have to do it ourselves. Run the following command in the terminal:<br />
<em>perl -MMIME::Base64 -e &#8216;print encode_base64(&#8220;\000user\@domain.tld\000password&#8221;)&#8217;</em><br />
<strong>AHVzZXJAZG9tYWluLnRsZABwYXNzd29yZA==</strong><br />
The string of random characters it returned is the base64-encoded version of &#8220;<em>\0user@domain.tld\0password</em>.&#8221;</p>
<p>Now let&#8217;s try authenticating ourselves when sending a mail through telnet!<br />
<em>telnet localhost 25</em><br />
<strong>Trying 127.0.0.1&#8230;<br />
Connected to localhost.<br />
Escape character is &#8216;^]&#8217;.<br />
220 server.domain.tld ESMTP Postfix</strong><br />
<em>AUTH PLAIN AHVzZXJAZG9tYWluLnRsZABwYXNzd29yZA==</em><br />
<strong>235 2.7.0 Authentication successful</strong><br />
From here on send a mail as usual, with &#8220;MAIL FROM&#8221;, &#8220;RCPT TO&#8221; and &#8220;DATA.&#8221;</p>
<p>That&#8217;s all there was to it &#8211; now you, like me and my company&#8217;s employees, should be able to send mail from outside the local network. ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/guides/sending-mail-from-outside-your-network/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nmailadm – web interface for mail server administration</title>
		<link>http://nemrod.se/projects/nmailadm/</link>
		<comments>http://nemrod.se/projects/nmailadm/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 22:50:26 +0000</pubDate>
		<dc:creator>nemrod</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://nemrod.se/site/?p=107</guid>
		<description><![CDATA[This is a mail administration interface that I made after I had set up my own Postfix+Dovecot+MySQL mail server. It&#8217;s a very rudimentary interface but it can add virtual domains, aliases and mailboxes &#8211; pretty much everything you need. That is, unless you&#8217;re interested in vacation responders and things like that. It was made to [...]]]></description>
			<content:encoded><![CDATA[<p>This is a mail administration interface that I made after I had set up my own Postfix+Dovecot+MySQL mail server. It&#8217;s a very rudimentary interface but it can add virtual domains, aliases and mailboxes &#8211; pretty much everything you need. That is, unless you&#8217;re interested in vacation responders and things like that.</p>
<p>It was made to work with my own mail database that I created, for specifications of that you can go to the guides section and read the mail server guide. It should be pretty easy for anyone familiar with PHP and MySQL to edit the source to work with a different database if you&#8217;ve got one and don&#8217;t want to change it.</p>
<p>It&#8217;s free as in free speech so you have no obligations regarding usage or modifications to it, but it&#8217;s always nice to hear from anyone using what you make so feel free to post a comment or send me a mail. Any bug fixes, improvements or other additions would be neat to get so I can host the new version here. :)</p>
<p><a class="button" href="http://nemrod.se/proj/nmailadm/nmailadm-0.1.tar.gz">nmailadm v0.1</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nemrod.se/projects/nmailadm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

