The Florida SEO - Learning Linux One Mistake at a Time.

A couple months ago I decided to take the leap into actually installing and running a Linux machine. After a couple of failed installs, I managed to format a disk and install my new favorite distro ... Debian installed. Coming from a Windoze environment there were a lot of hurdles to overcome just to figure out how to get around on a Linux setup. First off ... I've got to give props to the guys over at forums.debian.net ... without the hundreds of how-to posts I don't think I would have gotten too far.

The first real hurdle for me was wrapping my tiny little brain around the way Linux 'mounts' work. Being used to the drive letter mentality, it was odd to understand that there really is no drive letter ... it's just a label for how Windoze mounts a partition. I still don't really understand it all, but I do have an idea how It works now.

While Windoze typically installs to let's say c:\, Linux does not make a letter for a partition. As such, in Linux there is just '/' which is the root directory. Nearly all the working directories are installed under the root directory ... unless of course you should so choose to move them elsewhere ... which, is another story.

Typically, a Linux install will have the default directories installed as follows ...

/ - root = The main directory and the root of where everything else is.
/bin/ = The executable directory ... where stuff that can execute goes.
/boot/ = Guess what goes here heh? Yeah, your boot loader, kernels, etc.
/dev/ = Devices ... Big topic ... lot's of stuff in here ... mostly disks and tty's. Google it.
/home/ = This is where your files are ... You are running as a user right and not root right? If not ... Well ... You'll probably be reinstalling your system pretty soon ...
/etc/= This is where the configuration files are located in a Debian distro.
/lib/ = Libraries ... this is where the informational source files required by the systems' essential binaries are ...
/media/ = Mounted points for removable media ... like a usb or a CD-ROM ...
/opt/ = Optional applications ... Now this one is interesting because sometimes it's used for add-on applications that are not part of a typical .deb package. There may also exist sub directories under /opt too ... such as /opt/bin, /opt/include, /opt/lib, etc.
/proc/ = This is a virtual file system where processes status are found ... I.E. /proc/cpuinfo
/root/ = The REAL root users file. This is not the same as / root. This is the root users' home directory ... You really shouldn't be in there if your just working as a user.
/sbin/= System binaries – This is for the root user or the system ... not your stuff.
/srv/ = The serve directory ... I choose this one to serve my web stuff from. Why? I don't know ... I just happen to like the sound of /srv/ instead of /var/www ...
/sys/ = Supposedly the file system for kernel objects ... Don't know much about it yet.
/usr/ = The second level file system for shareable stuff ... like /usr/local, /usr/bin, or /usr/sbin ...
/var/ = Variable data ... many Linux distros will install Apache related stuff here ... Like /var/www for web docs ... I moved mine though but I don't think it really matters where it comes from ...
Again ... I'm new to Linux so a lot of this is well still new to me ... sue me if I say the wrong thing.

The biggest hurdle was trying to figure out how to actually move around the files system. First of all ... If you don't have permission ...Linux may not even let you enter a directory. Say for example you try to 'CD' to enter into the /root/ home directory you'll simply get a permission denied message. This is how Linux keeps standard users from accessing places they shouldn't. In order to access the /root/ directory you either need to be the root user (which you should never use while operating X windowed programs) or you need a special access level to get there. This access is called 'SU' or Substitute User. However, before being allowed to use SU ... you must be given permission in a special access file called the sudoers file ... Now on a Debian based Linux distro ... the sudoers file is located under /etc/ ... specifically /etc/sudoers ...

So you need to have root access to either add yourself or someone else to the sudoers file. I don't know exactly why, but you are supposed to only edit this file with the visudo command which, opens the file in the VI editor ... At this point you can either add yourself or someone else to the file as a 'sudoer' so that access may be given. However, if your not familiar with getting around in VI or VIM ... then well ... guess what ... You've got some more learnin' to do ... cause if you don't know how to get around in VIM (like I didn't) then you are going to be in for quite a surprise ...

So ... after literally two months of trial and error, I've finally gotten to the point where I can actually use Linux ... it's taken a lot of work ... but if I can figure it out then I guess nearly anyone can ...

Here's a screenshot of my Debian box running with KDE 4.4

BlogCFC ColdFish Code Block Print Function Update

Normally I pay quite a bit of attention to my site after I do any major updates or changes but I've been quite a slacker lately and I seemed to have missed a few issues that happened after I updated my blog core ... Bad me.

Something interesting that I truly thought would be an isolated incident - and my problem - actually wasn't. It seems that there was a bug where Gecko based browsers - Firefox - don't seem to like the window.frames[] syntax ... So, for those that are using BlogCFC and want to be able to print code blocks from Firefox ... You may need to update the formatter.cfc with the new syntax ... Here's the link for the formatter.cfc ... on RIAForge ... or you can simply copy the update from here ...

view plain print about
1<!---
2    Copyright 2009 Jason Delmore
3    All rights reserved.
4    jason@cfinsider.com
5    
6    This program is free software: you can redistribute it and/or modify
7    it under the terms of the GNU Lesser General Public License (LGPL) as published by
8    the Free Software Foundation, either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public License    
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18    --->

19<cfcomponent output="false">
20    <cffunction name="init" access="public" hint="This function initializes all of the variables needed for the component." output="false">
21        <cfscript>
22            //initialize a buffer
23
                
24            // If you're using JDK 1.5 or later and want some extra performance this can be a StringBuilder
25
            //variables.buffer=createObject("java","java.lang.StringBuilder").init();
26
            variables.buffer=createObject("java","java.lang.StringBuffer").init();
27            
28            // initialize private variables
29
            // TODO : Change the parser state to be a struct rather than individual variables.
30
            variables.isCommented=false;
31            variables.isTag=false;
32            variables.isValue=false;
33            variables.isCFSETTag=false;
34            variables.isCFScript=false;
35            variables.isCFQueryTag=false;
36            variables.isOneLineComment=false;
37            variables.isMXML=false;
38            variables.isActionscript=false;
39            variables.isSQL=false;
40            variables.isSQLValue=false;
41            variables.initialparser="";
42            variables.spansOpened = 0;
43            variables.spansClosed = 0;
44        
</cfscript>
45        <cfreturn this/>
46    </cffunction>
47    
48    <cffunction name="getHTMLOutput" access="public" hint="This function accepts a block of code and formats it into syntax highlighted HTML." output="false">
49        <cfargument name="code" type="string"/>
50        <cfargument name="parser" type="string"/>
51        <cfargument name="codesig" type="string"/>
52        <cfscript>
53            var BIstream = createObject("java","java.io.StringBufferInputStream").init(arguments.code);
54            var IStream = createObject("java","java.io.InputStreamReader").init(BIstream);
55            var reader = createObject("java","java.io.BufferedReader").init(IStream);
56            var line = reader.readLine();
57            var linenumber = 0;
58            
59            if (arguments.parser neq ""{
60                "variables.is#arguments.parser#" = true;
61            }
62            
63            if (getConfig().getShowToolbar()) {
64                variables.buffer.append(getToolbarHTML(arguments.code,arguments.codesig));            
65            }
66            
67            variables.buffer.append("<span id='formatted_code_" & arguments.codesig & "' style='" & getStyle("TEXT") & "'>");
68            while isdefinedd("line")) {
69                if (getConfig().getShowLineNumbers()) {
70                    linenumber = linenumber + 1;
71                    variables.buffer.append("<span style='" & getStyle("LINENUMBER") & "'>" & linenumber & "</span>");
72                }
73                formatLine(line);
74                line = reader.readLine();
75            }
76            // there appears to be more spans created than cleaned up... closing up any extras... will need to review to see what is keeping extra spans
77
            while (variables.spansOpened gt variables.spansClosed) {
78                variables.spansClosed = variables.spansClosed + 1;
79                variables.buffer.append("</span>");
80            }
81            variables.buffer.append("</span>");
82            reader.close();
83
84            return variables.buffer;
85        
</cfscript>
86    </cffunction>
87    
88    <cffunction name="getToolbarHTML" access="private" output="true">
89        <cfargument name="code" type="string"/>
90        <cfargument name="codesig" type="string"/>
91        <cfset var toolbarHTML = ""/>
92        <cfsavecontent variable="toolbarHTML">
93            <iframe id='print_frame_#arguments.codesig#' style='display:inline;height:0px;width:0px;' frameborder='0'></iframe>
94            <script type='text/javascript'>
95                function toggle_view_#arguments.codesig#() {
96                    var temp = document.getElementById('htmlencoded_plain_#arguments.codesig#').style.display;
97                    document.getElementById('htmlencoded_plain_#arguments.codesig#').style.display=document.getElementById('formatted_code_#arguments.codesig#').style.display;
98                    document.getElementById('formatted_code_#arguments.codesig#').style.display=temp;
99                    if (temp=='none') {
100                        document.getElementById('view_#arguments.codesig#').innerHTML='view formatted';
101                    } else {
102                        document.getElementById('view_#arguments.codesig#').innerHTML='view plain';
103                    }
104                }
105                function copy_to_clipboard_#arguments.codesig#() {
106                    var code=unescape(document.getElementById('htmlencoded_plain_#arguments.codesig#').innerHTML).replace(/&lt;/g, '\x3C').replace(/&gt;/g, '\x3E').replace(/&amp;/g, '\x26').replace(/\x3Cbr\x3E/gi, '\r\n').replace(new RegExp('&nbsp;&nbsp;&nbsp;&nbsp;', 'gi'), '\t');
107                    window.clipboardData.setData('text',code);
108                }
109                function print_#arguments.codesig#() {
110                    document.getElementById("print_frame_#arguments.codesig#").contentWindow.document.body.innerHTML = document.getElementById('formatted_code_#arguments.codesig#').innerHTML;
111                    document.getElementById("print_frame_#arguments.codesig#").contentWindow.focus();
112                    document.getElementById("print_frame_#arguments.codesig#").contentWindow.print();
113                }
114                function show_about_#arguments.codesig#() {
115                    document.getElementById('about_#arguments.codesig#').style.display='inline';
116                    window.setTimeout('hide_about_#arguments.codesig#();', 4000);
117                }
118                function hide_about_#arguments.codesig#() {
119                    document.getElementById('about_#arguments.codesig#').style.display='none';
120                }
121            </script>
122            <div style='#getStyle("TOOLBAR")#'>
123                <span style='margin:0 0 0 2em'/>
124                <!--- Toggle code view --->
125                <a href='javascript:toggle_view_#arguments.codesig#()' style='#getStyle("TOOLBARLINK")#' id='view_#arguments.codesig#'>view plain</a>
126                
127                <!--- Copy to clipboard --->
128                <a href='javascript:copy_to_clipboard_#arguments.codesig#()' style='display:none;#getStyle("TOOLBARLINK")#' id='view_copy_to_clipboard_link_#arguments.codesig#'>copy to clipboard</a>
129                <!--- The cross-browser copy to clipboard methods out there are hacky and only work on certain browsers... if the browser handles it, then the link show up... --->
130                <script type='text/javascript'>if(window.clipboardData) { document.getElementById('view_copy_to_clipboard_link_#arguments.codesig#').style.display='inline';}</script>
131                
132                <!--- Print --->
133                <a href='javascript:print_#arguments.codesig#()' style='#getStyle("TOOLBARLINK")#'>print</a>
134                
135                <!--- About --->
136                <a href='javascript:show_about_#arguments.codesig#()' style='#getStyle("TOOLBARLINK")#'>about</a>
137                
138            </div>
139            <span id='about_#arguments.codesig#' style='display:none;#getStyle("TEXT")#'><span style='#getStyle("LINENUMBER")#'>&nbsp;</span>&nbsp;ColdFISH is developed by Jason Delmore.  Source code and license information available at <a href='http://coldfish.riaforge.org/'>coldfish.riaforge.org</a><br/></span>
140            <span id='htmlencoded_plain_#arguments.codesig#' style='display:none;#getStyle("TEXT")#'>#REReplace(REReplace(htmleditformat(arguments.code), "\n", "<br />", "ALL"),"\t","&nbsp;&nbsp;&nbsp;&nbsp;","ALL")#</span>
141        </cfsavecontent>
142        <cfreturn toolbarHTML/>
143    </cffunction>
144    
145    <cffunction name="formatLine" access="private" hint="This function takes a single line of code and formats it into syntax highlighted HTML." output="false">
146        <cfargument name="line" type="any"/>
147        <cfscript>
148            var character = "";
149            var thisLine=arguments.line;
150            var i = 0;
151            var endtagPos = 0;
152            var startAttributePos = 0;
153            var keywordskip = 0;
154
155            
156            if (variables.isOneLineComment) endOneLineComment();
157            
158            for (i=0; i LT thisLine.length(); i=i+1)
159            {
160                character=thisLine.charAt(javacast('int',i));
161                if (character EQ '
<')
162                {
163                    if (variables.isCFScript AND NOT variables.isValue)
164                        endCFScript();
165                    if (regionMatches(thisLine, 1, i+1, "!--", 0, 3))
166                    {
167                        if (regionMatches(thisLine, 1, i+4, "-", 0, 1))
168                        {
169                            startComment("CF");
170                        } else {
171                            startComment("HTML");
172                        }
173                    } else {
174                        if (regionMatches(thisLine, 1, i+1, "CF", 0, 2) OR regionMatches(thisLine, 1, i+1, "/CF", 0, 3))
175                        {
176                            startTag("CF");
177                            if (regionMatches(thisLine, 1, i+3, "SET", 0, 3) AND NOT regionMatches(thisLine, 1, i+6, "T", 0, 1)) // CFSET Tag
178                            {
179                                variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',i+6)));
180                                i=i+5;
181                                startCFSET();
182                            }
183                            else if (regionMatches(thisLine, 1, i+3, "SCRIPT>", 0, 6)) // CFSCRIPT TAG
184                            {
185                                variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',i+9)) & "&gt;");
186                                i=i+9;
187                                startCFScript();
188                            }
189                            else if (regionMatches(thisLine, 1, i+3, "QUERY", 0, 5)) // START CFQUERY TAG
190                            {    // TODO: This sets the value color immediately to match SQL values including the CFQuery tag...
191                                variables.isCFQueryTag = true;
192                            } else if (regionMatches(thisLine, 1, i+4, "QUERY", 0, 5)) // END CFQUERY TAG
193                            {
194                                variables.isCFQueryTag = false;
195                                endSQL();
196                            }
197                        }
198                        else if    (
199                                     regionMatches(thisLine, 1, i+1, "TA", 0, 2) OR
200                                    regionMatches(thisLine, 1, i+1, "/TA", 0, 3) OR
201                                    regionMatches(thisLine, 1, i+1, "TB", 0, 2) OR
202                                    regionMatches(thisLine, 1, i+1, "/TB", 0, 3) OR
203                                    regionMatches(thisLine, 1, i+1, "TD", 0, 2) OR
204                                    regionMatches(thisLine, 1, i+1, "/TD", 0, 3) OR
205                                    regionMatches(thisLine, 1, i+1, "TF", 0, 2) OR
206                                    regionMatches(thisLine, 1, i+1, "/TF", 0, 3) OR
207                                    regionMatches(thisLine, 1, i+1, "TH", 0, 2) OR
208                                    regionMatches(thisLine, 1, i+1, "/TH", 0, 3) OR
209                                    regionMatches(thisLine, 1, i+1, "TR", 0, 2) OR
210                                    regionMatches(thisLine, 1, i+1, "/TR", 0, 3)
211                                ) // HTML TABLE
212                        {
213                            startTag("HTMLTABLES");
214                        }
215                        else if (regionMatches(thisLine, 1, i+1, "IMG", 0, 3) OR regionMatches(thisLine, 1, i+1, "STY", 0, 3) OR regionMatches(thisLine, 1, i+1, "/STY", 0, 4)) //IMG or STYLE Tag
216                        // TODO: Do separate syntax highlighting for stuff inside style
217                        {
218                            startTag("HTMLSTYLES");
219                        }
220                        else if (
221                                    regionMatches(thisLine, 1, i+1, "FORM", 0, 4) OR
222                                    regionMatches(thisLine, 1, i+1, "/FORM", 0, 5) OR
223                                    regionMatches(thisLine, 1, i+1, "INPUT", 0, 5) OR
224                                    regionMatches(thisLine, 1, i+1, "/INPUT", 0, 5) OR
225                                    regionMatches(thisLine, 1, i+1, "TEXT", 0, 4) OR
226                                    regionMatches(thisLine, 1, i+1, "/TEXT", 0, 5) OR
227                                    regionMatches(thisLine, 1, i+1, "SELECT", 0, 6) OR
228                                    regionMatches(thisLine, 1, i+1, "/SELECT", 0, 7) OR
229                                    regionMatches(thisLine, 1, i+1, "OPT", 0, 3) OR
230                                    regionMatches(thisLine, 1, i+1, "/OPT", 0, 3)
231                                )
232                        {
233                            startTag("HTMLFORMS");
234                        }
235                        else if (
236                                     regionMatches(thisLine, 1, i+1, "MX:", 0, 3) OR
237                                    regionMatches(thisLine, 1, i+1, "/MX:", 0, 4)
238                                )
239                        {
240                            if (regionMatches(thisLine, 1, i+4, "SCRIPT>", 0, 6)) // MX:SCRIPT TAG
241                            {
242                                startTag("ACTIONSCRIPTTAG");
243                                variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',i+10)) & "&gt;");
244                                i=i+10;
245                                startActionscript();
246                            } else if (regionMatches(thisLine, 1, i+5, "SCRIPT>", 0, 6)) // END MX:SCRIPT TAG
247                            {
248                                endActionscript();
249                                startTag("ACTIONSCRIPTTAG");
250                                variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',i+11)));
251                                i=i+12;
252                                endTag();
253                            } else {
254                                startTag("MXML");
255                                startAttributePos=find(' ',thisLine,i+1); //start finding the next space from current position
256                                endtagPos=find('>
',thisLine,i+1); //start finding the end tag from current position
257                                if (startAttributePos neq 0) {  // start attribute colors
258                                    variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',startAttributePos)));
259                                    i=startAttributePos-1;
260                                    startMXMLTag();
261                                } else {
262                                    if (endtagPos neq 0) { // found >

263                                        variables.buffer.append(thisLine.substring(javacast('int',i+1), javacast('int',endtagPos-1)));
264                                        i=i+endtagPos;
265                                        variables.buffer.append("&gt;");
266                                        endHighlight();
267                                    }
268                                }    
269                            }
270                        } else {
271                            if (variables.isActionscript or variables.isSQL) {
272                                variables.buffer.append("&lt;");
273                            } else {
274                                startTag("HTML");
275                            }
276                        }
277                    }
278                }
279                else if (character EQ '>')
280                {
281                    if (variables.isCommented AND regionMatches(thisLine, 1, i-2, "--", 0, 2))
282                    {
283                        if (regionMatches(thisLine, 1, i-3, "-", 0, 1))
284                        {
285                            endComment("CF");
286                        } else {
287                            endComment("HTML");
288                        }
289                    } else {
290                        if (variables.isCFSETTag) {
291                            endCFSET();
292                        } else if (variables.isActionscript) {
293                            //This is where a CDATA for AS ends
294                            variables.buffer.append("&gt;");
295                        } else if (variables.isSQL) {
296                            variables.buffer.append("&gt;");
297                        } else if (variables.isCFQueryTag) {
298                            endTag();
299                            startSQL();
300                        } else if (variables.isMXML) {
301                            endMXMLTag();
302                        } else {
303                            endTag();
304                        }
305                    }
306                }
307                else if (character EQ '"')
308                {
309                    if (variables.isTag OR variables.isCFScript OR variables.isActionscript)
310                    {
311                        if (NOT variables.isValue) {
312                            startValue();
313                            variables.buffer.append('"');
314                        } else {
315                            variables.buffer.append('"');
316                            endValue();
317                        }
318                    } else {
319                        variables.buffer.append('"');
320                    }
321                }
322                else if (character EQ '{')
323                {
324                    startBind();
325                    variables.buffer.append("{");
326                    endBind();
327                }
328                else if (character EQ '}')
329                {
330                    startBind();
331                    variables.buffer.append("}");
332                    endBind();
333                }
334                else if (character EQ '/')
335                {
336                    if ((variables.isCFScript OR variables.isActionscript) AND regionMatches(thisLine, 1, i+1, "/", 0, 1) AND NOT variables.isCommented)
337                    {
338                        if (variables.isActionscript) {
339                            startOneLineComment("MXMLCOMMENT");
340                            variables.buffer.append("/");
341                        } else {
342                            startOneLineComment("HTMLCOMMENT");
343                            variables.buffer.append("/");
344                        }
345                    }
346                    else if (variables.isCommented)
347                    {
348                        if (regionMatches(thisLine, 1, i-1, "*", 0, 1))
349                        {
350                            endComment("SCRIPT");
351                        } else {
352                            variables.buffer.append("/");
353                        }
354                    } else {
355                        if (regionMatches(thisLine, 1, i+1, "*", 0, 1))
356                        {
357                            startComment("SCRIPT");
358                        } else {
359                            variables.buffer.append("/");
360                        }
361                    }
362                }
363                else if (variables.isSQL AND character EQ '-')
364                {
365                    if (regionMatches(thisLine, 1, i+1, "-", 0, 1) AND NOT variables.isCommented)
366                    {
367                        startOneLineComment("SQLCOMMENT");
368                        variables.buffer.append("-");
369                    } else {
370                        variables.buffer.append("-");
371                    }
372                }
373                else if (variables.isSQL AND character EQ "'" AND NOT variables.isCommented)
374                {
375                    if (NOT variables.isValue) {
376                        startValue();
377                        variables.buffer.append("'");
378                    } else {
379                        variables.buffer.append("'");
380                        endValue();
381                    }
382                }
383
384                // straight up replacements
385                else if (character EQ '\t' OR character EQ '    ')
386                {
387                    variables.buffer.append("&nbsp;&nbsp;&nbsp;&nbsp;");
388                }
389                else if (character EQ ' ')
390                {
391                    variables.buffer.append("&nbsp;");
392                }
393                else if (character EQ '&')
394                {
395                    if (regionMatches(thisLine, 1, i+1, "##", 0, 1)) {
396                        variables.buffer.append("&");
397                    } else {
398                        variables.buffer.append("&amp;");
399                    }
400                } else {
401                    if (not variables.isCommented AND not variables.isValue and (i eq 0 OR NOT listcontainsnocase('a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,@', thisLine.substring(javacast('int',i-1),javacast('int',i))))) {
402                        keywordskip = 0;
403                        // would like this to be much more generic rather than checking "is"
404                        if (variables.isActionscript) {
405                            keywordskip = keywordsearch(thisLine,i,"Actionscript");
406                        } else if (variables.isCFscript or variables.isCFSetTag) {
407                            keywordskip = keywordsearch(thisLine,i,"CFscript");
408                        } else if (variables.isSQL) {
409                            keywordskip = keywordsearch(thisLine,i,"sql");
410                        }
411                        if (keywordskip) {
412                            i = i + keywordskip;
413                        } else {
414                            variables.buffer.append(character.toString());
415                        }
416                    } else {
417                        variables.buffer.append(character.toString());
418                    }
419                }
420            }
421            variables.buffer.append("<br />");
422        </cfscript>
423    </cffunction>
424    <cffunction name="keywordsearch" access="private" hint="This function searches for keywords." output="false">
425        <cfargument name="thisLine" type="any"/>
426        <cfargument name="i" type="numeric"/>
427        <cfargument name="parser" type="string"/>
428        <cfset var keywordmap = getConfig().getKeywordmap()/>
429        <cfset var keyword = listfirst(thisLine.substring(javacast('int',i)),' (')/> <!--- search starting from current position --->
430        <cfset var findkey = StructFindKey(keywordmap[parser], keyword)/>
431        <cfset var keywordtype = ""/>
432        
433        <cfif arraylen(findkey)>
434            <cfset keywordtype = findkey[1].value/>
435            <cfset variables.buffer.append("<span style='" & getStyle(keywordtype) & "'>" & keyword & "</span>")/>
436             <cfreturn keyword.length()-1/>
437        </cfif>
438        <cfreturn 0/>
439    </cffunction>
440    <cffunction name="regionMatches" access="private" hint="This function checks if a regionMatches." output="false">
441        <cfargument name="string1" type="any"/>
442        <cfargument name="caseInsensitive" type="boolean" default="true"/>
443        <cfargument name="startPosition1" type="numeric"/>
444        <cfargument name="string2" type="any"/>
445        <cfargument name="startPosition2" type="numeric"/>
446        <cfargument name="endPosition2" type="numeric"/>
447        <cfreturn arguments.string1.regionMatches(arguments.caseInsensitive, javacast('int',arguments.startPosition1), arguments.string2, javacast('int',arguments.startPosition2), javacast('int',arguments.endPosition2))/>
448    </cffunction>
449    <cffunction name="startHighlight" access="private" hint="" output="false">
450        <cfargument name="element" type="string"/>
451        <cfset variables.spansOpened = variables.spansOpened + 1/>
452        <cfset variables.buffer.append("<span style='" & getStyle(arguments.element) & "'>")/>
453    </cffunction>
454    <cffunction name="endHighlight" access="private" hint="" output="false">
455        <cfargument name="line" type="any"/>
456        <cfset variables.spansClosed = variables.spansClosed + 1/>
457        <cfset variables.buffer.append("</span>")/>
458    </cffunction>
459    <cffunction name="startOneLineComment" access="private" output="false">
460        <cfargument name="type" type="string"/>
461        <cfscript>
462        startHighlight(type);
463        variables.isOneLineComment=true;
464        variables.isCommented=true;
465        
</cfscript>    
466    </cffunction>
467    <cffunction name="endOneLineComment" access="private" output="false">
468        <cfscript>
469        endHighlight();
470        variables.isOneLineComment=false;
471        variables.isCommented=false;
472        
</cfscript>    
473    </cffunction>
474    <cffunction name="startComment" access="private" output="false">
475        <cfargument name="type" type="string"/>
476        <cfscript>
477        if (type  EQ  "CF"{
478            startHighlight("CFCOMMENT");
479            variables.buffer.append("&lt;");
480        } else if (type  EQ  "HTML"{
481            if (variables.isMXML) {
482                startHighlight("MXMLCOMMENT");
483            } else {
484                startHighlight("HTMLCOMMENT");
485            }
486            variables.buffer.append("&lt;");
487        } else {
488            if (variables.isActionscript) {
489                startHighlight("ACTIONSCRIPTCOMMENT");
490            } else if (variables.isSQL) {
491                startHighlight("SQLCOMMENT");
492            } else {
493                startHighlight("CFSCRIPTCOMMENT");
494            }
495            variables.buffer.append("/");
496        }
497        variables.isCommented=true;
498        
</cfscript>
499    </cffunction>
500    <cffunction name="endComment" access="private" output="false">
501        <cfargument name="type" type="string"/>
502        <cfscript>
503        if (type  EQ  "SCRIPT"{
504            variables.buffer.append("/");
505        } else {
506            variables.buffer.append("&gt;");
507        }
508        endHighlight();
509        variables.isCommented=false;
510        
</cfscript>
511    </cffunction>
512    <cffunction name="startTag" access="private" output="false">
513        <cfargument name="type" type="string"/>
514        <cfscript>
515        if NOTT variables.isCommented AND NOT variables.isValue) {
516            if (type  EQ  "CF"{
517                startHighlight("CFTAG");
518            } else if (type  EQ  "HTMLSTYLES"{
519                startHighlight("HTMLSTYLES");
520            } else if (type  EQ  "HTMLTABLES"{
521                startHighlight("HTMLTABLES");
522            } else if (type  EQ  "HTMLFORMS"{
523                startHighlight("HTMLFORMS");
524            } else if (type EQ "MXML"{
525                startHighlight("MXML");
526            } else if (type EQ "ACTIONSCRIPTTAG"{
527                startHighlight("ACTIONSCRIPTTAG");
528            } else { // type is HTML
529
                startHighlight("HTML");
530            }
531            variables.isTag=true;
532        }
533        variables.buffer.append("&lt;");
534        
</cfscript>
535    </cffunction>
536    <cffunction name="endTag" access="private" output="false">
537        <cfscript>
538        variables.buffer.append("&gt;");
539        if NOTT variables.isCommented AND NOT variables.isValue) {
540            endHighlight();
541            variables.isTag=false;
542        }
543        
</cfscript>
544    </cffunction>
545    <cffunction name="startValue" access="private" output="false">
546        <cfscript>
547        if NOTT variables.isCommented) {
548            if (variables.isCFSETTag OR variables.isCFScript) {
549                startHighlight("CFSCRIPTVALUE");
550            } else if (variables.isActionscript) {
551                startHighlight("ACTIONSCRIPTVALUE");
552            } else if (variables.isMXML) {
553                startHighlight("MXMLVALUE");
554            } else if (variables.isSQL) {
555                startHighlight("SQLVALUE");
556            } else {
557                startHighlight("VALUE");
558            }
559            variables.isValue=true;
560        }
561        
</cfscript>
562    </cffunction>
563    <cffunction name="endValue" access="private" output="false">
564        <cfscript>
565        if NOTT variables.isCommented) {
566            endHighlight();
567            variables.isValue=false;
568        }
569        
</cfscript>
570    </cffunction>
571    <cffunction name="startBind" access="private" output="false">
572        <cfscript>
573        if NOTT variables.isCommented) {
574            startHighlight("BIND");
575        }
576        
</cfscript>
577    </cffunction>
578    <cffunction name="endBind" access="private" output="false">
579        <cfscript>
580        if NOTT variables.isCommented) {
581            endHighlight();
582        }
583        
</cfscript>
584    </cffunction>
585    <cffunction name="startCFSET" access="private" output="false">
586        <cfscript>
587        if NOTT variables.isCommented) {
588            startHighlight("CFSET");
589            variables.isCFSETTag=true;
590        }
591        
</cfscript>
592    </cffunction>
593    <cffunction name="endCFSET" access="private" output="false">
594        <cfscript>
595        if NOTT variables.isCommented) {
596            endHighlight();
597            variables.buffer.append("&gt;");
598            endHighlight();
599            variables.isCFSETTag=false;
600        } else {
601            variables.buffer.append("&gt;");
602        }
603        
</cfscript>
604    </cffunction>
605    <cffunction name="startMXMLTag" access="private" output="false">
606        <cfscript>
607        if NOTT variables.isCommented) {
608            startHighlight("MXMLATTRIBUTES");
609            // TODO: Add in MXML Value colors.
610
            // setStyle("VALUE","color:##900");
611
            variables.isMXML=true;
612        }
613        
</cfscript>
614    </cffunction>
615    <cffunction name="endMXMLTag" access="private" output="false">
616        <cfscript>
617        if NOTT variables.isCommented) {
618            endHighlight();
619            variables.buffer.append("&gt;");
620            endHighlight();
621            // TODO: Add in MXML Value colors.
622
            // setStyle("VALUE","color:##0000CC");
623
            variables.isMXML=false;
624        } else {
625            variables.buffer.append("&gt;");
626        }
627        
</cfscript>
628    </cffunction>
629    <cffunction name="startCFScript" access="private" output="false">
630        <cfscript>
631        if NOTT variables.isCommented) {
632            endHighlight();
633            startHighlight("CFSCRIPT");
634            variables.isCFScript=true;
635        }
636        
</cfscript>
637    </cffunction>
638    <cffunction name="endCFScript" access="private" output="false">
639        <cfscript>
640        if NOTT variables.isCommented) {
641            endHighlight();
642            variables.isCFScript=false;
643        }
644        
</cfscript>
645    </cffunction>
646    <cffunction name="startActionscript" access="private" output="false">
647        <cfscript>
648        if NOTT variables.isCommented) {
649            endHighlight();
650            startHighlight("ACTIONSCRIPT");
651            variables.isActionscript=true;
652        }
653        
</cfscript>
654    </cffunction>
655    <cffunction name="endActionscript" access="private" output="false">
656        <cfscript>
657        if NOTT variables.isCommented) {
658            variables.isActionscript=false;
659        }
660        
</cfscript>
661    </cffunction>
662    <cffunction name="startSQL" access="private" output="false">
663        <cfscript>
664        if NOTT variables.isCommented) {
665            variables.isSQL=true;
666        }
667        
</cfscript>
668    </cffunction>
669    <cffunction name="endSQL" access="private" output="false">
670        <cfscript>
671        if NOTT variables.isCommented) {
672            variables.isSQL=false;
673        }
674        
</cfscript>
675    </cffunction>
676    
677    <!--- configuration methods --->
678    <cffunction name="setConfig" access="public" hint="This sets the coldfish configuration object for the parser to use." output="false">
679        <cfargument name="config" type="any"/>
680        <cfset variables.coldfishconfig = config/>
681    </cffunction>
682    <cffunction name="getConfig" access="public" hint="This sets the coldfish configuration object for the parser to use." output="false">
683        <cfargument name="config" type="any"/>
684        <cfreturn variables.coldfishconfig/>
685    </cffunction>
686    <cffunction name="getStyle" access="private" hint="This function can be used to get the style used in conjunction with a type of language element." output="false">
687        <cfargument name="element" type="string"/>
688        <cfreturn getConfig().getStyle(element)/>
689    </cffunction>
690    <cffunction name="getInitialParser" access="private" hint="You can set the initial parser state with this.  This is helpful for scripts that make initial parsing impossible (ie. Script, Actionscript)" output="false">
691        <cfreturn getConfig().getInitialParser()/>
692    </cffunction>
693    <cffunction name="getKeywordmap" access="private" hint="You can set the keywordmap with this." output="false">
694        <cfreturn getConfig().getKeywordMap()/>
695    </cffunction>
696</cfcomponent>

I'd like to extend a special thanks to Ray Camden & Jason Delmore for their prompt replies and expeditious changes ... Much Appreciated.

How to Get Thousands of Quality Links in One Minute

The first thing you need to know about getting top rankings in Google is that you need to have quality content - so when you get Google's traffic you can actually generate business from it - then you need Inbound Links to get you to the first position. So, for those of you that just want to know how you can get those oh so coveted links, read quick and I'll show you how to get thousands of quality links in one minute.

You Need to Get Inbound Links for the Keywords You Want to Rank For

Okay - this may seem a bit oversimplified - but it's not really. Finding link partners is really pretty simple. Simple I mean like walking to New York from Miami. It's not a difficult concept to grasp, but it takes time to get there ... so, let's get started.

1

Go into Google and Search for the keyword that you most want to rank for and then copy the link location, (Right Click and then Copy Link Location, Copy Shortcut or Copy Link Address) to the first page, first position listing on the results page. For example, if we want to rank for Lawyer Directory, we would search Google for Lawyer Directory and simply copy the address to the top ranking site. (Not too difficult - eh?)

2

Next we are going to open a new tab in your browser. It doesn't matter which browser you have, the shortcut for "open a new tab" is CTRL+T in Windows or CMD+T in Mac for Firefox, Opera, Chrome and even Internet Explorer, I am using Firefox because I'm addicted to it ... but it really doesn't matter so go ahead and open a new tab ...

3

Then we are going to go the address for Site Explorer in Yahoo! (http://siteexplorer.search.yahoo.com/) - You can either highlight the address that's currently in your browser by hovering over the address area with your mouse and clicking or you can do it like a pro and learn the shortcut for highlighting the address area in your browser of choice. I bet CTRL+L in Windows or CMD+L in Mac are what you're looking for, so either type in the address for Yahoo's! Site Explorer or be a whiz kid and get there through the nifty little shortcut you just learned.

4

Once you've gotten to Yahoo's! Site Explorer simply paste in the URL to site that is ranking in Google for your keyword and click Explorer URL.

5

Now that we have access to your competitors information courtesy of Yahoo! We only need to retrieve the Inbound Link Data. In order to get just that, we have to click on the Inlinks Tab ...

6

Since we now have access to the info for the Inbound Links, we want to sort the data so that it only shows information on Inbound Links from other sites. We don't need to know if our competitors' site links to itself as they probably wouldn't be a very good link partner for us ... so we need to select "Except from this Domain" from the "Show Inlinks" dropdown list.

7

If you're still with me thus far, (a quick study shouldn't be more than about thirty seconds into this ...) you're doing great and just a few more steps to dominating the SERP's ... Now what we need to do is Grab All the Inbound Link Data. To do that, we are going to click on Export first 1000 results to TSV to download your competitors' link info as a .tsv file. The .tsv format is simply a text format that uses a tab as the delimiter - hence the name Tab Separated Values.

8

Okay ... the file you are downloading contains all of your competitors' Inbound Link Data, but to make this information easy to work with we need to massage it a little. If you have Excel this is a breeze, if not - well, you may have some luck with Calc from Open Office.What we need to do now is save the .tsv file. When you download the file, (which should be named 'url_inlinks.tsv') you need to save it to either your desktop or a place that you will be able to easily find it - unlike your browsers' temporary folder ... eh hem.

9

The next step is to simply open up Excel or Calc and then import the file into a more readable and manageable format. So, Open up Excel and Select the Data Tab.

10

Now we want to import the data from our 'url_inliks.tsv' file. So with the Data Tab active, navigate to the far left hand side of your Excel window and select Get External Data and then select From Text.

Now once you've selected the From Text button in Excel the 'Import Text File' dialogue box will open up. You need to select All Files (*.*) from the Files of Type Dropdown List and navigate to where you stored the file. I simply stored mine on the desktop for now ...

Now the Text Import Wizard will open up ... and for simplicity I'm only going to show one diagram here.

  • Text Import Wizard - Step One: All you have to do is select Delimited as the data type and click next.
  • Text Import Wizard - Step Two: Since the format is .tsv, the Delimiter should be automatically set to Tab but if it's not, check the radio button for Tab and click next.
  • Text Import Wizard - Step Three: You shouldn't have to anything here except click Finish.

If Excel wants you to select an Area or a New Sheet, just select Cell A1 in the top left corner and that's it! I like to get rid of all the Title information as it really doesn't do me much good ... so I clean up my spreadsheets a little by simply deleting the A column ...

If you did everything correctly you should have up to a thousand highly targeted links for your primary keyword. I hope this helps you and Good Luck with your link campaign!

Link Building Articles for Link Builders

The title, Link Building Articles for Link Builders, pretty much says exactly what it should. Over the past few years I've collected some of the most influential articles available on the subject of link building. Though it's not a complete list, I think there's enough about link building here to keep even a pro busy for quite a while. If you feel that you can contribute to the list leave me a comment and I'll check it out ...

A Linking Campaign Primer

Backlinks: The Beginner's Guide to Backlink Theory

Link Building from A to Z

LinkMoses Linking Commandments

Professional's Guide to Link Building

Link Building 101 - The Almost Complete Link Guide

Link Building with the Experts

Up Close Look at Eric Ward's Link Building Desktop

Advanced Link Building Strategies

The Enormous Link Baiting Articles List

Link Building Strategies: 69 Solid Tactics

101 Ways to Build Link Popularity

131 (Legitimate) Link Building Strategies

Link Baiting: Which Hook Attracts the Right Fish?

Market Research for Link Building - Who You Can Get Links From

Matt Cutts Interviewed by Eric Enge

Eric Enge Interviews Eric Ward

How Google Finds Your Needle in the Web's Haystack

The Google Pagerank Algorithm and How It Works

Matt Cutts on PageRank sculpting

Over 125 Legitimate Link Building Strategies

.edu Link Fallacies Explained

Are You A Link Whore?

Linking's Holy Grail: The Passively-Obtained Backlink

Looking for Links In All The Wrong Places

What Makes a Web Site Link-Worthy?

Linking Mistakes To Avoid, Part 1 - Link Optimization and Short URLs

Linking Mistakes To Avoid, Part 2 - Removing Orphaned URLs

Why Reciprocal Links Will Always Be Viable

What If Everything You Know About Link Building Is Wrong?

Riding The Twitter Link Waves

How Link Signals Can Be Misunderstood

Link Building's Glass Ceiling

8 Ways Backlink Analysis Can Offer Competitive Intelligence

10 Commandments of Link Building

10 Goals For Link Building Campaigns: Moving Beyond "Get More Links"

11 Experts on Link Development Speak Out

12 Different Types of Links and How To Get Them

17 Ways Search Engines Judge the Value of a Link

21 Link Builders Share Advanced Link Building Queries

Jim Westergren - Link Building Guide

Website Content & Content Writing: Does Quality Content Really Matter?

Understanding Your Websites' Audience is Critical to Marketing Your Website

One of the most common beliefs held by many SEO experts is that content is king. I also hold this belief. However, as popular as the view is, I'm surprised at the amount of people involved in search marketing initiatives that discount website content as simply a means to an end - text that's essentially necessary to make the website appear 'professional.' In more than a few occasions I've had clients that practically refused to add content because they feel their site should communicate their message through its images and branding. Based on that premise, they want to focus on link building to improve their sites keyword rankings and landing page optimization to increase the sites conversion ratios.

So Does Website Content Really Matter?

This issue of which marketing initiative to approach, brings us to one of the most controversial subjects in the SEO industry - Content -vs- Links. I really try not to argue here because I find the question essentially to be parallel to asking if a cars transmission or engine is more important. The answer here should be self evident. However, it's not. In my humble opinion there's no right or wrong answer. I think the important question is really whether your website communicates the message required to affect the desired result. What may be effective for one website may not be for another. I feel that the key to effective website marketing is in understanding how to communicate to your audience and knowing which marketing initiative to take to communicate that message effectively. In some cases content is of the utmost importance and inbound links are simply required to obtain rankings - in other cases just the opposite holds true - inbound links are top priority and website content is simply not a major requirement. What is truly important is in knowing which marketing initiative to take.

Effective Communication is the Key to Website Marketing

In order to determine the most effective marketing strategy for a website the single most important question that needs to be answered is: What are you attempting to communicate through the website? Once that question is answered, you can consider the available options to get that message across and create a marketing campaign from there. Sounds simple right? Well, in concept it is. However, determining the most effective campaign requires a bit of insight into the type of communication needed. As a rule of thumb I generally find that service based websites have a stronger requirement to focus on the quality of content than consumer and retail based websites. The reason for this is quite simple and has little if anything to do with websites. This matter is actually based on the type of industry - not the type of website. Most service based industries do not have a visible, tangible product. As such, content is typically required to express a position of value for the service whereas retail based websites such as one that sells consumer electronics or mobile phones, would generally want to focus on communicating the value of the product or the products' brand which, doesn't always require words to express.

Google Site Preview in Search Results

I was taking a look on line and noticed that Google's waxing experimental again ... this time with site preview in the search engine results pages ... Now I can see how this would be beneficial - Let's keep people from having to go back and forth from Google results to site 1 back to the results and then site 2 ... This is pretty cool ...

Good Call Google ... I'm all for it. Much better in my book than the 'Google Instant' idea.

WordPress Thesis Theme Customization - Adding a Custom XHTML Sitemap

The Thesis Theme for WordPress - One Powerful WordPress Framework

Lately I've been learning all I can on leveraging the functionality of the Thesis theme for WordPress. When I first heard about the versatility and power of Thesis in a blog post by Rae Hoffman, I was immediately interested in what benefits I could offer my customers that opted to have me design and build them a custom WordPress site. Having customized and hacked several of Chris Pearson's WordPress themes in the past, I figured I should just go for it and purchase the Thesis developer theme - Chris' greatest accomplishment thus far.

Wow Thesis is Sophisticated - There's a Lot to Learn

I have to admit, when I first took a look into the core of the Thesis framework, I was a bit intimidated - Thesis was nothing like I expected under the hood. First off, Thesis comes with lots of customization options right out of the box ... [Take a look here] So, getting to know what was available from the core install was quite an undertaking in itself. The good news is, when you purchase Thesis, you not only get a lifetime subscription to the theme, you also get the exceptional tech support of the Thesis designer / developer community. The support community is always available to help you along the way as you learn how to negotiate the Thesis framework.

Some Folks Just Can't Leave Well Enough Alone

I'm definitely not the kind of guy that is happy with being 'okay'. If there's a way to make something better, stronger or faster - then that's what I'm gonna' try to do next. So, when I saw that there wasn't a simple way of making custom page templates in Thesis - I knew that I needed to set out to tackle that issue. One of the first things I wanted to do in my own Thesis themes, was to create and XHTML sitemap like some other WordPress themes had. In the past, I would simply create a custom page template for my sitemap page and then rip out and modify the code from a theme that I admired. Simple. However, in Thesis things aren't so easy. First of all, the Thesis was of customizing pages is to make all your custom changes to pages that won't be affected in future upgrades. Thesis does so by offering customization through manipulating two files; styles.css, custom_functions.php, both of which are available under the theme's custom folder. However, most of the customization are actually 'hooked' in to the framework by creating your own custom functions. The old way of simply creating a new template and then assigning it to a page or post won't work with Thesis.

On With The Show - Classes - Object Oriented Customizations

So basically I had to answer the question ...

How Can I Create Sophisticated Customizations and Minimalize Negative Effects?

After searching online, I finally found an answer to my problem. Creating Custom Classes. In Gary Jones' tutorial in creating an XHTML sitemap for Thesis, I recognized the ultimate solution to customizations in Thesis - leveraging the Object Oriented nature of the Thesis framework. Gary basically makes all customizations in a custom classes file as in this example for an XHTML sitemap. Following Gary's example, we create a file for our new class entitled GT_Sitemap.php, and place it in a directory named classes which is located in under our Thesis custom directory.

view plain print about
1<?php
2/**
3* Allows XHTML sitemap to be added
4*
5* @package GT_Sitemap
6* @author Gary Jones 
7* @version 2010-05-19
8* @since 2010-03-20
9*/

10
11class GT_Sitemap  {
12 /**
13  * @var string
14  */

15  protected $_pagesText;
16 /**
17  * @var string
18  */

19  protected $_postsText;
20 /**
21  * @var string
22  */

23  protected $_archivesText;
24 /**
25  * @var int
26  */

27  protected $_headingLevel;
28 /**
29  * @var array
30  */

31  protected $_order = array();
32 /**
33  * @var bool
34  */

35  protected $_showPageDate;
36 /**
37  * @var string
38  */

39  protected $_showPostDate;
40 /**
41  * @var bool
42  */

43  protected $_showPostCount;
44 /**
45  * @var string
46  */

47  protected $_archivesType;
48 /**
49  * @var string
50  */

51  protected $_pagesDateFormat;
52 /**
53  * @var string
54  */

55  protected $_postsDateFormat;
56 /**
57  * @var string
58  */

59  protected $_customPagesQuery = '';
60 /**
61  * PHP4 compatible constructor
62  */

63  public function GT_Sitemap() {
64  if(version_compare(PHP_VERSION,"5.0.0","__construct")) {
65  register_shutdown_function(array($this,"__destruct"));
66  }
67  }
68 /**
69  * PHP5 constructor, setting defaults
70  */

71  public function __construct() {
72 $this->
_pagesText = 'Pages';
73  $this->
_postsText = 'Posts';
74  $this->_archivesText = 'Monthly Archives';
75  $this->_headingLevel = 3;
76  $this->_order = array('pages', 'posts', 'archives');
77  $this->_showPageDate = true;
78  $this->_showPostDate = 'published';
79  $this->_showPostCount = true;
80  $this->_archivesType = 'monthly';
81  $this->_pagesDateFormat = get_option('date_format');
82  $this->_postsDateFormat = get_option('date_format');
83  $this->_customPagesQuery = '';
84  }
85 /**
86  * @param string $id
87  */

88  public function setPagesText($id) {
89  $this->_pagesText = $id;
90  return $this;
91  }
92 /**
93  * @param string $id
94  */

95  public function setPostsText($id) {
96  $this->_postsText = $id;
97  return $this;
98  }
99 /**
100  * @param string $id
101  */

102  public function setArchivesText($id) {
103  $this->_archivesText = $id;
104  return $this;
105  }
106 /**
107  * @param array $id
108  */

109  public function setOrder($arg1, $arg2 = null, $arg3 = null) {
110  $this->_order = func_get_args();
111  return $this;
112  }
113 /**
114  * @param int $id
115  */

116  public function setHeadingLevel($id) {
117  $this->_headingLevel = $id;
118  return $this;
119  }
120 /**
121  * @param string $id
122  */

123  public function setPageDateFormat($id) {
124  if ( 0 === func_num_args() ) {
125  $this->_showPageDate = '';
126  } else {
127  $this->_pagesDateFormat = $id;
128  }
129  return $this;
130  }
131 /**
132  * @param string $id
133  */

134  public function setPostDateFormat($id) {
135  if ( 0 === func_num_args() ) {
136  $this->_showPostDate = '';
137  } else {
138  $this->_postsDateFormat = $id;
139  }
140  return $this;
141  }
142 /**
143  * @param string $id
144  */

145  public function setDateFormat($id) {
146  $this->setPageDateFormat($id);
147  $this->setPostDateFormat($id);
148  return $this;
149  }
150 /**
151  *
152  */

153  public function hidePostCount() {
154  $this->_showPostCount = false;
155  return $this;
156  }
157 /**
158  * @param string $id
159  */

160  public function setArchivesType($id) {
161  $archiveTypes = array('yearly', 'monthly', 'daily', 'weekly', 'postbypost', 'alpha');
162  if ( in_array($id, $archiveTypes) ) {
163  $this->_archivesType = $id;
164  $this->setArchivesText(substr_replace($id, strtoupper(substr($id, 0, 1)), 0, 1) . ' Archives');
165  }
166  return $this;
167  }
168 /**
169  * @param string $id
170  */

171  function setCustomPagesQuery($id) {
172  $this->_customPagesQuery = $id;
173  return $this;
174  }
175 /**
176  * @param string $shortcode The shortcode keyword that will be used to output the sitemap
177  */

178  public function shortcode($shortcode) {
179  add_shortcode( $shortcode, array(&$this, 'build') );
180  }
181 /**
182  * Does the main work of creating the output
183  */

184  public function build() {
185  foreach ($this->_order as $section) {
186 if ( 'pages' === $section ) {
187  $output .= '<h' . $this->_headingLevel . '>' . $this->_pagesText . '</h' . $this->_headingLevel . '>' . "\n"
188  . '<ul>' . "\n" . wp_list_pages('echo=0&show_date=' . $this->_showPageDate . '&date_format=' . $this->_pagesDateFormat . '&title_li=&' . $this->_customPagesQuery) . '</ul>' . "\n";
189  }
190 if ( 'posts' === $section ) {
191  $output .= '<h' . $this->_headingLevel . '>' . $this->_postsText . '</h'. $this->_headingLevel . '>'."\n"
192  . '<ul>' . "\n" . $this->_posts_by_category() . '</ul>' . "\n";
193  }
194 if ( 'archives' === $section ) {
195  $output .= '<h' . $this->_headingLevel . '>' . $this->_archivesText . '</h'. $this->_headingLevel . '>' . "\n"
196  . '<ul>' . "\n" . wp_get_archives('type=' . $this->_archivesType . '&echo=0&show_post_count=' . $this->_showPostCount). '</ul>' . "\n";
197  }
198  }
199  return $output;
200 }
201 protected function _posts_by_category() {
202  global $wpdb, $post;
203  $tp = $wpdb->prefix;
204  $sort_code = 'ORDER BY name ASC, post_date DESC';
205  $the_output = NULL;
206  $last_posts = (array)$wpdb->get_results("SELECT {$tp}terms.name, {$tp}terms.term_id, {$tp}term_taxonomy.term_taxonomy_id    FROM {$tp}terms, {$tp}term_taxonomy    WHERE {$tp}terms.term_id = {$tp}term_taxonomy.term_id AND {$tp}term_taxonomy.taxonomy = 'category'");
207  if (empty($last_posts)) {
208  return NULL;
209  }
210  $the_output .= '';
211  $used_cats = array();
212  $i = 0;
213 foreach ($last_posts as $posts) {
214  if (in_array($posts->name, $used_cats)) {
215  unset($last_posts[$i]);
216  } else {
217  $used_cats[] = $posts->name;
218  }
219  $i++;
220  }
221  $last_posts = array_values($last_posts);
222 foreach ($last_posts as $posts) {
223  $the_output .= '&lt;li&gt;&lt;a href="' . get_category_link($posts->term_id) .' "&lt;strong&gt;' . apply_filters('list_cats', $posts->name, $posts) . '&lt;/strong&gt;&lt;/a&gt;&lt;ul&gt;';
224  
225  $arcresults = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' AND ID IN (SELECT object_id FROM {$tp}term_relationships, {$tp}terms WHERE {$tp}term_relationships.term_taxonomy_id =" . $posts->term_taxonomy_id . ") ORDER BY post_date DESC");
226  
227  foreach ( $arcresults as $arcresult ) {
228  $the_output .= '&lt;li&gt;&lt;a href="' . get_permalink($arcresult->ID) . '"&gt;' . apply_filters('the_title', $arcresult->post_title) . '&lt;/a&gt; ';
229  if ($this->_showPostDate) {
230  $the_output .= date($this->_postsDateFormat,strtotime($arcresult->post_date));
231  }
232  $the_output .= '&lt;/li&gt;';
233  }
234  $the_output .= '&lt;/ul&gt;&lt;/li&gt;';
235  }
236  return $the_output;
237  }
238  }
239  ?>

Then, we simply add the next three lines of code in our custom_functions.php file:

view plain print about
1require_once 'classes/GT_Sitemap.php'; 
2  $sitemap = new GT_Sitemap;
3  
4  $sitemap->
shortcode('sitemap');

The first line simply includes our custom class file. The second line then instantiates a new sitemap object and third, we assign the variable $sitemap to the shortcode 'sitemap' so that all we need to do is to add the shortcode in the body of a new page or post and voila' - we have a new sitemap.

Note: If you wish to implement this code, I had to modify several lines from the code I found on Gary's site - In a comparison with Gary's code, you'll see there are several differences. Apparently Gary made some changes to the curr