Integrating Classic ASP with WordPress using AJAX

I’ve built a few websites now in WordPress with some custom data that had to be integrated into Classic ASP websites. Here’s how I did this using AJAX from VBScript.

I’ve taken three different approaches (so far!) to integrate data from an external website into a Classic ASP website:

  • pull HTML ready to output onto the page
  • pull XML and parse it, iteratively writing the HTML output
  • pull XML and transform it into HTML using XSLT

Each of them are useful approaches, depending on the circumstances.

Pulling HTML from WordPress into Classic ASP

This is by far the simplest approach, but it binds the output structure to the WordPress site. I used this when I was replacing a Classic ASP website with a new, large WordPress website, which was built in stages over a period of time. I needed to move some data administration across to WordPress but keep showing the data on the Classic ASP website.

Rather than duplicate the data from WordPress across to something Classic ASP could access, I chose to just take the HTML output from WordPress and display it on the Classic ASP website. The WordPress website uses shortcodes to display tables of data, and search forms for that data. In WordPress, a shortcode function must return the HTML for the page as a string, given a set of parameters, so it’s easy to just call the shortcode function and grab the HTML to return via AJAX.

The HTML in this instance has a search form, and a table of data. I needed to process any search parameters to pass to WordPress, and display the HTML on the Classic ASP page after the search. All of the actual search and formatting logic is on the WordPress site, in a custom plugin.

Here’s the interesting bits of the code in my WordPress plugin; I’ve left out how the HTML was generated because it’s not important for this post, but you can probably imagine the usual database query, iteration to build an HTML table, and search form.

// add the AJAX actions, for both anonymous and logged-in users
add_action('wp_ajax_awri-yeb-ext', 'ajaxYebExternal');
add_action('wp_ajax_nopriv_awri-yeb-ext', 'ajaxYebExternal');

/**
* run the YEB search from an external site,
* returning HTML for insertion into external website's pages
*
* NB: search terms will be found in $_POST per normal,
* just posted by AJAX instead
*/
function ajaxYebExternal() {
	$baseURL = stripslashes($_GET['base']);
	$search = new YebSearch();
	$search->setBaseURL($baseURL);
	$html = $search->replaceShortTag(array());

	header('Content-type: text/html');
	echo $html;
	exit;
}

Now, here’s how I pulled it across to Classic ASP. Remember that the HTML includes a search form, so I have to check for search parameters to pass to WordPress along with the AJAX action.

' send an HTTP request to new WordPress site to do the search there on current data
Sub ShowRemoteYEB()
	Dim xhr, post, url, baseURL

	On Error Resume Next
	Err.Clear

	' base URL for any in-page links, and the search form action
	baseURL = "http://" & Request.ServerVariables("HTTP_HOST") & Request.ServerVariables("SCRIPT_NAME")

	' AJAX service URL
	url = "http://example.com/wp-admin/admin-ajax.php"

	' build the AJAX request, giving the AJAX action and our script name, plus any search parameters
	post = "action=awri-yeb-ext&base=" & Server.URLEncode(baseURL)
	For Each i In Request.QueryString
		post = post & "&" & Server.URLEncode(i) & "=" & Server.URLEncode(Request.QueryString(i))
	Next

	Set xhr = Server.CreateObject("MSXML2.ServerXMLHTTP")
	xhr.setTimeouts 60000, 60000, 60000, 180000
	xhr.open "GET", url & "?" & post, False
	xhr.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
	xhr.send

	If Err.Number = 0 Then
		Response.Write xhr.responseText
	End If
	Set xhr = Nothing

	On Error GoTo 0
End Sub

All that was needed then was a copy of the form’s JavaScript scripts and some CSS to style the HTML so that it fitted in with the rest of the Classic ASP website, until the whole site finally moved across to WordPress.

Pulling XML from WordPress and processing in Classic ASP

I do the odd bit of maintenance on a portal website written in Classic ASP. It has the usual assortment of news articles, events, an industry directory, classified ads, and job ads. Recently, the job ads moved to a new WordPress website using a jobs board plugin (which is a series of stories in itself, only to be told over small glasses of something strong!)

To get a listing of the latest jobs on the front page of the portal website, I again used AJAX to pull from the WordPress website. Because the data formatting was different between the WordPress website and the portal website, I chose to pull the data across as XML and process it locally in Classic ASP. This allowed me to provide a single XML feed from WordPress, and process and display it differently on different Classic ASP pages.

Here’s the core of the code on WordPress.

// add the AJAX actions, for both anonymous and logged-in users
add_action('wp_ajax_jobs-recent', 'ajaxRecentJobs');
add_action('wp_ajax_nopriv_jobs-recent', 'ajaxRecentJobs');

/**
* AJAX function returning a list of recent jobs
*/
function ajaxRecentJobs() {
	$limit = 10;
	if (isset($_GET['limit'])) {
		$limit = @intval($_GET['limit']);
		if ($limit <= 0)
			$limit = 10;
	}

	// create a new XML writer
	$xml = new XMLWriter();
	$xml->openMemory();
	$xml->startDocument('1.0', 'UTF-8');
	$xml->startElement('jobs');

	// ask jobs board plugin for a list of jobs
	$jobList = Wpjb_Model_Job::activeSelect()
		->limit($limit)
		->execute();

	// iterate over list, adding to XML
	foreach ($jobList as $job) {
		$xml->startElement('job');

		$xml->writeElement('url', wpjb_link_to('job', $job));
		$xml->writeElement('is_featured', $job->is_featured);
		$xml->writeElement('title', $job->job_title);
		$xml->writeElement('location', $job->locationToString());

		// must assign to variable before testing; empty() can't test magic properties
		$company_name = $job->company_name;
		if (!empty($company_name)) {
			$xml->writeElement('company', $company_name);
		}

		$job_created_at = $job->job_created_at;
		if ($job_created_at) {
			// want the date in XML friendly format
			// so convert from string to DateTime, and format
			$xml->writeElement('job_created_at', date_create($job_created_at)->format('c'));
		}

		$xml->endElement();		// job
	}
	$xml->endElement();		// jobs

	// set the content type and send the XML
	header('Content-Type: application/xml; charset=UTF-8');
	echo $xml->outputMemory();
	exit;
}

And here’s how I chopped it up in Classic ASP for the front page of the portal website.

' send an HTTP request to retrieve an XML list of jobs from Jobs website and write to page
Sub RecentJobs()
	Dim xhr, payload, xml, url
	Dim job, jobnodes, title, location

	On Error Resume Next
	Err.Clear

	' AJAX query URL
	url = "http://example.com/wp-admin/admin-ajax.php?action=jobs-recent&limit=3"

	Set xhr = Server.CreateObject("MSXML2.ServerXMLHTTP")
	xhr.setTimeouts 60000, 60000, 60000, 180000
	xhr.open "GET", url, False
	xhr.send

	If Err.Number = 0 Then
		Set xml = Server.CreateObject("MSXML2.DOMDocument")
		If xml.loadXML(xhr.responseText) Then
			Set jobnodes = xml.documentElement.selectSingleNode("/jobs").childNodes
			If jobnodes.length = 0 Then
				Response.Write "<li><strong>No records found.</strong></li>" & vbCrLf
			Else
				For Each job In jobnodes
					title = job.selectSingleNode("./title").text
					location = job.selectSingleNode("./company").text
					If Len(location) > 0 Then
						location = location & " / "
					End If
					location = location & job.selectSingleNode("./location").text
					If Len(location) > 0 Then
						title = title & ": " & location
					End If

					Response.Write "<li>&raquo;  <a href=""" & job.selectSingleNode("./url").text & """>" _
						& Server.HTMLEncode(title) & "</a></li>" & vbCrLf
				Next
			End If
		Else
		End If
		Set xml = Nothing
	End If
	Set xhr = Nothing

	On Error GoTo 0
End Sub

There’s actually a few different scripts using the XML jobs feed, and one of them is quite complex; all of the logic for that (display logic) is kept in Classic ASP on the portal website, and the WordPress website (and its code) never needs to know about any of it.

Transforming XML with XSLT in Classic ASP

A while back, I had to integrate data from an internal server with a listing page on a public server. The data from the internal server was dumped to XML daily, and loaded onto a folder on the public server. I chose to use XSLT to transform the XML into HTML, because the client would be making some changes to the template as time progressed and XSLT seemed the easiest way to allow that to happen.

Here’s how I processed the XML via XSLT in Classic ASP.

Sub showServices()
	' load XML data
	Set services = Server.CreateObject("MSXML2.DOMDocument.6.0")
	services.validateOnParse = true
	services.load Server.MapPath("/_private/services.xml")
	If err.number <> 0 Then
		Response.Write "Error loading data: " & err.description
		Exit Sub
	End if

	' load the XSLT script
	Set xsldom = Server.CreateObject("MSXML2.FreeThreadedDOMDocument.6.0")
	xsldom.validateOnParse = true
	xsldom.load Server.MapPath("showServices.xsl")
	If err.number = 0 Then
		Set xslt = Server.CreateObject("MSXML2.XSLTemplate.6.0")
		xslt.stylesheet = xsldom
	End If

	' transform XML data according to XSL template
	Set xslproc = xslt.createProcessor()
	If err.number = 0 Then
		xslproc.input = services
		If err.number = 0 Then
			xslproc.Transform
			If err.Number = 0 Then
				Response.Write xslproc.output
			End If
		End If
	End If
	If err.number <> 0 Then
		Response.Write "Error: " & err.description
	End if
End Sub

I won’t show the XSLT, because it is proprietary and would identify the client. However, there are many good XSLT tutorials around the web, and the point of this post is how to bring that across into an old Classic ASP website.

Jobs are done, quite a few of them in fact; I use the first two approaches extensively, and have used the third approach from time to time as it seemed appropriate. Either way, that cat gets skinned!

facebooktwittergoogle_plusredditpinterestlinkedinmailfacebooktwittergoogle_plusredditpinterestlinkedinmail
  • Ryan

    This is great but have you done the reverse? Use a wordpress site to house a classic asp program?

    Currently facing this issue and it is a mess of iframes.
    Thanks!
    -Ryan

    • http://snippets.webaware.com.au/ Ross McKay

      G’day Ryan,

      I haven’t, but the same principles apply. Probably the easiest way from Classic ASP to WordPress would be to have code in Classic ASP that generates the HTML you want on your WordPress site (without header/footer), and grab it using wp_remote_get() to pull it into WordPress. You could even cache it as a transient with an expiry that suits the freshness of your Classic ASP data, e.g. 30 minutes or 24 hours — that way your pages would load more quickly when someone has already visited them.

      Personally, I’d wrap that up in a simple plugin, and use either a shortcode or a widget to show it on the page.

      cheers,
      Ross