Flash Content Managment Systems: With Search Engine Optimization
Flash Content Managment Systems: With Search Engine Optimization
Flash Content Managment Systems: With Search Engine Optimization
W I T H S E A R C H E N G I N E O P T I M I Z AT I O N
Above is an example of a flash navigation and a flash body content in action. All the text is in the html generated by the CMS, and thus retains all the SEO. This allows for embedding fonts and styles along with all your regular flash media.
About the Author, Steven Stark: Steven received his first job as a Junior Web Developer in 2000, and within the first year I was managing a small web development team after running the company solo for 6 months. By 2002, he attended the Center of Digital Arts and Technology where he completed the 3 year X-Media certification. After college he worked for another design company that dealt primarily with Car Dealers, producing over 20 high end websites in just under 6 months. Afterwards, he then moved to Vancouver and worked in Affiliate Managment for a large Online Sports company. Soon after, however, he started focusing on his own contracts and soon decided to turn that into a business. Being a jack of all trades allows Steven the unique ability to manage and teach a large staff what he knows and how to do it properly and efficiently. This experience and position makes it so Steven is able to keep on the cutting edge of new technologies like Flash and Flex Actionscripting, and come up with some new solutions to year old problems.
Appendix
CHAPTER #1 - Introduction Method to the Madness Action Script and Flash XML CMS / Joomla! Fonts Javascript CHAPTER #2 - Preparation Joomla! Class and Prototypes Forums CHAPTER #3 Customization Templates and CSS CMS Customization Strict XHTML CHAPTER #4 Action Script Fonts Javascript I.E. VS F.F. Add HTML and Parse Results Render HTML Filters and Gradients CHAPTER #5 Rinse and Repeat Troubleshooting and Testing Different .swf for each block Search Engine Optimization Credits
Introduction
Method to the Madness
This process is very long and nerve racking, and should not be tried at home by any sane person. That said, I am slightly crazy and like to push things to the edge, and I came across a problem. The problem was that I wanted to have flash animations behind the content generated by my content management system, and you are not allowed to put anything overtop of a flash element. Also, things under the flash element will, of course, loose all functionality. What is the solution? Send all the HTML data to flash and have flash, not the browser, render the html to the screen. And guess what, this actually does work! And not only does it work, but you can add more functionality than regular html and at the same time have search engines read all the info, as it is right inside the .html as any other page. Ok, if you are not currently jumping up and down with joy, this document is not for you and you should leave now. If you have an uncontrollable, slightly maddening smile right now, then you will be happy to go through the purgation needed to make this happen. This is not for amatures, and you will need to know all the following technologies discussed in this introduction. Also, you should keep in mind that I am only going to provide you with the most basic of information required to do this, and I expect that you will be able to fit in the blanks. This is a very large and maddening puzzle. And, finally, I am a self taught programmer, and just an intermediate one at that. I am sure that some of my code can be improved, and I would love it if you added a comment below showing everyone a superior method.
XML
For this project, only a moderate knowledge of xml is required. You must understand that the XHTML is going to be sent to flash, turned into a string, modified, then converted into an XML object, and rendered. In short, XHTML is a form of XML.
Joomla!
Joomla! Is currently my favorite Open Source Content Management System. We require an open source CMS because we need to modify some of the root code. Joomla! Runs on PHP and MySQL, and has a very large community for support. I use it with 90% of my websites. There are many benefits of using a CMS, however the most important is the ease of modifying the content, the extra functionality and the modules and components you can easily add to it and modify.
Fonts
If you have ever worked with a print designer, you will know that they really want to use their fancy font, however in the world of websites we can only use a few basic universal fonts like verdana and arial. This is no more! Flash is able to embed fonts, and we can link to the fonts in our .CSS file that we will later create. Also, now that we have flash 8 we can add filters and gradients to our fonts in action script, as if we were in photoshop.
Javascript
You will only need a basic understanding of javascript for this. You need to know how the Document Object Model (DOM) works in order to locate the correct blocks. getElementById() will be a big help for us here. That is about it, but I could see this soon leading into building your own popup windows full of content from within flash using java script, which will be the subject of the next document I will write. There is alot you can do with Javascript and Flash, so it cannot hurt to know a thing or two about Javascript.
Preparation
Joomla!
For this documentation I will be assuming that you are using Joomla! ( Mambo should be the same ). Install Joomla! to your server just like any other website. Set it so be SEO Friendly if possible. Fill it up with a some content but keep things loose. We need to keep the content simple html, only using things like <p> and <b> ect, as defined in the FP XHTML Render documentation, as discussed later. This is the time to setup and needed modules and components. Get everything working with plain html first before moving to flash.
Forums
If you are stuck, web forums are a great resource, but you need to pick carefully. I find good results from http://www.actionscript.org and http://kirupa.com/ .
Customization
Templates and CSS
There is actually nothing you need to do for the template, except keep in mind that the content is going to be hidden until the flash sees it. In Joomla!, the content is defined by the id body_outer, and if it is not then set it to that. In your .CSS, define .body_outer to have visibility: none; , making it invisible. When you embed your flash .swf, give it the name my_content_swf.
CMS Customization
Now we have to customize the output of our CMS to be that which flash will be expecting. I will go over this using Joomla!. Open /components/ com_content/content.class.php and /components/com_content/content.php in dreamweaver. In content.php navigate to where is says // show/hides the intro text, for me it is line 1255. You will have to edit this to what works for you, but for me I changed it to read: if ( $params->get( introtext ) ) { $row->text = <div id=\to_flash\><span class=\real_ header\> . $row->introtext . ( $params->get( intro_only ) ? : chr(13) . </span><span class=\real_content\> . $row->fulltext . </span></ div>); } else { $row->text = $row->fulltext; } What I am doing here is making sure to use divs and spans in the right spots. the render only can see spans, but the parent to_flash tag can be a div. I am also making sure that the ids are setup properly. Only the elements inside the to_flash div will be sent to flash. You may find other places you need to edit the content output in these two files.
Strict XHTML
You must make sure to read the documentation for the FP XHTML RENDER very closely, as it only allows certain tags. Also, all content must be setup with basic tags in XML format, so you can expect a certain header format followed by a series of <p> tags, so we can properly parse the string. This is very important and will cause most of your problems. I cannot stress this enough! Read the documentation that comes with FP XHTML closely because as versions of FP XHTML change, so will the compatability. I am hoping that the future versions will be alot less strict, allowing for a much smoother CMS to Flash integration.
Action Script
Fonts
Flash is great, it can embed any font you want. There is plenty of documentation about this online. You import the font into your library, give it a linkage id and leave set the size and bold and that. Then leave it alone! Every .swf will have a .css associated with it, and that .css is where you define the font styles and the linkage id to the font you wish to use.
JavaScript
This is a very important step. Frames #1 and #2 will be dedicated to javascript and you flash will start on frame #3. in frame #1 put the following: _root.getURL(javascript: top.document.my_content_swf. SetVariable(\_root.html_content\,unescape(top.document. getElementById(\to_flash\).innerHTML));); This script is calling the HTML from the to_flash div we defined earlier, and sending it to the my_content_swf .swf on the page (this flash file), as the string _root.html_content. On frame two, include this code:
if(_root.html_content == undefined){ this.gotoAndPlay(1); }; This creates a slow frame based loop. No need to use up the computer with a really fast loop or listener, so just use a frame based loop. You will thank me when you have a lot of these going at once!
I.E. vs F.F.
Internet Explorer acts differently than Fire Fox when using this javascript .innerHTML method. For this reason we have to change the whole string to lower case. We then have to parse this string using this function: String.prototype.replace = function(a,b) {return this.split(a).join(b);} For my content my I.E. fix parsing looks like this: = _root.html_content.replace( ,); = _root.html_content.replace(class=re,class=\ = _root.html_content.replace(er>,er\>); = _root.html_content.replace(ent>,ent\>); = _root.html_content.replace( size=24>,
This removes the tabs (that is not spaces it is the tab character), and adds the quotes where they should be. You have to be creative here, and know what html you are expecting. Here I am expecting a font tag with the size of 24 set. Yes, this is a touch restricing, however it should be workable in most cases.
/* String.prototype.encase A simple and quick way to ensure your strings are being displayed with the proper capitalization, no matters how their content is capitalized. Concerning the pattern parameter, every alphabetical char is mapped as capitalization mask, while a non-alphabetical char is mapped as keep the source capitalization for this char. The last pattern char is wrapped till the end of string. Ex: trace(hELLo WoRLd.encase(A.)); Displays: HELLo WoRLd Ex: trace(hELLo WoRLd.encase(Aa)); Displays: Hello world Ex: trace(hELLo WoRLd.encase(A)); Displays: HELLO WORLD Have fun! - Nosferatu */ String.prototype.encase = function(pattern) { if (typeof pattern != string) return this; var a=a, _a=A, z=z, _z=Z, str=, i, j, pt, ch; String.prototype.__c = String.prototype.toString; for (i = 0, j = Math.min(this.length, pattern.length); i < j; i++) { ch = this.charAt(i); pt = pattern.charAt(i); String.prototype.__c = pt >= _a && pt <= _z ? String.prototype. toUpperCase : pt >= a && pt <= z ? String.prototype.toLowerCase : String. prototype.toString; str += ch.__c(); } str += this.substring(i).__c(); delete String.prototype.__c; return str; } I then have to go through my XML and find the proper nodes and change the first characters in each line and paragraph to be capitalized. I can only do this by knowing the exact format for the html I am collecting. My script looks like this:
_root.test_xml.parseXML(_root.test_call); //capitalize quote _root.test_xml.childNodes[0].childNodes[1].childNodes[0]. childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[0]. childNodes[0].nodeValue = \ + _root.test_xml.childNodes[0]. childNodes[1].childNodes[0].childNodes[0].childNodes[0].childNodes[0]. childNodes[0].childNodes[0].childNodes[0].nodeValue.encase(Aa) + \; //capitalize author _root.test_xml.childNodes[0].childNodes[1].childNodes[0]. childNodes[0].childNodes[0].childNodes[0].childNodes[1].childNodes[0]. nodeValue = ~ + _root.test_xml.childNodes[0].childNodes[1]. childNodes[0].childNodes[0].childNodes[0].childNodes[0].childNodes[1]. childNodes[0].nodeValue.encase(Aa); //capitalize body //ph1 for(a=0; a<_root.test_xml.childNodes[0].childNodes[1].childNodes[0]. childNodes[0].childNodes[0].childNodes[1].childNodes.length; a++){ test = _root.test_xml.childNodes[0].childNodes[1]. childNodes[0].childNodes[0].childNodes[0].childNodes[1].childNodes[a]. childNodes[0].nodeValue.split(. ); for(b=0; b<test.length; b++){ test[b] = test[b].encase(Aa); trace(b+<>+test[b]); } _root.test_xml.childNodes[0].childNodes[1].childNodes[0]. childNodes[0].childNodes[0].childNodes[1].childNodes[a].childNodes[0]. nodeValue = test.join(. ); } With this script I am allowing for as many paragraphs as there is. I am not, however, searching for question marks as the end of a sentence, only periods. This parsing method only works when you know the exact format of the XHTML that the flash should receive. In most instances, you do know the exact format.
Render HTML
Now that we have our properly formatted XML object ready, we can render ourselves some HTML inside Flash! This is where the magic happens. You can put the render code right on frame #3 at the end, or you can be like me and put it in another movieclip in the library, with a linkage id, so you can call it into your scroll box. My render code is close to the same as the examples (mine updates my scrollbars, and uses javascript errors) from FP XHTML RENDER, and looks like this:
//!-- UTF8 //########################################## //enable tooltips import FastProtoZoo.FPhtmlRender.htmlRender; //attach on the fly this.attachMovie(htmlRender.symbolName, pgr, 1); //set box dim this.pgr.setDims(666,257); //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- this.pgr.setHTFCallback(this, received); //page rendered callBack this.pgr.setCallback(this, rendered, error); //enable html fixes this.pgr.useHTMLFix=true; // this.received = function(value:String) { trace(asfunction###+value); //parse if it is a close command }; //if rendered get page parameters this.rendered = function(value:String) { trace(rendered###+value); _root.scroll.bar.update(); }; //error while loading this.error = function(value:String) { trace(error###+value); _root.getURL(javascript:alert(error!>+value+);); }; //#############parse page this.pgr.preparse(_root.test_xml);
Credits
Written By Steven Alan Stark This file is allowed to be published on VancouverOnlineMedia.com and Digitopolis.com only. Please leave comments and and ideas you may have to improve this procedure. You can email me directly at steven@stevenstark.com ~Thank You