cache_dir != '') { $cache_file = $this->cache_dir.'/rsscache_'.md5($rss_url); $timedif = @ (time() - filemtime($cache_file)); if ($timedif < $this->cache_time) { // cached file is fresh enough, return cached array $result = unserialize(join('', file($cache_file))); // set 'cached' to 1 only if cached file is correct if ($result) $result['cached'] = 1; } else { // cached file is too old, create new $result = $this->Parse($rss_url); $serialized = serialize($result); if ($f = @ fopen($cache_file, 'w')) { fwrite($f, $serialized, strlen($serialized)); fclose($f); } if ($result) $result['cached'] = 0; } } // If CACHE DISABLED >> load and parse the file directly else { $result = $this->Parse($rss_url); if ($result) $result['cached'] = 0; } // return result return $result; } // ------------------------------------------------------------------- // Modification of preg_match(); return trimed field with index 1 // from 'classic' preg_match() array output // ------------------------------------------------------------------- function my_preg_match($pattern, $subject) { // start regullar expression preg_match($pattern, $subject, $out); // if there is some result... process it and return it if (isset ($out[1])) { // Process CDATA (if present) if ($this->CDATA == 'content') { // Get CDATA content (without CDATA tag) $out[1] = strtr($out[1], array (' '', ']]>' => '')); } elseif ($this->CDATA == 'strip') { // Strip CDATA $out[1] = strtr($out[1], array (' '', ']]>' => '')); } // If code page is set convert character encoding to required if ($this->cp != '') //$out[1] = $this->MyConvertEncoding($this->rsscp, $this->cp, $out[1]); $out[1] = iconv($this->rsscp, $this->cp.'//TRANSLIT', $out[1]); // Return result return trim($out[1]); } else { // if there is NO result, return empty string return ''; } } // ------------------------------------------------------------------- // Replace HTML entities &something; by real characters // ------------------------------------------------------------------- function unhtmlentities($string) { // Get HTML entities table $trans_tbl = get_html_translation_table(HTML_ENTITIES, ENT_QUOTES); // Flip keys<==>values $trans_tbl = array_flip($trans_tbl); // Add support for ' entity (missing in HTML_ENTITIES) $trans_tbl += array (''' => "'"); // Replace entities by values return strtr($string, $trans_tbl); } // ------------------------------------------------------------------- // Parse() is private method used by Get() to load and parse RSS file. // Don't use Parse() in your scripts - use Get($rss_file) instead. // ------------------------------------------------------------------- function Parse($rss_url) { // Open and load RSS file $urlParts = parse_url($rss_url); $host = $urlParts['host']; $uri = $urlParts['path']; if (strcmp($urlParts['query'], '') != 0) { $uri .= '?'.$urlParts['query']; } if (strcmp($urlParts['fragment'], '') != 0) { $fragment = $urlParts['fragment']; $fragment = substr($fragment, 4, strlen($fragment) - 3); $uri = $uri.$fragment; } if ($f = fsockopen($host, 80, $errno, $errstr, $this->connection_time)) { $rss_content = ''; fputs($f, "GET $uri HTTP/1.0\r\nHost: $host\r\n\r\n"); while (!feof($f)) { $rss_content .= fgets($f, 512); } fclose($f); // Parse document encoding $result['encoding'] = $this->my_preg_match("'encoding=[\'\"](.*?)[\'\"]'si", $rss_content); // if document codepage is specified, use it if ($result['encoding'] != '') { $this->rsscp = $result['encoding']; } // This is used in my_preg_match() // otherwise use the default codepage else { $this->rsscp = $this->default_cp; } // This is used in my_preg_match() // Parse CHANNEL info preg_match("'(.*?)'si", $rss_content, $out_channel); foreach($this->channeltags as $channeltag) { $temp = $this->my_preg_match("'<$channeltag.*?>(.*?)'si", $out_channel[1]); if ($temp != '') $result[$channeltag] = $temp; // Set only if not empty } // If date_format is specified and lastBuildDate is valid if ($this->date_format != '' && ($timestamp = strtotime($result['lastBuildDate'])) !== -1) { // convert lastBuildDate to specified date format $result['lastBuildDate'] = date($this->date_format, $timestamp); } // Parse TEXTINPUT info preg_match("']*[^/])>(.*?)'si", $rss_content, $out_textinfo); // This a little strange regexp means: // Look for tag with or without any attributes, but skip truncated version (it's not beggining tag) if (isset ($out_textinfo[2])) { foreach ($this->textinputtags as $textinputtag) { $temp = $this->my_preg_match("'<$textinputtag.*?>(.*?)'si", $out_textinfo[2]); if ($temp != '') $result['textinput_'.$textinputtag] = $temp; // Set only if not empty } } // Parse IMAGE info preg_match("']*>(.*?)'si", $rss_content, $out_imageinfo); if (isset ($out_imageinfo[1])) { foreach ($this->imagetags as $imagetag) { $temp = $this->my_preg_match("'<$imagetag.*?>(.*?)'si", $out_imageinfo[1]); if ($temp != '') $result['image_'.$imagetag] = $temp; // Set only if not empty } } // Parse ITEMS preg_match_all("'(.*?)'si", $rss_content, $items); $rss_items = $items[2]; $i = 0; $result['items'] = array (); // create array even if there are no items foreach ($rss_items as $rss_item) { // If number of items is lower then limit: Parse one item if ($i < $this->items_limit || $this->items_limit == 0) { foreach ($this->itemtags as $itemtag) { $temp = $this->my_preg_match("'<$itemtag.*?>(.*?)'si", $rss_item); if ($temp != '') $result['items'][$i][$itemtag] = $temp; // Set only if not empty } // Strip HTML tags and other bullshit from DESCRIPTION if ($this->stripHTML && $result['items'][$i]['description']) $result['items'][$i]['description'] = strip_tags($this->unhtmlentities(strip_tags($result['items'][$i]['description']))); // Strip HTML tags and other bullshit from TITLE if ($this->stripHTML && $result['items'][$i]['title']) $result['items'][$i]['title'] = strip_tags($this->unhtmlentities(strip_tags($result['items'][$i]['title']))); // If date_format is specified and pubDate is valid if ($this->date_format != '' && ($timestamp = strtotime($result['items'][$i]['pubDate'])) !== -1) { // convert pubDate to specified date format $result['items'][$i]['pubDate'] = date($this->date_format, $timestamp); } // Item counter $i ++; } } $result['items_count'] = $i; return $result; } else { return False; //die("Network error: $errstr ($errno)"); } } } ?> blog:ludens


Webserver migration

~ studio:ludens @ 11:02 Europe/Amsterdam

Because of overwhelming interest in the Repper tool, we have decided to move to a new server with more space and faster access time. Over the next couple of days we will migrate our tools to our new server. During this time, you might experience some problems, such as broken links (if you use a linked patterns in your site) or the site being temporary unavailable. Please do not panic, this is all part of the plan to give you the best design tools ever ;-) !!


The studio:ludens design team

Bookmark and Share


Just launched: Repper Gallery

~ studio:ludens @ 22:45 Europe/Amsterdam

We’ve been planning this for a while, but it is finally there: the Repper Gallery! With the gallery, you can explore all the patterns that you and other people have made with the Repper pattern making tool. All patterns in the gallery are released under the Creative Commons license for non-commercial use.

Repper Gallery

We have provided you with some options to find patterns in every shape, color or style you can think of. You can search on:

  • Tags: find patterns with a certain subject or style. And if you find a nice pattern, please help all other people and yourself search for them by adding tags yourself. (we’ve just launched it, so not very many patterns have been tagged yet. We need your help!)
  • Color: we’re really excited about this one! It’s still in beta-stage, but you can search for patterns in a certain color. Click the color box next to the search field to select the color you want and get inspired by the amazing variety of patterns out there.
  • Size: different sizes of patterns can be used for different things. Small patterns often look really good as a stylish Twitter (video), MySpace or desktop background. Big patterns are good for situations where you need a lot of detail: use it in your personal art project or send a postcard with the pattern on it to your friends! (thanks to our partner!)

As always, we’d very much like to know what you think of this new option. Repper is a community-driven project and we’d like to hear what you want to do with it. We’ve already got some new features planned…

More on this soon!

Go to the Gallery

Your own patterns with Repper

Bookmark and Share


Repper Frenzy - my favourites

~ alex @ 14:34 Europe/Amsterdam

The past couple of days have been quite hectic here @ studio:ludens. After we put the word out that we had a new tool for you to play with, Repper, it got twittered, tweeted, twotted, twadoozled and twambled. At the moment, we have almost 3500 pattern designs. What we are working on now is a way to make all these patterns available to the community with a nice web-based interface.

We will keep you updated on our progress with that (follow us on twitter: @studioludens), but in the meantime I want to show you some of my favourite patterns.

Flower skin

Flower skin



Flower Pattern 1

Nice flowers

Hands 1

Hands 1

Abstract 1

Abstract 1

These are just some of the patterns that have been made using Repper. We are excited about the overall quality of the patterns and we want the best pattern makers to get credit for their work. So, if you recognize one of the patterns as one you made, comment on this blog post and we’ll give you credit!

More patterns after the jump…

continue reading »

Bookmark and Share


Super easy pattern making with ‘Repper’

~ studio:ludens @ 16:20 Europe/Amsterdam


What started as a weekend project has developed into a working product for you to get your hands on, for free! We are proud to present to you: Repper, the pattern creator. This nifty app turns any image into a pattern you can use in your favourite image program, your social networking profile background or your website. I posted a video for you on youtube and vimeo so you can check out how it works.

Repper Youtube

Youtube Video

repper vimeo

Vimeo video

Give it a go! And tell us what you think! If you have comments, suggestions for improvement, requests for new features or praise, you are more than welcome to send it to us. We need your input to improve this tool, and that’s what we want to do.

Stay tuned for updates and new features to Repper over the coming weeks.

And, of course, happy pattern making!

Bookmark and Share


FlyingStick Project Files

~ studio:ludens @ 13:23 Europe/Amsterdam

Wing Pattern Illustrator File


Wing 04 Illustrator File


/more to come…

Bookmark and Share


Curious Cup project Files

~ studio:ludens @ 13:15 Europe/Amsterdam

Here you guys can find all the files from the ‘Curious Cup’ project (Fablab workshop March 27th). Enjoy!

coffeedrinker1 coffeedrinker2

Flash 10 application

Flash 10 SWF

RFID Plastic case Illustrator File

RFID wood case Illustrator File

Bookmark and Share


Ludens Flickr page

~ studio:ludens @ 11:58 Europe/Amsterdam

From now on, you can find all the photos we make on workshops and images of our design in progress on our new studio:ludens Flickr page. Happy viewing!

Bookmark and Share


Fablab workshop March 27th

~ studio:ludens @ 11:31 Europe/Amsterdam

Last Friday we held a workshop at Little Mountain for design students and professionals in Eindhoven. Our goal was to explore the possibilities of the Fablab concept for designers. Results for this day included three (mostly) working prototypes and a lot of inspiration on what a Fablab should be, Eindhoven Style. Read on for an account of the day, with lots of pictures.

fablab_workshop_2_studio_ludens-6 continue reading »

Bookmark and Share


User-centered Innovation

~ studio:ludens @ 17:16 Europe/Amsterdam

I found this amazingly interesting video from Eric von Hippel where he talks about user-centered innovation. For us, stimulating this type of innovation and giving more people access to tools with which they can innovate is an important goal.

What I noted in the examples von Hippel mentioned in his talk was the skill of users to modify a product or create a totally new one. What if users who do not have the tools now to build something will have them in the future. Could that mean that we can access a whole new field of knowledge that has never been used before?


From: Eric de Bruijn

Bookmark and Share


Dutch Design Week 2008 a big success!

~ studio:ludens @ 15:39 Europe/Amsterdam

With over a thousand visitors from all over the world our humble presentation stand was hitting it big time. This year we were to be found in the Klokgebouw building on Strijp S. Together with over a hundred other independent design studio’s we presented our new exciting ideas to the world.

For us, this was the opportunity to let everybody meet and play with our new design tools. What made it even more exciting is that people could see their own design being made in front of their eyes! The kind people at Trotec lend us a laser cutter to complete our production process and fulfill our goal: show people they can be creative. And creative they were! Over 150 designs were made by the visitors, and our stand grew in coolness with every design we put up there. Check it out:

Apart from letting people create their own coaster designs we showcased another product: ‘Create your own carpet’.  We presented two carpet designs made from the best carpets in the Netherlands. It worked out quite wonderful and we are now discussing with a carpet producer about bringing it to the market. More on this soon!

Bookmark and Share