How to use CDN for static content (javascript/CSS/Font files) in Question2Answer CMS?

Website speed is one of the major factors in the search engine ranking algorithm. If your website takes several seconds to load, search engines will rank your pages low even if you have great content. There are many things that you need to consider to have a fast website and delivering static content using CDN is one of them. If you have hosted your JS/CSS/Image files in the USA and your visitors are from India, your webpages will take several seconds to load for Indian visitors. But delivering your static content from CDN will make your webpages faster in India too.

Question2Answer, aka Q2A, is a very user-friendly CMS to post questions and answers. Unlike WordPress, it does not 100s of plugins to add some new features to it. If you want to add some features to Q2A, you need to make changes to its codes and to modify codes, you need to first understand the flow of codes. In this post, I am going to explain what changes you need to make in Q2A codes to deliver static content from a CDN. Thanks to the Q2A team for keeping codes on Github, that made my search easier.

You need to modify only 3 PHP files to deliver static files (JS, CSS, and font files) from a CDN. If any of your posts contains an image file, it will not be delivered from the CDN. Here are the steps:

  1. Create a folder (e.g. “qacdn”) in the home directory (e.g. “public_html”) of your website.
  2. Create 3 folders “qa-content”, “qa-plugin”, and “qa-theme” in the new folder “qacdn”.
  3. Copy (not move) all files from “public_html/qa-content” to “public_html/qacdn/qa-content”.
  4. Copy (not move) all files and folders from “public_html/qa-theme/SnowFlat” to “public_html/qacdn/qa-theme/SnowFlat”. You can move only static files if you want.
  5. Copy (not move) all files and folders from “public_html/qa-plugin/wysiwyg-editor” to “public_html/qacdn/qa-plugin/wysiwyg-editor”.
  6. If you are using BunnyCDN, add a pull zone to point to “yourdomain.com/qacdn”. I have not used other CDN, so you need to figure out how can you access “yourdomain.com/qacdn”.
  7. Using your domain DNS manager, add a CNAME (e.g. “static.yourdomain.com”) to point to the URL of your CDN you got in step 6. This way you can access the content of the new folder “qacdn” using “static.yourdomain.com”.
  8. Now time to make small changes in the following PHP codes (existing line in the code has been commented out and the new line has been added to use CDN. Variable $this->rooturl has been replaced with $cdnurl in qa-theme.php for the font files.):

public_html/qa-include/qa-theme-base.php

public function head_css()
{
	//$this->output('<link rel="stylesheet" href="' . $this->rooturl . $this->css_name() . '"/>');  // commented to use CDN
	$this->output('<link rel="stylesheet" href="https://static.domain.com/qa-theme/SnowFlat/' .  $this->css_name() . '"/>');

public_html/qa-include/app/page.php

if (isset($qa_content['script_rel'])) {
	$uniquerel = array_unique($qa_content['script_rel']); // remove any duplicates
	foreach ($uniquerel as $script_rel) {
		// load recaptcha JS from google
		if (strpos(qa_html($script_rel) , "google.com") !== false) {
			$script[] = '<script src="' . qa_html(qa_path_to_root() . $script_rel) . '"></script>'; 
		}
		else	{
			//$script[] = '<script src="' . qa_html(qa_path_to_root() . $script_rel) . '"></script>';  // commented out to use CDN
			$script[] = '<script src="https://static.domain.com/' .  qa_html($script_rel) . '"></script>'; 
		}
	}
}

if (isset($qa_content['script_src'])) {
	$uniquesrc = array_unique($qa_content['script_src']); // remove any duplicates
	foreach ($uniquesrc as $script_src) {
		// load recaptcha JS from google
		if (strpos(qa_html($script_src) , "google.com") !== false) {
			$script[] = '<script src="' . qa_html($script_src) . '"></script>';
		}
		else	{
			//$script[] = '<script src="' . qa_html($script_src) . '"></script>';	// commented out to use CDN 
			$script[] = '<script src="https://static.domain.com' . substr(qa_html($script_src), strpos(qa_html($script_src), "/")) . '"></script>';
		}
	}
}

public_html/qa-theme/SnowFlat/qa-theme.php

public function head_css()
{	
	// change $this->rooturl to $cdnurl
	$cdnurl = "https://static.domain.com/qa-theme/SnowFlat/";   // use it for CDN
	// add RTL CSS file
	if ($this->isRTL)
		$this->content['css_src'][] = $this->rooturl . 'qa-styles-rtl.css?' . QA_VERSION;

	if ($this->localfonts) {
		// add Ubuntu font locally (inlined for speed)
		$this->output_array(array(
			"<style>",
			"@font-face {",
			" font-family: 'Ubuntu'; font-weight: normal; font-style: normal;",
			" src: local('Ubuntu'),",
			"  url('{$cdnurl}fonts/ubuntu-regular.woff2') format('woff2'), url('{$cdnurl}fonts/ubuntu-regular.woff') format('woff');",
			"}",
			"@font-face {",
			" font-family: 'Ubuntu'; font-weight: bold; font-style: normal;",
			" src: local('Ubuntu Bold'), local('Ubuntu-Bold'),",
			"  url('{$cdnurl}fonts/ubuntu-bold.woff2') format('woff2'), url('{$cdnurl}fonts/ubuntu-bold.woff') format('woff');",
			"}",
			"@font-face {",
			" font-family: 'Ubuntu'; font-weight: normal; font-style: italic;",
			" src: local('Ubuntu Italic'), local('Ubuntu-Italic'),",
			"  url('{$cdnurl}fonts/ubuntu-italic.woff2') format('woff2'), url('{$cdnurl}fonts/ubuntu-italic.woff') format('woff');",
			"}",
			"@font-face {",
			" font-family: 'Ubuntu'; font-weight: bold; font-style: italic;",
			" src: local('Ubuntu Bold Italic'), local('Ubuntu-BoldItalic'),",
			"  url('{$cdnurl}fonts/ubuntu-bold-italic.woff2') format('woff2'), url('{$cdnurl}fonts/ubuntu-bold-italic.woff') format('woff');",
			"}",
			"</style>",
		));
	}



	public function head_script()
	{
		//$jsUrl = $this->rooturl . $this->js_dir . '/snow-core-js?' . QA_VERSION; //commented out to use CDN 
		$jsUrl = "https://static.domain.com/qa-theme/SnowFlat/" . $this->js_dir . '/snow-core-js?' . QA_VERSION;
		$this->content['script'][] = '<script src="' . $jsUrl . '"></script>';

		parent::head_script();
	}
	

In the above code, I have replaced ‘snow-core.js’ with ‘snow-core-js’ as BunnyCDN was modifying the code. I hope it works for you. I am using BunnyCDN and the static files are delivered to my website discoverbits.in from the CDN. If you have any questions, post them in the comment box.

One Reply to “How to use CDN for static content (javascript/CSS/Font files) in Question2Answer CMS?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.