supernaut’s Links

Every blog used to have a Blogroll. But then they became sad; even WordPress got rid of theirs. Some people never heard or didn’t care. I discovered I’d never deleted my old link list, but it was also horribly out of date. I pondered updating it, but the idea seemed cumbersome.

Then I wondered if I could use my RSS feeds from my daily reading, all already categorised and downloadable as an OPML file. This would mean my link list would reflect the blogs and websites I’m actually reading now, and make redundant the need to have two separate lists.

… Turns out I can!

PHP has an extension called SimpleXML which can parse an xml file and spit it out however I might like and OPML is just an xml format. Off to the code!

I wanted to know if it was even possible first, but I ended up getting it all working, or at least dumping formattable text on the first try. From there to getting it nicely arranged by category was a much longer process, well, a couple of hours. Next to do is filtering, so I can exclude certain categories, and sorting alphabetically. As for the OPML file itself, I export it from my current RSS reader Feedly, and upload it to WordPress into a field using Advanced Custom Fields. It’s gloriously simple.

See all two-hundred-and-something of them here: supernaut’s Links

…(edit) Sorting alphabetically and excluding embarrassing categories achieved! For anyone interested in the code, it looks like this, and is largely based on Recently’s code, plus the filtering and sorting examples I found on Stack Overflow:

function supernaut_opml_feeds( $xmlObj, $depth = 1 ) {
	if ( count( $xmlObj->children() ) > 0 ) {
		echo str_repeat( "\t", $depth ) . '<ul class="opml-category">';
	}

	$feed_list = array();
	foreach ($xmlObj->children() as $feed) {
		$feed_list[] = $feed;
	}

	usort($feed_list, function($a, $b) {
		return strcasecmp( (string)$a['title'], (string)$b['title'] );
	});

	foreach ( $feed_list as $feed ) {
		if ( ($feed['title'] != 'blah') && ($feed['title'] != 'gaah') ) {
			if ( isset( $feed['htmlUrl'] ) || isset( $feed['xmlUrl'] ) ) {
				echo str_repeat( "\t", $depth ) . '<li>';
				if ( isset( $feed['htmlUrl'] ) ) {
					echo '<a href="' . htmlentities( $feed['htmlUrl'] ) . '"';
					if ( isset( $feed['description'] ) ) {
						echo ' title="' . htmlentities( $feed['description'] ) . '"';
					} else {
						echo ' title="' . $feed['title'] . '"';
					}
					echo ' target="_blank">' . $feed['text'] . '</a>';
				} else {
					echo $feed['text'];
				}
				if ( isset( $feed['xmlUrl'] ) ) {
					echo ' – <em><a href="' . htmlentities( $feed['xmlUrl'] ) . '">feed</a></em>';
				}
				echo '</li>';
			} elseif ( isset($feed['text'] ) && !isset( $feed['htmlUrl'] ) ) {
				echo str_repeat( "\t", $depth) . '<li>' . $feed['text'];
			}
			supernaut_opml_feeds( $feed, $depth + 1 );
		}
	}

	if ( count( $xmlObj->children() ) > 0) { 
		echo str_repeat( "\t", $depth) . '</ul>'; 
		if ( $depth > 1 ) {
			echo str_repeat( "\t", $depth - 1 ) . '</li>';
		}
	}
}

$opml_xml = get_field( 'opml_file' );
$opml_file = new SimpleXMLElement( $opml_xml, null, true );
supernaut_opml_feeds( $opml_file->body );