<?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>Sjeiti</title>
	<atom:link href="http://www.sjeiti.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sjeiti.com</link>
	<description></description>
	<lastBuildDate>Wed, 17 Apr 2013 11:44:48 +0000</lastBuildDate>
	<language>en-EN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4</generator>
		<item>
		<title>Bookmarklet for fullscreen Google Maps</title>
		<link>http://www.sjeiti.com/bookmarklet-for-fullscreen-google-maps/</link>
		<comments>http://www.sjeiti.com/bookmarklet-for-fullscreen-google-maps/#comments</comments>
		<pubDate>Sun, 07 Apr 2013 11:08:55 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1958</guid>
		<description><![CDATA[<p>Here's a bookmarklet that strips everything on Google Maps but the map itself. Put the  browser fullscreen and you've got the whole world to printscreen desktop images from. Siberia has some pretty awesome landscapes.</p><p>The post <a href="http://www.sjeiti.com/bookmarklet-for-fullscreen-google-maps/">Bookmarklet for fullscreen Google Maps</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>As a developer I use bookmarklets all the time. For those of you who don&#8217;t know: a bookmarklet is similar to a bookmark but instead of a hyperlink it points to: &#8220;javascript:console.log(&#8216;&#8230;do some Javacript to alter the page you&#8217;re currently viewing&#8217;);&#8221;.<br />
So when developing I tend to use it for lots of stuff: quick login into a secure part, automatically fill forms with random data, altering data I get from some site&#8230; I even used it to load and initialize the level editor for a game I recently built.</p>
<p>Here&#8217;s one I just made that strips everything on Google Maps but the map itself. Put the  browser fullscreen and you&#8217;ve got the whole world to printscreen desktop images from. Siberia has some pretty awesome landscapes.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/gm1.jpg" alt="gm1" /></p>
<p>I first tried it the easy way, by injecting jQuery and taking it from there. Worked fine on maps.google.nl but curiously maps.google.com wasn&#8217;t too keen on script injection (even threw a warning). So I rolled up my sleeves and rewrote it to pure js.</p>
<p><a href='javascript:(function(p){var q=function(i){return p.getElementById(i)},e=function(i){return p.getElementsByClassName(i)},s=function(i){i&#038;&#038;i.parentNode.removeChild(i)},c=function(i,z,l,u,v){var j=v.style,t=v.parentNode;j.left=i;j.top=z;j.width=l;j.height=u;if(t&#038;&#038;t.style){c(i,z,l,u,t)}},o=q("map"),a=q("panelarrow2"),r=e("mv-secondary mv-shown")[0],n="#panel,#views-control,#topbar-startcol,#controls.dragzoom.btn,#lmc3d,#scalecontrol,#map_overview,#copyright,#misc.distance_measurement.btn,#loadmessagehtml,#ds-v,#ds-h,.onegoogle,.mapfooter,.gmnoprint".split(",");a&#038;&#038;a.click();r&#038;&#038;r.click();for(var k=0,d=n.length;k<d;k++){var m=n[k],h=m.substr(0,1),b=m.substr(1),g;if(h=="#"){s(q(b))}else{g=e(b);for(var f=0,d=g.length;f<d;f++){s(g[f])}}}c(0,0,"100%","100%",o)})(document);'>Here it is.</a></p>
<p>Drag the above link to your bookmarks bar and head out to <a href="http://maps.google.com">Google Maps</a> to test it.</p>
<p>The post <a href="http://www.sjeiti.com/bookmarklet-for-fullscreen-google-maps/">Bookmarklet for fullscreen Google Maps</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/bookmarklet-for-fullscreen-google-maps/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Storing multiple properties in one integer using bitwise AND</title>
		<link>http://www.sjeiti.com/multiple-properties-in-one-variable/</link>
		<comments>http://www.sjeiti.com/multiple-properties-in-one-variable/#comments</comments>
		<pubDate>Tue, 22 Jan 2013 14:37:43 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[actionscript]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1826</guid>
		<description><![CDATA[<p>Objects with multiple properties with each their own variable can get a bit messy. Here&#8217;s a nice solution to store multiple properties in a single variable. Watch: var ability = { WALK:1 ,CRAWL:2 ,RUN:4 ,FLY:8 ,SWIM:16 }; function creature(name,abilities){ return { toString: function(){return '[object creature "'+name+'"]'} ,name: name ,can: function(ability){return !!(ability&#038;abilities)} }; } var humans [...]</p><p>The post <a href="http://www.sjeiti.com/multiple-properties-in-one-variable/">Storing multiple properties in one integer using bitwise AND</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Objects with multiple properties with each their own variable can get a bit messy. Here&#8217;s a nice solution to store multiple properties in a single variable.</p>
<p><span id="more-1826"></span> </p>
<p>Watch:<code data-language="javascript">
<pre>var ability = {
	WALK:1
	,CRAWL:2
	,RUN:4
	,FLY:8
	,SWIM:16
};

function creature(name,abilities){
	return {
		toString: function(){return '[object creature "'+name+'"]'}
		,name: name
		,can: function(ability){return !!(ability&#038;abilities)}
	};
}

var humans = creature('humans',ability.WALK|ability.RUN|ability.CRAWL|ability.SWIM);
var fishes = creature('fishes',ability.SWIM);
var turtles = creature('turtles',ability.SWIM|ability.CRAWL);
var pigs = creature('pigs',ability.WALK|ability.SWIM);

humans.can(ability.WALK); // returns true
fishes.can(ability.WALK); // returns false
turtles.can(ability.RUN); // returns false
pigs.can(ability.FLY); // returns false</pre>
<p></code></p>
<p>So the abilities itself are stored in a single private variable, but we can easily test any ability with the creature.can method. Nice huh?</p>
<h2>Spoiler alert</h2>
<p>But let me take some of the magic away by explaining what really happens.<br />
As you might have noticed the abilities are powers of two (1,2,4,8,16&#8230;). This corresponds to the binary equivalent of the decimal power of ten. The same sequence in binary is: 1,10,100,1000,10000.<br />
So adding any of the properties will always result in a unique number: ie the decimal 2 and 8 result in the binary 1010 (the properties are not really added but we&#8217;ll come to that).</p>
<h2>Bitwise AND</h2>
<p>The trick lies in the &#038; operator, or bitwise AND. <a href="http://en.wikipedia.org/wiki/Bitwise_operation">Bitwise operations</a> are extremely fast calculations because they are handled directly by the processor.<br />
Bitwise AND compares the binary equivalent of two numbers and returns a new number where the 1&#8242;s coincide. Like this:<br />
<code data-language="javascript" data-line="-1">
<pre style="font: 24px/30px Inconsolata,courier,monospace;">0101 &#038; // 5
0011 = // 3
0001   // 1</pre>
<p></code></p>
<p>In the example a pig is able walk and swim, so that&#8217;s 1|16=17, which is 10001 in binary. So to test if pigs can fly you&#8217;d do 17&#038;8, which is zero because:<br />
<code data-language="javascript" data-line="-1">
<pre style="font: 24px/30px Inconsolata,courier,monospace;">10001 &#038; // 17
01000 = // 8
00000   // 0</pre>
<p></code></p>
<h2>Bitwise OR</h2>
<p>You might also notice that the abilities are added by means of another bitwise operator: the bitwise OR, represented by the pipe sign: |. Bitwise OR is not the same as adding, but we are dealing with powers of two, so in this case it is. Bitwise OR really works like this:<br />
<code data-language="javascript" data-line="-1">
<pre style="font: 24px/30px Inconsolata,courier,monospace;">0101 &#038; // 5
0011 = // 3
0111   // 7</pre>
<p></code></p>
<h2>Impress your friends</h2>
<p>So that&#8217;s basically how it works. Fast. Practical in numerous cases (for storing a bunch of checkboxes in a database for instance). Very useful to keep your code clean and minimal (assuming you know how to read bitwise operators, but now you do). Plus looking at the variable &#8216;ability&#8217; alone immediately tells you a great deal about the rest of the code:</p>
<ul>
<li>capital properties tells you they are constant, so they don&#8217;t change</li>
<li>binary sequence tells you the properties are stored as a single variable</li>
<li>binary sequence also tells you an object can have multiple properties, but only one of each</li>
</ul>
<p>There is however a maximum to all this. Bitwise operations in Javascript are done on 32 bit numbers. But that should be more than enough for most.</p>
<p>The post <a href="http://www.sjeiti.com/multiple-properties-in-one-variable/">Storing multiple properties in one integer using bitwise AND</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/multiple-properties-in-one-variable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating tileable noise maps</title>
		<link>http://www.sjeiti.com/creating-tileable-noise-maps/</link>
		<comments>http://www.sjeiti.com/creating-tileable-noise-maps/#comments</comments>
		<pubDate>Wed, 26 Sep 2012 11:11:32 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[dimension]]></category>
		<category><![CDATA[pattern]]></category>
		<category><![CDATA[Perlin Noise]]></category>
		<category><![CDATA[simplex noise]]></category>
		<category><![CDATA[tile]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1775</guid>
		<description><![CDATA[<p>Creating a tileable image in Photoshop is easy; crop an image, take the cropped right and bottom and stick it left and top with a fade. But creating proper tileable noise maps is a bit trickier to get your head around if you want to do it right. If you have a basic understanding of [...]</p><p>The post <a href="http://www.sjeiti.com/creating-tileable-noise-maps/">Creating tileable noise maps</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Creating a tileable image in Photoshop is easy; crop an image, take the cropped right and bottom and stick it left and top with a fade. But creating proper tileable noise maps is a bit trickier to get your head around if you want to do it right.</p>
<p><span id="more-1775"></span></p>
<p>If you have a <a title="Hugo Elias on Perlin noise" href="http://freespace.virgin.net/hugo.elias/models/m_perlin.htm" target="_blank">basic understanding of Perlin noise</a> you&#8217;ll know that it consists of interpolated random numbers. People mostly use it in two dimensions. But it&#8217;s also useful in one dimension (movement for instance), in three dimensions (cylindrical and spherical mapping of 3D objects) and even four or five dimensions.<br />
You can use four dimensional noise to create a tileable 2D image. Thinking in four dimensions is not an everday practice so we&#8217;ll take it one dimension at a time.</p>
<p>In <a href="http://test.sjeiti.com/noiseTiling">the examples</a> I&#8217;ve used <a title="Simplex noise on Wikipedia" href="http://en.wikipedia.org/wiki/Simplex_noise" target="_blank">Simplex noise</a> with two octaves. Simplex noise is faster in higher dimensions and it looks better because of it&#8217;s triangular nature.<br />
I&#8217;ve written a small function called drawNoise to deal with canvas creation and pixel array looping. You can <a href="http://www.sjeiti.com/wp-content/uploads/noiseTiling.zip">download the examples here</a>.</p>
<h2>One dimensional tileable noise</h2>
<p>In one dimension the noise is an endless smooth line (my noise implementation starts at two so I&#8217;m using a constant for the second parameter). Here you can still really see it&#8217;s just interpolated random numbers.</p>
<pre><code data-language="javascript" data-line="128">// one dimensional line
fNoiseScale = .02;
drawNoise(function(i,x,y){
	var v = Simplex.noise(
		 123+x*fNoiseScale
		,137 // we just need one dimension so this parameter is a constant
	);
	return v*iSize>y?255:0;
}).img();</code></pre>
<p><img src="http://www.sjeiti.com/wp-content/uploads/line.jpg" alt="one dimensional noise" /></p>
<p>You can use this in your animation by recalculation the noise value for each millisecond but you could also create a loop and precalculate the values. The values in the image above do not loop. But looping is quite easy, all it takes is an extra dimension and a loop&#8230; or eeh circle.</p>
<h2>A one dimensional loop</h2>
<p>For most of you Perlin noise looks something like the following image.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/noise.jpg" alt="Simplex noise" /></p>
<p>If we were to draw a circle in there and read out the noise values on that circle we&#8217;d have a one dimensional loop.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/noiseCircle.jpg" alt="Noise with a circle to create a one dimensional loop" /></p>
<p>In code this looks like this:</p>
<pre><code data-language="javascript" data-line="162">// one dimensional loop
drawNoise(function(i,x,y){
	var fNX = x/iSize // we let the x-offset define the circle
		,fRdx = fNX*2*Math.PI // a full circle is two pi radians
		,a = fRdsSin*Math.sin(fRdx)
		,b = fRdsSin*Math.cos(fRdx)
		,v = Simplex.noise(
			 123+a*fNoiseScale
			,132+b*fNoiseScale
		)
	;
	return v*iSize>y?255:0;
}).img().div(2);</code></pre>
<div style="background:url(http://www.sjeiti.com/wp-content/uploads/lineLoop.jpg);height:128px;"></div>
<p><br/></p>
<p>You can probably already see where we are going with this. For looping a two dimensional image we&#8217;ll need a three dimensional noise map (at least).</p>
<h2>A cylindrical map</h2>
<p>Perlin noise was originally created for continuous 3D texturing (Tron). Instead of the image map being a piece of paper wrapped around an object the image map is calculated by the location in the three dimensional noise field. So when slicing the object you&#8217;d still be able to calculate the map for the newly created surface.</p>
<p>Before our ultimate goal of a tileable image we will first create one that just tiles left and right. It&#8217;s like the two dimensional circle for our one dimensional loop but with one extra dimension: a cylinder.</p>
<pre><code data-language="javascript" data-line="178">// three dimensional cylindrical map
drawNoise(function(i,x,y){
	var fNX = x/iSize
		,fRdx = fNX*2*Math.PI
		,a = fRdsSin*Math.sin(fRdx)
		,b = fRdsSin*Math.cos(fRdx)
		,v = Simplex.noise(
			 123+a*fNoiseScale
			,132+b*fNoiseScale
			,312+y*fNoiseScale // similar to the one dimensional loop but we add a third dimension defined by the image y-offset
		)
	;
	return v*255<<0;
}).img().div(2);</code></pre>
<p><img src="http://www.sjeiti.com/wp-content/uploads/noiseCylindrical.jpg" alt="a cylindrical noise map" /></p>
<h2>A spherical image map</h2>
<p>You might think a sphere would come in handy for our tileable image but you're wrong.<br />
As a small sidestep I'll show you how to calculate a spherical image map and what it looks like.</p>
<pre><code data-language="javascript" data-line="195">// three dimensional spherical map
document.body.addChild('h2').innerText = 'three dimensional spherical map';
fNoiseScale = .1;
var oSpherical = drawNoise(function(i,x,y){
	var  fNX = (x+.5)/iSize // added half a pixel to get the center of the pixel instead of the top-left
		,fNY = (y+.5)/iSize
		,fRdx = fNX*2*Math.PI
		,fRdy = fNY*Math.PI // the vertical offset of a 3D sphere spans only half a circle, so that is one Pi radians
		,fYSin = Math.sin(fRdy+Math.PI) // a 3D sphere can be seen as a bunch of cicles stacked onto each other, the radius of each of these is defined by the vertical position (again one Pi radians)
		,a = fRdsSin*Math.sin(fRdx)*fYSin
		,b = fRdsSin*Math.cos(fRdx)*fYSin
		,c = fRdsSin*Math.cos(fRdy)
		,v = Simplex.noise(
			 123+a*fNoiseScale
			,132+b*fNoiseScale
			,312+c*fNoiseScale
		)
	;
	return v*255<<0;
}).img();</code></pre>
<p><img src="http://www.sjeiti.com/wp-content/uploads/noiseSpherical.jpg" alt="a spherical noise map" /><img src="http://www.sjeiti.com/wp-content/uploads/sphere.jpg" alt="a sphere with noise" /></p>
<h2>Cubical panorama map</h2>
<p>The sphere we just made can also be used as a panorama if we'd put the camera in the center of the sphere. But a better technique is a cubical panorama because it has far less faces. The sphere is mapped onto the six sides of a cube as indicated by this sketch.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/sketchCube.jpg" alt="sketch mapping sphere to cube" /></p>
<p>For each pixel on the face of the cube we have to calculate the intersection between our viewpoint C in the center and the sphere. This might sound difficult but really isn't.</p>
<p>We can perceive the line CA as a vector. And vectors can be normalized, so it's direction doesn't change but it's length is reduced to 1. Which makes all our vectors together look like a sphere.</p>
<p>Normalization is also quite simple, we just have to divide the xyz values of the vector with the total length of the vector. The length of the vector can be calculated using the theorem or Pythagoras.</p>
<p>In the code below you can see the normalize calculation is first done for a single face. Then the noise is calculated for al six faces simultaneously since its just a matter of swapping xyz values to get the position on another face.</p>
<pre><code data-language="javascript" data-line="238">// 3D panoramical cube map
document.body.addChild('h2').innerText = '3D panoramical cube map';
// we're not using the drawNoise function because our canvas is rectangular
var mCubemap = document.createElement('canvas')
	,iW = 6*iSize;
mCubemap.width = iW;
mCubemap.height = iSize;
var  iHSize = iSize/2 // half the size of the cube
	,oCtx = mCubemap.getContext('2d')
	,oImgData = oCtx.getImageData(0,0,iW,iSize)
	,aPixels = oImgData.data
	,aa = 123
	,bb = 231
	,cc = 321
;
for (var i=0,l=iSize*iSize;i&lt;l;i++) {
	var  x = i%iSize		// x position in image
		,y = (i/iSize)&lt;&lt;0	// y position in image
		,a = -iHSize + x+.5	// x position on the cube plane, the added .5 is to get the center of the pixel
		,b = -iHSize + y+.5 // y position on the cube plane
		,c = -iHSize		// z position of the cube plane
		,fDistanceAB = Math.sqrt(a*a+b*b) // to calculate the vectors length we use Pythagoras twice
		,fDistanceABC = Math.sqrt(fDistanceAB*fDistanceAB+c*c)
		,fDrds = .5*fDistanceABC // adjust the distance a bit to get a better radius in the noise field
		,v = 1
	;
	a /= fDrds; // normalize the vector
	b /= fDrds; // normalize the vector
	c /= fDrds; // normalize the vector
	//
	// since we now know the spherical position for one plane we can derive the positions for the other five planes simply by switching the x, y and z values (the a, b and c variables)
	var aNoisePositions = [
		 [a,b,c]	// back
		,[-c,b,a]	// right
		,[-a,b,-c]	// front
		,[c,b,-a]	// left
		,[a,c,-b]	// top
		,[a,-c,b]	// bottom
	];
	for (var j=0;j&lt;6;j++) {
		v = Simplex.noise(
			 aa + aNoisePositions[j] [0]
			,bb + aNoisePositions[j] [1]
			,cc + aNoisePositions[j] [2]
		);
		var pos = 4*(y*iW+j*iSize+x); // the final position of the rgba pixel
		aPixels[pos] = aPixels[pos+1] = aPixels[pos+2] = v*255&lt;&lt;0;
		aPixels[pos+3] = 255;
	}
}
oCtx.putImageData(oImgData,0,0);
document.body.addChild('img',{src:mCubemap.toDataURL("image/jpeg")});</code></pre>
<p>Here are the six sides stuck into a single image plus a screenshot of what it looks like from within the cube. The source code also has an actual 3D example done with <a title="mr Doob's threejs on Github" href="https://github.com/mrdoob/three.js/" target="_blank">threejs</a>.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/noiseCubeMap.jpg" alt="cubical panorama map" /><br/><br />
<img src="http://www.sjeiti.com/wp-content/uploads/noiseCubeMap3D1.jpg" alt="noiseCubeMap3D" /></p>
<h2>A 2D tileable image</h2>
<p>A 2D tileable image might seem easy but I find it the most difficult of the ones I described here because understanding it requires you to think in four dimensions. The closest we really got was the cylindrical map (with it's horizontal repeat), so we'll take that as our starting point.<br />
In the cylindrical map we used the image horizontal position for the circle; so the horizontal image position provided us with two coordinates x and y in the noise xyz field. The image's vertical position corresponded to z in the noise field.</p>
<p>We also want the image to tile vertically so if we add an extra dimension we can use it to create a second circle to replace the fields linear z value. It's almost like creating two cylinders in a four dimensional field. I tried to vizualize it a bit in the following sketch, it's not accurate but I'm trying to convey the general idea, not draw a four dimensional cylinder.</p>
<p><img src="http://www.sjeiti.com/wp-content/uploads/sketchCylinders.jpg" alt="sketch of two cylinders in four dimensions" /></p>
<p>The code pretty straightforward; just two circles in four dimensional noise space.</p>
<pre><code data-language="javascript" data-line="343">// four dimensional tile
fNoiseScale = .003;
drawNoise(function(i,x,y){
	var  fNX = x/iSize
		,fNY = y/iSize
		,fRdx = fNX*2*Math.PI
		,fRdy = fNY*2*Math.PI
		,a = fRds*Math.sin(fRdx)
		,b = fRds*Math.cos(fRdx)
		,c = fRds*Math.sin(fRdy)
		,d = fRds*Math.cos(fRdy)
		,v = Simplex.noise(
			 123+a*fNoiseScale
			,231+b*fNoiseScale
			,312+c*fNoiseScale
			,273+d*fNoiseScale
		)
	;
	return (Math.min(Math.max(2*(v -.5)+.5,0),1)*255)<<0;
}).img().div(2,2);</code></pre>
<p>And here's the result:</p>
<div style="background:url(http://www.sjeiti.com/wp-content/uploads/noiseTileable.jpg);height:400px;"></div>
<p>The post <a href="http://www.sjeiti.com/creating-tileable-noise-maps/">Creating tileable noise maps</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/creating-tileable-noise-maps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating a subversion repository from Google Code to Github</title>
		<link>http://www.sjeiti.com/migrating-a-subversion-repository-from-google-code-to-github/</link>
		<comments>http://www.sjeiti.com/migrating-a-subversion-repository-from-google-code-to-github/#comments</comments>
		<pubDate>Fri, 24 Aug 2012 11:16:27 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Google Code]]></category>
		<category><![CDATA[migrating]]></category>
		<category><![CDATA[migration]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[SVN]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1722</guid>
		<description><![CDATA[<p>Recently I migrated TinySort from Google Code to Github. I&#8217;m a real Git noob so I expected a full history migration to be a real pain in the ass. Plus I also wanted to move both the open and closed issues (since they correspond to the regression tests). Luckily it turned out to be a [...]</p><p>The post <a href="http://www.sjeiti.com/migrating-a-subversion-repository-from-google-code-to-github/">Migrating a subversion repository from Google Code to Github</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Recently I migrated <a href="https://github.com/Sjeiti/TinySort" title="TinySort" target="_blank">TinySort</a> from Google Code to Github. I&#8217;m a real Git noob so I expected a full history migration to be a real pain in the ass. Plus I also wanted to move both the open and closed issues (since they correspond to the regression tests). Luckily it turned out to be a lot easier than I anticipated.</p>
<p><span id="more-1722"></span></p>
<p>Unlike <a href="https://help.github.com/articles/importing-from-subversion" title="Github: Importing from Subversion" target="_blank">what Github says you should do to migrate</a> I started at Google Code itself. Google Code also supports Git and <a href="http://code.google.com/p/support/wiki/ConvertingSvnToGit" title="Google Code: Convert your project from Subversion to Git" target="_blank">they have excellent instructions</a> to convert your existing Subversion repository into a Git repository.</p>
<p><small>Since my project didn&#8217;t have any tags the Google Code instructions sufficed. If your project does have tags and you want to convert them properly you might be better off following Githubs suggestion to use the <a href="https://github.com/nirvdrum/svn2git" target="_blank">svn2git tool</a> (there&#8217;s also the <a href="https://github.com/JohnAlbin/git-svn-migrate" target="_blank">git-svn-migrate tool</a>, I have no idea which is better). My main reason for not using svn2git was that it requires Ruby. And although I think I have that installed I didn&#8217;t want to overcomplicate things because I already didn&#8217;t know what I was doing learing Git and all.</small></p>
<p>Once you&#8217;ve followed the instructions you should have a checkout of your project on your local machine. Now all that is left is to move it to Github.</p>
<p>I&#8217;m mainly using Git Bash here but I also have Tortoise Git installed and Githubs own Windows client (although the latter sucks a bit).</p>
<p>Presuming you have a Github account and created an empty project to push the lot into; you first have to add the Github remote to the project (Unlike Subversion a Git project can have multiple locations called &#8216;remotes&#8217;):</p>
<pre><code data-language="git">$ git remote add origin git@github.com:GITHUB_USERNAME/REPO_NAME.git</code></pre>
<p>You can check yourself we now have two remotes: googlecode (you added earlier) and origin.</p>
<pre><code data-language="git">$ git remote
googlecode
origin</code></pre>
<p>Before we can push to Github (origin) we must do a pull. And since origin is not our default remote (googlecode is) we must also specify which branch to pull from (the master branch).</p>
<pre><code data-language="git">$ git pull origin master</code></pre>
<p>Since your repo is now up-to-date you can push:</p>
<pre><code data-language="git">$ git push --all origin</code></pre>
<p>&#8230;and that&#8217;s it!</p>
<p>Now for the issues, this proved somewhat more laborious. <a href="https://github.com/alexrudnick/migrate-googlecode-issues" title="migrate Google Code issues" target="_blank">This piece of Python code</a> does the trick. I speak as much Python as I speak Japanese so I hardly bothered checking the code. I only added my login data, altered it to move everything instead of only the open issues and commented out ln 13 &#8216;from __future__ import print_function&#8217; since that line prevented it from running.</p>
<p>This worked with only two minor mishaps: all thirty or so closed issues I had were now open on Github and all issues on Google Code were now tagged &#8216;migrated&#8217; and open. For the latter I just added the migrated tag to the closed issues list on Google Code. On Github I just closed the issues by hand.<br />
So next time I&#8217;ll try to alter the script a bit to actually close the closed issues (also some good Python practice for me).</p>
<p>The post <a href="http://www.sjeiti.com/migrating-a-subversion-repository-from-google-code-to-github/">Migrating a subversion repository from Google Code to Github</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/migrating-a-subversion-repository-from-google-code-to-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Logo</title>
		<link>http://www.sjeiti.com/logo/</link>
		<comments>http://www.sjeiti.com/logo/#comments</comments>
		<pubDate>Fri, 06 Jul 2012 17:45:45 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[graphic design]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1652</guid>
		<description><![CDATA[<p>I really just wanted to update my WordPress core. But I got a little overexcited and redesigned my site. One thing let to another and I decided to redesign my logo. Then I thought: you know what would be freaking cool, a logo made of one HTML element and pure CSS. Which worked out just [...]</p><p>The post <a href="http://www.sjeiti.com/logo/">Logo</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>I really just wanted to update my WordPress core.</p>
<p><span id="more-1652"></span></p>
<p>But I got a little overexcited and redesigned my site. One thing let to another and I decided to redesign my logo. Then I thought: you know what would be freaking cool, a logo made of one HTML element and pure CSS.</p>
<p>Which worked out just fine if I may say so myself:</p>
<pre><code data-language="css" data-line="-1">#logo {
	width: 67px;
	height: 108px;
}
#logo:before, #logo:after {
	content: '';
	position: relative;
	top: 14px;
	left: 4px;
	display: block;
	width:56px;
	height:28px;
	background-color: #000;
	border-radius: 0 28px 0 28px;
	transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
}
#logo:after {
	top: 29px;
	left: -6px;
	width:80px;
	height:32px;
	transform:rotate(46deg) skewx(-9deg) skewy(-9deg);
}</code></pre>
<div id="logo">
<style>#logo {
	width: 67px;
	height: 108px;
	margin: 10px auto;
	zoom: 3;
}
#logo:before, #logo:after {
	content: '';
	position: relative;
	top: 14px;
	left: 4px;
	display: block;
	width:56px;
	height:28px;
	background-color: #000;
	border-radius: 0 28px 0 28px;
	-moz-transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
	-webkit-transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
	-o-transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
	-ms-transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
	transform: rotate(40deg) skewx(-3deg) skewy(-3deg);
}
#logo:after {
	top: 29px;
	left: -6px;
	width:80px;
	height:32px;
	-moz-transform: rotate(46deg) skewx(-9deg) skewy(-9deg);
	-webkit-transform: rotate(46deg) skewx(-9deg) skewy(-9deg);
	-o-transform: rotate(46deg) skewx(-9deg) skewy(-9deg);
	-ms-transform: rotate(46deg) skewx(-9deg) skewy(-9deg);
	transform: rotate(46deg) skewx(-9deg) skewy(-9deg);
}</style>
</div>
<p>Now the only problem is: how the hell do I turn this into vector?</p>
<p>The post <a href="http://www.sjeiti.com/logo/">Logo</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/logo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tinysort: a tiny survey</title>
		<link>http://www.sjeiti.com/tinysort-a-tiny-survey/</link>
		<comments>http://www.sjeiti.com/tinysort-a-tiny-survey/#comments</comments>
		<pubDate>Tue, 03 Jul 2012 07:46:41 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[SVN]]></category>
		<category><![CDATA[tinysort]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=1030</guid>
		<description><![CDATA[<p>Help me decide whether to move Tinysort to Github... or not...</p><p>The post <a href="http://www.sjeiti.com/tinysort-a-tiny-survey/">Tinysort: a tiny survey</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>For versioning I&#8217;ve always used <a href="http://subversion.tigris.org/">SVN</a>. I put opensource stuff on Google code and have <a href="http://xp-dev.com/">XP-dev</a> for private projects. Naturally I&#8217;ve also used <a href="http://git-scm.com/">Git</a> sometimes, a lot of open source projects are on <a href="https://github.com/">Github</a> and when you work freelance your bound to walk into a Git project sooner or later.</p>
<p><span id="more-1030"></span><br />
A while ago I got <a href="https://code.google.com/p/tinysort/issues/detail?id=28&amp;can=1">a ticket</a> on <a href="http://tinysort.sjeiti.com/">Tinysort</a> asking if I was planning to migrate to Github. I said not anytime soon but that was a while ago.<br />
And now I&#8217;m still not sure whether I should make the switch because I still suck at Git (stupid confusing terminologies between SVN and Git). But then again, I&#8217;ll keep sucking at it if I don&#8217;t use it.</p>
<p><del datetime="2012-08-24T07:05:36+00:00">So here&#8217;s a Google Doc survey:</del></p>
<p>Well, with about a hundred entries the result of the tiny survey should be clear, <a href="https://github.com/Sjeiti/TinySort" title="TinySort on Github" target="_blank">Github it is</a>.</p>
<p><img src="https://docs.google.com/spreadsheet/oimg?key=0AgLsBMvUgAW8dEZHY0hFTXJ6Q1ZFUzZVcVpmM0t4V3c&#038;oid=3&#038;zx=sriyr9l0vt49" /></p>
<p><!--iframe src="https://docs.google.com/spreadsheet/embeddedform?formkey=dEZHY0hFTXJ6Q1ZFUzZVcVpmM0t4V3c6MQ" width="100%" height="480px" frameborder="0" marginheight="0" marginwidth="0">Bezig met laden&#8230;</iframe--></p>
<p>The post <a href="http://www.sjeiti.com/tinysort-a-tiny-survey/">Tinysort: a tiny survey</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/tinysort-a-tiny-survey/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android phone DOM</title>
		<link>http://www.sjeiti.com/android-phone-dom/</link>
		<comments>http://www.sjeiti.com/android-phone-dom/#comments</comments>
		<pubDate>Sat, 30 Jun 2012 11:30:27 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=975</guid>
		<description><![CDATA[<p>Cleaning up my phone the other day I found some cool stuff. Two years ago I coded some stuff while I was on vacation. This was also on it&#8230; Anyway, here&#8217;s a little thing I wrote on a phone to see what the DOM on that phone browser really looked like. http://test.sjeiti.com/DOM/ Types are neatly [...]</p><p>The post <a href="http://www.sjeiti.com/android-phone-dom/">Android phone DOM</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Cleaning up my phone the other day I found some cool stuff. Two years ago I coded <a href="http://www.sjeiti.com/?p=604">some stuff</a> while I was on vacation. This was also on it&#8230;</p>
<p><span id="more-975"></span></p>
<p>Anyway, here&#8217;s a little thing I wrote on a phone to see what the DOM on that phone browser really looked like.</p>
<p><a href="http://test.sjeiti.com/DOM/">http://test.sjeiti.com/DOM/</a></p>
<p>Types are neatly color coded, objects and functions can fold, and booleans toggled.</p>
<p>Vacation or not, I just can&#8217;t go that long without coding anything.</p>
<p>The post <a href="http://www.sjeiti.com/android-phone-dom/">Android phone DOM</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/android-phone-dom/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LESS variables to Javascript</title>
		<link>http://www.sjeiti.com/less-variables-to-javascript/</link>
		<comments>http://www.sjeiti.com/less-variables-to-javascript/#comments</comments>
		<pubDate>Mon, 18 Jun 2012 15:01:18 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[director]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=977</guid>
		<description><![CDATA[<p>LESS CSS is great and all but what if you want to use the same LESS variables in Javascript. Here&#8217;s an easy solution I used for a site I recently made. In LESS create class rules within a non-existing id. Then read them by traversing the document.styleSheets. Here&#8217;s a Github gist and here&#8217;s a fiddle. [...]</p><p>The post <a href="http://www.sjeiti.com/less-variables-to-javascript/">LESS variables to Javascript</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>LESS CSS is great and all but what if you want to use the same LESS variables in Javascript.</p>
<p><span id="more-977"></span></p>
<p>Here&#8217;s an easy solution I used for a site I recently made.<br />
In LESS create class rules within a non-existing id. Then read them by traversing the document.styleSheets.</p>
<p>Here&#8217;s a <a href="https://gist.github.com/2948738">Github gist</a> and here&#8217;s a <a href="http://jsfiddle.net/Sjeiti/VHQ8x/">fiddle</a>.</p>
<p>So in my LESS file I have the following:
<pre><code data-language="css">@thumbsWidth: 654px;
@thumbsTop: 123px;
#less {
	.thumbsWidth { width: @thumbsWidth; }
	.thumbsTop { width: @thumbsTop; }
}</code></pre>
<p>Then call the function: <code data-language="javascript">getLessVars('less');</code></p>
<p>Which returns the following object with the LESS variables:
<pre><code data-language="javascript">{
	thumbsWidth: 123,
	thumbsTop: 456
}</code></pre>
<p>easy</p>
<p>The post <a href="http://www.sjeiti.com/less-variables-to-javascript/">LESS variables to Javascript</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/less-variables-to-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interactive fluid dynamics in Javascript</title>
		<link>http://www.sjeiti.com/interactive-fluid-dynamics-in-javascript/</link>
		<comments>http://www.sjeiti.com/interactive-fluid-dynamics-in-javascript/#comments</comments>
		<pubDate>Fri, 25 May 2012 11:47:34 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nature]]></category>
		<category><![CDATA[fluid dynamics]]></category>
		<category><![CDATA[port]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=934</guid>
		<description><![CDATA[<p>Don&#8217;t know why, but after seeing Oliver Hunt&#8217;s fluid solver I wanted to use fluid dynamics on my site as an interactive particle flowfield. As you might suspect fluid dynamics is really complex stuff. In computational programming it is mimicked by using Navier-Stokes equations. Olivers fluid solver is based on a 2003 paper by Jos [...]</p><p>The post <a href="http://www.sjeiti.com/interactive-fluid-dynamics-in-javascript/">Interactive fluid dynamics in Javascript</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>Don&#8217;t know why, but after seeing <a href="http://nerget.com/fluidSim/">Oliver Hunt&#8217;s</a> fluid solver I wanted to use fluid dynamics on my site as an interactive particle flowfield.</p>
<p><span id="more-934"></span></p>
<p>As you might suspect fluid dynamics is really complex stuff. In computational programming it is mimicked by using <a href="http://en.m.wikipedia.org/wiki/Navier%E2%80%93Stokes_equations">Navier-Stokes equations</a>. Olivers fluid solver is based on a 2003 paper by <a href="http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/GDC03.pdf">Jos Stam</a> describing a fast implementation for realtime use.</p>
<p>The first thing I did is grab his script and implement it roughly. Only it worked wrongly for non square images. So I looked around some more for other implementations of fluid dynamics and found one in Actionscript by <a href="http://blog.inspirit.ru/?p=248">Eugene Zatepyakin</a>. Since Actionscript is my second language and Eugene is an excellent programmer I decided I&#8217;d port his code to Javascript (+Eugenes version had viscosity implemented).</p>
<p>When I got the port up and running it ran faster than Olivers script but it had the same vertical vs horizontal discrepancy. Luckily, while optimizing, I found out why and fixed it.</p>
<p>Porting stuff from C++ to Java to Actionscript to Javascript does not go by unpunished. The Webkit browers will run it quite nicely but Firefox really sucks at it (even moreso than IE).</p>
<p>Here it is:</p>
<p><iframe src="http://test.sjeiti.com/fluidSolver" width="100%" height="200px"></iframe></p>
<p>In the above implementation I&#8217;ve used the raw fluid in a canvas, and the red dots are tiny 1px divs above it. You can also watch it fullscreen from <a href="http://test.sjeiti.com/fluidSolver">http://test.sjeiti.com/fluidSolver</a> or <a href="http://test.sjeiti.com/fluidSolver/fluidSolver.zip">download the source</a>.</p>
<p>With it I&#8217;ve made a minimal dusty look on <a href="http://ronvalstar.nl/">ronvalstar.nl</a> (only Webkit since Firefox and IE aren&#8217;t fast enough). It uses only the velocity field for the dust particles. It starts with a low number of particles that is in- or decremented depending on the framerate. The dust particles are influenced by mouse movement, but also by interacting with the menu and/or projects.</p>
<p>The post <a href="http://www.sjeiti.com/interactive-fluid-dynamics-in-javascript/">Interactive fluid dynamics in Javascript</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/interactive-fluid-dynamics-in-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using WordPress media library in a plugin</title>
		<link>http://www.sjeiti.com/using-wordpress-media-library-in-a-plugin/</link>
		<comments>http://www.sjeiti.com/using-wordpress-media-library-in-a-plugin/#comments</comments>
		<pubDate>Tue, 01 May 2012 21:42:37 +0000</pubDate>
		<dc:creator>Sjeiti</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[media]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[thickbox]]></category>
		<category><![CDATA[undocumented]]></category>

		<guid isPermaLink="false">http://www.sjeiti.com/?p=938</guid>
		<description><![CDATA[<p>I just spent a couple of hours trying to figure this one out. Here&#8217;s how to use the WordPress media library in a plugin or custom post type&#8230; the right way. It took me a while to to get this right. So much for Google because everybody with a similar problem posted the same solution, [...]</p><p>The post <a href="http://www.sjeiti.com/using-wordpress-media-library-in-a-plugin/">Using WordPress media library in a plugin</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></description>
			<content:encoded><![CDATA[<p>I just spent a couple of hours trying to figure this one out. Here&#8217;s how to use the WordPress media library in a plugin or custom post type&#8230; the right way.</p>
<p><span id="more-938"></span></p>
<p>It took me a while to to get this right. So much for Google because everybody with a similar problem posted the same solution, mostly with the same cumbersome code (why bother writing a new post if you&#8217;re just gonna copy-paste the code from someone elses blog).</p>
<p><del data-reason="let's not be all negative about this; we all love WordPress :-)">But before I proceed: carefull not to turn this post into a rant I&#8217;ll say it now just to get it over with: &#8220;Wow, what a bunch of poorly documented, badly written spaghetti code WordPress is&#8221;. That&#8217;s it.</del></p>
<p>If you look a bit closer to the admin source you&#8217;ll find a Javascript click-implementation for all &#8216;a.thickbox&#8217; (media-upload.dev.js ln 65-71).<br />
A bit further you&#8217;ll see that the upload uri for that &#8216;a.thickbox&#8217; can be retreived with the PHP function &#8216;get_upload_iframe_src($type)&#8217;. Now it doesn&#8217;t say anywhere what that $type is supposed to be but digging through the code (media.php) and doing some trial and error it seems a string of the possible values: image, video, audio, file or media (where the latter is any of the previous but file). If you want extra types checkout <a href="http://codex.wordpress.org/Function_Reference/add_filter" class="broken_link">add_filter</a> with &#8216;<a href="http://codex.wordpress.org/Plugin_API/Filter_Reference/upload_mimes" class="broken_link">upload_mimes</a>&#8216;.</p>
<p>All we need now is to add a javascript callback function.<br />
The javascript callback function is a global. This is bloody ridiculous but not surprising if you&#8217;ve ever inspected window or $_GLOBAL in WordPress.<br />
The callback function returns a different HTML string depending on the type of file you&#8217;ve selected (type image has an image tag inserted).<br />
What all these identical solutions on Google do wrong is that they set this global javascript callback function (and add placeholders) the moment you enter the page. It is neater to set it the moment you press the &#8216;a.thickbox&#8217; button, this way you can adjust your callback when you have multiple uploads (ie an image and a pdf).</p>
<p>Once you&#8217;ve added the thickbox and setup the javascript callback you should be able to use the WordPress media library.</p>
<p>But what if you do not want that HTML that is returned but, say, a post_id (more experienced WordPress users will know that posts, pages, attachements, images and everything are all stored in the table [wp]_posts). With the post_id (or attachement_id) you&#8217;d be able to use more than just an image- or attachement uri, you can also use the title and/or description of a file.</p>
<p>As said, the callback function returns a different types of HTML. The image HTML snippet contains the attachement_id but the others don&#8217;t. When you trace back where the callback function is invoked you&#8217;ll find an <a href="http://codex.wordpress.org/Function_Reference/add_filter" class="broken_link">add_filter hook</a> called &#8216;media_send_to_editor&#8217;. It&#8217;s nowhere to be found on <a href="http://codex.wordpress.org/" class="broken_link">codex.wordpress.org</a> but it&#8217;s easy enough to implement. The call itself is done in media.php ln 488 (apply_filters(&#8216;media_send_to_editor&#8217;, $html, $send_id, $attachment)). And if you look through the surrounding function you&#8217;ll see the $send_id is exactly what we need. Not only that; the $attachement parameter is an associative array filled with other usefull stuff (title,description etc&#8230;).<br />
We overwrite the $html parameter (the filter callback expects $html returned) and set the priority of the filter to something really high so we know for sure it&#8217;s the last function applied&#8230; and we&#8217;re there&#8230;<br />
&#8230;or are we?<br />
Hooking up to &#8216;media_send_to_editor&#8217; will also cause whatever you do in that function to happen in the normal text editor (after all: that&#8217;s what we&#8217;re hacking into).<br />
So we need to try to determine were we come from. There is the $_POST['_wp_http_referer'] but if you examine it you&#8217;ll see that it does not contain the $GET vars we added to the upload button href. It took me a while to notice: if you check the upload iframe uri you&#8217;ll see that somebody did a very sloppy job off chopping of the last $GET variables after &#8216;TB_iframe&#8217; (WTF WordPress, seriously?!). So don&#8217;t append or use add_query_arg but insert your extra variables.</p>
<p>So since we now know  where we come from we can use this in our hook function. We don&#8217;t even have to parse an HTML string. We just want some data so we&#8217;re going to parse JSON.</p>
<p>Here is an example custom post type: <a href="http://www.sjeiti.com/wp-content/uploads/download/foobarbaz.zip">foobarbaz.zip</a> (simply add it to your theme dir and include the php file in your functions.php).</p>
<p>There are two important lines in the PHP (the rest is mainly for building a custom post type):</p>
<pre><code data-language="php" data-line="67">$sUri = esc_url( str_replace('&amp;type=','&amp;target=foobarbaz&amp;input='.$sInputName.'&amp;preview='.$sPreview.'&amp;tab=library&amp;type=',get_upload_iframe_src($sSubType)) );</code></pre>
<p>This is the code for creating the uri used in the upload button. Notice the insertion of the $GET vars.<br />
And there is the entire mediaSendToEditor function on line 81.<br />
<label class="code">file: posttype-foobarbaz.php</label></p>
<pre><code data-language="php" data-line="81">function mediaSendToEditor($html, $attachment_id, $attachment) {
	// check for the GET vars added in boxView
	parse_str($_POST['_wp_http_referer'], $aPostVars);
	if (isset($aPostVars['target'])&#038;&#038;$aPostVars['target']=='foobarbaz') {
		// add extra data to the $attachement array prior to returning the json_encoded string
		$attachment['id'] = $attachment_id;
		$attachment['edit'] = get_edit_post_link($attachment_id);
		$attachment['input'] = $aPostVars['input'];
		$attachment['preview'] = $aPostVars['preview'];
		if ($aPostVars['type']=='image') {
			foreach (array('thumb','medium','large') as $size) {
				$aImg = wp_get_attachment_image_src( $attachment_id, $size);
				if ($aImg) $attachment['img_'.$size] = $aImg[0];
			}
		}
		$html = json_encode($attachment);
	}
	return $html;
}</code></pre>
<p>There&#8217;s also a tiny caveat conserning the &#8216;Insert into post&#8217; button in the upload iframe. If you create a custom post type that does not support &#8216;editor&#8217; you&#8217;ll have to add this button yourself.</p>
<p>Here&#8217;s the js responsible for the callback:<br />
<label class="code">file: scripts/foobarbaz.js</label></p>
<pre><code data-language="javascript">(function($){
	var fnOldSendToEditor;
	$(function(){
		// store original send_to_editor function
		fnOldSendToEditor = window.send_to_editor;
		// add a different send_to_editor function to each thickbox anchor
		var $Box = $('#foobarbaz-box');
		if ($Box.length) {
			$Box.find('a.thickbox').each(function(i,el){
				var $A = $(el).click(function(){
					window.send_to_editor = getFnSendToEditor($A.data('type'));
				});
			});
		}
		// hack tb_remove to reset window.send_to_editor
		var fnTmp = window.tb_remove;
		window.tb_remove = function(){
			if (fnOldSendToEditor) window.send_to_editor = fnOldSendToEditor;
			fnTmp();
		};
	});
	function getFnSendToEditor(type){
		return function(fileHTML){
			var oData = JSON.parse(fileHTML);
			//console.log(oData);
			$('#'+oData.input).val(oData.url);
			$('#'+oData.preview).text(type+': '+oData.url.split('/').pop());
			tb_remove();
		}
	}
})(jQuery);</code></pre>
<p>First the original send_to_editor function is stored. Then each a.thickbox is assigned an onclick to replace the send_to_editor. This function creates and returns an anonymous function in order to parse the &#8216;type&#8217; parameter through it&#8217;s scope (not manditory but a nice alternative to the insertion of the $GET vars).<br />
Then we hack into tb_remove to restore the original send_to_editor function (since we also want this to happen when you simply close the upload iframe).<br />
You&#8217;ll also notice that the original global &#8216;send-to-editor&#8217; function is stored and restored on callback so as to maintain it&#8217;s original texteditor functionality. And that&#8217;s it.</p>
<p>So there you have it&#8230;</p>
<p>(once again: <a href="http://www.sjeiti.com/wp-content/uploads/download/foobarbaz.zip">foobarbaz.zip</a>)</p>
<p>The post <a href="http://www.sjeiti.com/using-wordpress-media-library-in-a-plugin/">Using WordPress media library in a plugin</a> appeared first on <a href="http://www.sjeiti.com">Sjeiti</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.sjeiti.com/using-wordpress-media-library-in-a-plugin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
