While working on my Recommended Links plugin, I wanted a way to auto-populate the link title field based on the URL entered. I was stuck for a while dealing with cross-domain XHR issues and initially fell back to using a WP Ajax request, using wp_remote_get to get the remote link and returning that to PHP… however, it was slow and not all that elegant. Why bootstrap the entire WP environment for one simple Ajax request?

Did some researching, though, and I discovered YQL, which I had played with before, but never thought of as a tool for getting around cross-domain request issues. Apparently, however, its been widely used for that purpose for a year or so — there’s even a jQuery plugin that converts all external Ajax requests to YQL queries. Sweet!

The one problem I had, though, was that YQL’s html table only includes the <body> element, and I wanted to retrieve the <title> text.

So I looked through the Open Data Tables available, and lo and behold, there’s an htmlstring table that returns the entire html of a document as a string. So all I had to do was a little regex matching to find the <title> element, and I was all set.

Performance wise, this is 4-5 times faster than going through wp_ajax and PHP (300-350ms per load as opposed to 1.2-1.6s, on my local environment).

Here’s my CoffeeScript code, if you want to see how it was done:

$('#reclink_URL').bind 'change', (event) ->
	linkUrl = $(this).val()
	$.ajax 'http://query.yahooapis.com/v1/public/yql',
		type: 'get',
		data: {
			q: "use 'http://www.datatables.org/data/htmlstring.xml' as htmlstring;
				select * from htmlstring where url='#{ linkUrl }'",
			format: 'json'
			},
		dataType: 'json',
		success: (r) ->
			response = r.query.results
			unless response
				alert '404 error?!'
				return false
			title = response.result.match( /<\s*title\s*>([^<]*)<\/title>/ )[1]
			unless title
				alert 'Document has no title?!'
				return false
			unless $('#reclink_title').val() is not ''
			 	$('#reclink_title').val title
	null

and the compiled jQuery/Javascript, for people who find that easier to read:

    $('#reclink_URL').bind('change', function(event) {
      var linkUrl;
      linkUrl = $(this).val();
      $.ajax('http://query.yahooapis.com/v1/public/yql', {
        type: 'get',
        data: {
          q: "use 'http://www.datatables.org/data/htmlstring.xml' as htmlstring; select * from htmlstring where url='" + linkUrl + "'",
          format: 'json'
        },
        dataType: 'json',
        success: function(r) {
          var response, title;
          response = r.query.results;
          if (!response) {
            alert('404 error?!');
            return false;
          }
          title = response.result.match(/<\s*title\s*>([^<]*)<\/title>/)[1];
          if (!title) {
            alert('Document has no title?!');
            return false;
          }
          if ($('#reclink_title').val() !== !'') {
            return $('#reclink_title').val(title);
          }
        }
      });
      return null;
    });

Leave a Reply