Alfresco Edit/Preview behind firewall

Posted by stephen on November 4th, 2008

After puting our servers behind a new Cisco firewall, we ran into a problem with the Alfresco Virtualization Server where you could either edit and not preview, or preview and not edit. Editing was only an issue where the Web Form content type was pulling in files on the AVM drive. In this case it was an included XSD.

The reason for this is that the preview goes out to ip.alfrescodemo.net to resolve the URL, which externally accesses the virtual server on port 8180. When you click edit, the IP in virtual-server.properties is used to access the AVM drive externally. With a strong security model, that’s obviously not going to happen. So, when I changed the virtual server IP to the local 192.168 base, editing worked, but previewing didn’t. With the public IP, it was the opposite.

Even allowing access to all ports for specific IP’s wasn’t working - still not sure on why that is. Adding the public IP to the Advanced TCP/IP settings of the box

It’s not clear yet whether this causes conflicts with other setups, but it did the trick for us! Editing and previewing works like a charm.

This is the solution for KTBU-21.

Website Core Toolkit (Standard)

Posted by stephen on October 26th, 2008

This framework is used for sites with the ability to be managed through Adobe Contribute. Adobe Dreamweaver will be used as the primary HTML production/site management tool.

File Naming and Directory/File Structure

File Naming

It is imporant to have a consistent file naming convention. I have had too many hang-ups caused by capitalization, so I opt to use all lower case characters, with dashes as seperators. Keep the name from 1 to 5 reasonably sized words. We want them to be understandable, but not clunky.

Root Directories

Being familiar with a common structure in your sites can save alot of time when working with all of the files. First we need our core directories, whos files will be used throughout the site.

  • /common/All site-wide CSS, Javascript (JS), image, and include resources should be placed here, respectively.
    • /common/css/
    • /common/images/
    • /common/include/
    • /common/js/
  • /templates/Dreamweaver watches the .dwt files in this directory and updates the dependant pages as neccessary.

Contextual Directories

Each of our sections is placed in its own directory, including the Home Page. A consistent directory structure is most helpful to a tool like jQuery.navActives in finding direct, parental, and child matches. Descriptive folder/file names also help with a number of things, including search indexing. The following is a example directory structure with a given set of sections:

  • Home Page/home/
  • About Us/about/
  • Products and Services/products-resources/

Each section/sub section directory should have /images/ and /documents/ folders. This keeps the images and documents used by that section local to those pages, and more mobile. This is also an Adobe Contribute default location for images or docs placed in a page by a content editor.

Head Resources and Template Content

Head Resources

The head resources are anything that will go in the <head> tag of the page. It is a good practice to have at least one site-wide resource file that is included in your base template. In this framework, that file is at /common/include/resources.htm. It includes site-wide meta tags, CSS <link> tags, JS <script> tags, and javascript init code such as a jQuery document.ready function.

Template Structure

I usually start with a base template, located at /templates/base.dwt. This defines the header, footer, and main area of the page where the other templates will be nested.

Header and Footer

Reusability and efficiency are key to a proper framework, so I use Server Side Includes (SSI) wherever appropriate and possible. The header and footer are prime examples. Even with Dreamweaver Templates, updating static HTML in a .dwt file would require updating each individual dependant page. By using include files, I can edit one file and the change is reflected wherever that file is included. This saves alot of time when file transfer is involved, and leaves less room for error. The header and footer are located at /common/include/header.htm and /common/include/footer.htm.

CSS and Javascript

CSS Stylesheets

ID selectors should generally be [A-z][1-9] characters only, and class selectors should be seperated by dashes, with no caps (like our file naming convention). An example of a selector with an ID and class name is:

#siteContainer .container-inner{}

IE does not recognize @import media types, so stylesheets with a specific media type need to be defined in the <head>.

I need to do some testing on the @media CSS encapsulator. If that works, media type defnition can be handled from within relevant stylesheet and all CSS references can be made from within site.css, but until then…

  • site.cssContains @import references to all primary style sheets. By default, the following:
    • base.cssContains resets and other base CSS properties for default rendering.
    • structural.cssContains styles for things like header, footer, page layouts.
    • modules.cssContains styles for content modules like secondary nav, sidebars, content containers, or the child elements thereof.
    • contribute.cssFor sites managed with Contribute only, this file should only list selector names of styles you want made available to Contribute editors. Allow properties to inherit from the other stylesheets for maintainability.
  • axs.cssContains styles for accessibility. Minimal testing has been done with this stylesheet, but I make it available in case it’s needed.
  • print.cssContains styles for print media.
  • ie.cssThis is referenced via conditional comment tags recognized only by IE. (e.g. <!–[IF IE]> <![endif]–>).

Javascript

The file at /common/js/site.js holds common functions or variables used throughout the site. For instance, this is where the indexOf() function is defined for IE.

SWFObject

Ever since the “click to activate” Active X update was made to IE, I’ve used SWFObject. I still prefer it to the ActiveContent.js generated by Flash and Dreamweaver. An example is at /samples/flash.html.

jQuery

The jQuery library is an essential part of this toolkit. At first I was afraid these JS libraries would complicate markup and create even more cross-browser issues. Anyone who’s worked with JS knows the struggle. But Unobtrusive Javascript libraries like jQuery seem to have a good handle on those issues, and I’m becoming increasingly comfortable with this black magic. Errors are handled gracefully, browser issues are minimal, and with their selector syntax, it does not complicate the markup at all. That being said, here are several of the core plugins I use and why:

  • jquery.meshtml I created this to mesh a string of HTML and existing element(s) on the page. Primarily used for arbitrary elements needed for advanced styling, such as complex containers and rounded corner containers.
  • jquery.selectorInspectorI created this to quickly generate CSS selectors based on the hierarchy of any given HTML. The indentation of the selectors respects that hierarchy, and you can step through each selector to confirm its specificity.
  • jquery.navActivesI created this tool to examine a specified list of anchor tags and compare them to a given URL, and return a list of parent, child, and exact matches.
  • jquery.navigenI’ve not created this yet. It’s purpose will be to create single or multi-level navigation out of unordered lists. It will use meshtml for the required element structure and navActives to handle active, parent and child links.

  • jquery.selecteSizerThis fixes the problem with IE not expanding the dropdown list so that the entire option is visible.

jQuery.navActives - Navigation Highlighting

Posted by stephen on October 26th, 2008

Nav highlighting can be a little tricky. It usually gets tricky when there is more than one level of secondary nav.

How do we know to hide or show sublinks, and how do we know when to highlight an associated “Overview” link? Or, what if your page is not in the left nav links, but you still want to highlight its parent? The list of caveats grows as you try to answer those questions, so I set out to make something that applies to these squirrely situations, instead of having to write a custom function each time.

jQuery.navActives scans through a specified list of links and finds the clostest matches to a given url (generally the current address - window.location.href).

Usage

j("#yourlinkcontainer a").navActive(options, callback(this, activeLinks, highestMatch));

The call back function is passed 3 parameters. The jQuery object calling the callback (this), an array of the matching links (activeLinks), and the highest match rigidity found (highestMatch).

Like my other plugins, we need to pass it some settings. Here’s an example of what I use for some primary navigation:
var mainNavHighlight = {
matchUrl:currentPageUrl,
alterElements: [{element:"each", className:"active"}],
rigidity:[1]
};
j(”div#siteHeader a”).navActives(mainNavHighlight);

Notice the rigidity. That is basically the number of items past the main URL to compare. That is one reason I have the Home Page in a “/home/” directory.

It is important that you organize ALL sections and sub sections in their own folder. Here’s a complex example of a navigation list that has parent and sub lists:

var sideNavHighlight = {
matchUrl:currentPageUrl,
alterElements: [{element:"each", className:"current"},
{element:"each.parents('ul:first').parent().children('a')", className:"current"},
{element:"each.siblings('ul:first').find('a:first')", className:"current"}],
rigidity:[1,2,3]
};
j(”div#sideNav a”).navActives(sideNavHighlight, showActiveSubs);
function showActiveSubs(i, list, high){
jQuery.map(list, function(n){
if(n.rigidity>=2){
jQuery(n.link).parents(”ul”).css(”display”,”block”);
}
});
}

Notice the alterElements setting, the rigidity, and the showActiveSubs function that uses the list of matched URLs returned by navActives.

jQuery.selectorInspector - Modular CSS With Indentation

Posted by stephen on October 26th, 2008

This tool allows you to select a block of HTML, then customize CSS selectors for each of the child elements. The resulting block of CSS is considered “modular”, in that the corresponding HTML must follow a particular structure. Yes, this is already the basic concept behind CSS selectors, but stylesheet selectors tend to be much more vague and unorganized. This allows you to control and recognize the scope of styles much more easily.

This tool also makes use of jQuery.paneSizer.

jQuery.paneSizer

Posted by stephen on October 26th, 2008

This plugin was created to be used with jQuery.selectorInspector. The following example has not been simplified to showcase paneSizer.

This tool could use considerable improvement  on following the mouse, but I was having some glitches using the UI resizables from jQuery.

jQuery.selecteSizer - a fix for IE cutting off select dropdowns

Posted by stephen on October 23rd, 2008

You may have seen this before…you have select dropdowns that are set to a certain width in accordance to the design. Anyone using IE will click the dropdown, and if any of the option items are wider than the select element’s width, they’re cutoff. This can be extremely hindering where you have a select dropdown of products or resources that all begin with the same ~20 characters. Some people just want to see the full option, too.

I’ve only found one, semi-elegant solution, and that is resizing the select container to “width:auto” on the focus event, and setting it back to its original size on the blur (unfocus) event. You also need to toggle the position to absolute and set its position so it shows up in the correct spot.

I created jQuery.selecteSizer to do this automatically on all specified selects.

Example Usage

if(j.browser.msie){
j("select").selecteSizer();
}

com.esiteful.debug.localTrace

Posted by stephen on October 16th, 2008

Since the ability to post to firebug’s console has been available, I’ve loved taking advantage of it. I created this debug function in order to trace errors to the Flash console with trace(myMsg), and to the Firebug console with ExternalInterface.call(”console.log”, myMsg). Here are the parameters localTrace accepts and their defaults:
localTrace(localTrace(traceMsg, debugMode=1, debugLvl=1, jsAlert=false);

  • traceMsg is the message you want to send to the console.
  • debugMode is the debug status of the referencing object.
  • debugLvl is the priority of the error message.
  • jsAlert tells the function whether or not to show the message as a javascript alert.
    (useful if your browser does not have a console)

traceMsg is the only required parameter, meaning you can use this function by just calling localTrace(”test message”).

Example Usage

In the referencing timeline actions or class, add an import line for the function.

import com.esiteful.debug.localTrace;

Create a variable called debugMode and set it to something between 1-5 (you can use however many numbers you’d like, but I generally don’t use more than 5).

var debugMode:int = 3;

Now make a call to localTrace(). I usually have a trace at the top of each of my functions so I know when they’re fired, but I obviously don’t always want these to show, so I give them a debug level or 2 (or higher, depending on their repetitivity).

I give error message that are caught in a try/catch a priority of 1. So, here’s a sample of debugging a simple function.

import com.esiteful.localTrace;
var debugMode=3;
function awesomeLogic(logicString){
try{
localTrace("[awesomeLogic("+logicString+")]“, debugMode, 2);
//put your logic here
}catch(err:Error){
localTrace(”Error at awesomeLogic\n”+err, debugMode, 1);
}
}

I couldn’t get the above quotes to show up correctly for the life of me…guess it’s about time to look for a good code container for these examples…

If this function is part of a class, I would change the messages include that (e.g. “className.awesomeLogic”).

There you have it! Of course, all suggestions on debugging are welcome.

Download com.esiteful.debug.localTrace.

jQuery.meshtml

Posted by stephen on October 14th, 2008

With tables being viewed as improper, overly-complicated structural markup, it surprises me sometimes how many divs and whatnots are required to achieve certain effects. It’s not efficient for us to create 6 divs for every container we want with rounded corners, when one or two would do for a rectangle. Even two divs can be somewhat complicated for clients unfamiliar with html, and we all know they still want to add pretty content.

jQuery.meshtml will replace or insert-into any element with a block of html (e.g. your complicated container markup). Here’s a quick sample:


var baseHtml = "<div>{$mesh}</div>";
var meshSettings = {base:baseHtml, replace:true};
j('.container-box').meshtml(meshSettings);

With replace set to true, the targeted elements will be replaced. Otherwise it will insert your block of html inside of the target elements.

What makes this more useful than the built in replaceWith, wrap, wrapInner and other methods is that our markup can be much more complicated, and we define exactly where we want the variable(s). By default, the variable name is “mesh”. Notice “{$mesh}” in baseHtml above. We can also define multiple variable names and what elements/content those reference. The keyword for the current element being inspected is “each”. See a more complex example of using meshtml below:

Note that you can use my getNodeHtml function so that you aren’t stuck with moving the innerHTML of the elements around. View the source of the complex example to see how.

jQuery function/plugin base

Posted by stephen on October 13th, 2008

A great article on creating your own jQuery plugins/functions.
http://www.learningjquery.com/2007/10/a-plugin-development-pattern

Here’s a quick sample. Serves well as a base…

jQuery.fn.functionName = function(options, callback){
var settings = {
setting: "a",
callback: null
};
if (options) {
jQuery.extend(settings, options);
}
var jQueryParent = this;
var objIdx = 0;
this.each(function(){
jQueryChild = jQuery(this);
//put all your goodies here
//execute the callbacks
if (settings.callback != null) {
settings.callback(this);
}
objIdx++;
});
if (callback != null) {
callback(jQueryParent);
}
return jQuery(this);
}

jQuery hover() and unbind()

Posted by stephen on October 13th, 2008

Quick tip on jQuery hover event. There is a gotcha you may also run into, which is similar to one I’ve found in Actionscript 3.0…obj.hover(function(){}) works as expected in Firefox and IE. Binding the mouseover event seems to get different results in FF and IE.

I was unable to unbind the hover event with obj.unbind(”hover”) and obj.unbind(”mouseover”), so I did some searching around and came across this post. Apparently, the hover() method binds to the mouseenter and mouseleave events, so I just needed to unbind those. Oddly, I haven’t seen those events anywhere in the jQuery event docs, along with several other properties and methods. I’m not sure where an actual complete reference is if their site doesn’t even have it…


Copyright © 2007 Stephen Rushing. All rights reserved.