Changing the Appearance

Exclusive offer: get 50% off this eBook here
Oracle ADF Enterprise Application Development – Made Simple: Second Edition

Oracle ADF Enterprise Application Development – Made Simple: Second Edition — Save 50%

Successfully plan, develop, test, and deploy enterprise applications with Oracle ADFwith this book and ebook

$32.99    $16.50
by Sten E. Vesterli | February 2014 | Enterprise Articles

In this article by Sten Vesterli, author of Oracle ADF Enterprise Application Development – Made Simple, Second Edition, explains how to use the powerful skin editor available in JDeveloper 11g Release 2 and later versions to create Cascading Style Sheets to create a new skin, which corresponds to your enterprise visual identity, for your application.

(For more resources related to this topic, see here.)

Controlling appearance

An ADF Faces application is a modern web application, so the technology used for controlling the look of the application is Cascading Style Sheets (CSS).

The idea behind CSS is that the web page (in HTML) should contain only the structure and not information about appearance. All of the visual definitions must be kept in the style sheet, and the HTML file must refer to the style sheet. This means that the same web page can be made to look completely different by applying a different style sheet to it.

The Cascading Style Sheets basics

In order to change the appearance of your application, you need to understand some CSS basics. If you have never worked with CSS before, you should start by reading one of the many CSS tutorials available on the Internet.

To start with, let's repeat some of the basics of CSS.

The CSS layout instructions are written in the form of rules. Each rule is in the following form:

selector { property: value; }

The selector function identifies which part of the web page the rule applies to, and the property/value pairs define the styling to be applied to the selected parts.

For example, the following rule defines that all <h1> elements should be shown in red font:

h1 { color: red; }

One rule can include multiple selectors separated by commas, and multiple property values separated by semicolons. Therefore, it is also a valid CSS to write the following line of code to get all the <h1>, <h2>, and <h3> tags shown in large, red font:

h1, h2, h3 { color: red; font-size: x-large; }

If you want to apply a style with more precision than just every level 1 header, you define a style class, which is just a selector starting with a period, as shown in the following line of code:

.important { color: red; font-weight: bold }

To use this selector in your HTML code, you use the keyword class inside an HTML tag. There are three ways of using a style class. They are as follows:

  • Inside an existing tag: <h1>
  • Inside the special <span> tag to style the text within a paragraph
  • Inside a <div> tag to style a whole paragraph of text

Here are examples of all the three ways:

<h1 class="important">Important topic</h1>
You <span class="important">must</span> remember this.
<div class="important">Important tip</div>

In theory, you can place your styling information directly in your HTML document using the <style> tag. In practice, however, you usually place your CSS instructions in a separate .css file and refer to it from your HTML file with a <link> tag, as shown in the following line of code:

<link href="mystyle.css" rel="stylesheet" type="text/css">

Styling individual components

The preceding examples can be applied to HTML elements, but styling can also be applied to JSF components. A plain JSF component could look like the following code with inline styling:

<h:outputFormat value="hello" style="color:red;"/>

It can also look like the line of code shown using a style class:

<h:outputFormat value="hello" styleClass="important"/>

ADF components use the inlineStyle attribute instead of just style as shown in the following line of code:

<af:outputFormat value="hello" inlineStyle="color:red;"/>

The styleClass attribute is the same, as shown in the following line of code:

<af:outputFormat value="hello" styleClass="important"/>

Of course, you normally won't be setting these attributes in the source code, but will be using the StyleClass and InlineStyle properties in the Property Inspector instead.

In both HTML and JSF, you should only use StyleClass so that multiple components can refer to the same style class and will reflect any change made to the style. InlineStyle is rarely used in real-life ADF applications; it adds to the page size (the same styling is sent for every styled element), and it is almost impossible to ensure that every occurrence is changed when the styling requirements change—as they will.

Building a style

While you are working out the styles you need in your application, you can use the Style section in the JDeveloper Properties window to define the look of your page, as shown in the following screenshot. This section shows six small subtabs with icons for font, background, border/outline, layout, table/list, and media/animation. If you enter or select a value on any of these tabs, this value will be placed into the InlineStyle field as a correctly formatted CSS.

When your items look the way you want, copy the value from the InlineStyle field to a style class in your CSS file and set the StyleClass property to point to that class. If the style discussed earlier is the styling you want for a highlighted label, create a section in your CSS file, as shown in the following code:

.highlight {background-color:blue;}

Then, clear the InlineStyle property and set the StyleClass property to highlight. Once you have placed a style class into your CSS file, you can use it to style the other components in exactly the same way by simply setting the StyleClass property.

We'll be building the actual CSS file where you define these style classes.

InlineStyle and ContentStyle

Some JSF components (for example, outputText) are easy to style—if you set the font color, you'll see it take effect in the JDeveloper design view and in your application, as shown in the following screenshot:

Other elements (for example, inputText) are harder to style. For example, if you want to change the background color of the input field, you might try setting the background color, as shown in the following screenshot:

You will notice that this did not work the way you reasonably expected—the background behind both the label and the actual input field changes. The reason for this is that an inputText component actually consists of several HTML elements, and an inline style applies to the outermost element. In this case, the outermost element is an HTML <tr> (table row) tag, so the green background color applies to the entire row.

To help mitigate this problem, ADF offers another styling option for some components: ContentStyle. If you set this property, ADF tries to apply the style to the content of a component—in the case of an inputText, ContentStyle applies to the actual input field, as shown in the following screenshot:

In a similar manner, you can apply styling to the label for an element by setting the LabelStyle property.

Unravelling the mysteries of CSS styling

As you saw in the Input Text example, ADF components can be quite complex, and it's not always easy to figure out which element to style to achieve the desired result. To be able to see into the complex HTML that ADF builds for you, you need a support tool such as Firebug. Firebug is a Firefox extension that you can download by navigating to Tools | Add-ons from within Firefox, or you can go to http://getfirebug.com.

When you have installed Firebug, you see a little Firebug icon to the far right of your Firefox window, as shown in the following screenshot:

When you click on the icon to start Firebug, you'll see it take up the lower half of your Firefox browser window.

Only run Firebug when you need it

Firebug's detailed analysis of every page costs processing power and slows your browser down. Run Firebug only when you need it. Remember to deactivate Firebug, not just hide it.

If you click on the Inspect button (with a little blue arrow, second from the left in the Firebug toolbar), you place Firebug in inspect mode. You can now point to any element on a page and see both the HTML element and the style applied to this element, as shown in the following screenshot:

In the preceding example, the pointer is placed on the label for an input text, and the Firebug panels show that this element is styled with color: #0000FF. If you scroll down in the right-hand side Style panel, you can see other attributes such as font-family: Tahoma, font-size: 11px, and so on.

In order to keep the size of the HTML page smaller so that it loads faster, ADF has abbreviated all the style class names to cryptic short names such as .x10. While you are styling your application, you don't want this abbreviation to happen. To turn it off, you need to open the web.xml file (in your View project under Web Content | WEB-INF). Change to the Overview tab if it is not already shown, and select the Application subtab, as shown in the following screenshot:

Under Context Initialization Parameters, add a new parameter, as shown:

  • Name: org.apache.myfaces.trinidad.DISABLE_CONTENT_COMPRESSION
  • Value: true

When you do this, you'll see the full human-readable style names in Firebug, as shown in the following screenshot:

You notice that you now get more readable names such as .af_outputLabel. You might need this information when developing your custom skin.

Conditional formatting

Similar to many other properties, the style properties do not have to be set to a fixed value—you can also set them to any valid expression written in Expression Language (EL). This can be used to create conditional formatting.

In the simplest form, you can use an Expression Language ternary operator, which has the form <boolean expression> ? <value if true > : <value if false>. For example, you could set StyleClass to the following line of code:

#{bindings.Job.inputValue eq 'MANAGER' ? 'managerStyle' :
 'nonManagerStyle'}

The preceding expression means that if the value of the Job attribute is equal to MANAGER, use the managerStyle style class; if not, use the nonManagerStyle style class. Of course, this only works if these two styles exist in your CSS.

Skinning overview

An ADF skin is a collection of files that together define the look and feel of the application. To a hunter, skinning is the process of removing the skin from an animal, but to an ADF developer it's the process of putting a skin onto an application.

All applications have a skin—if you don't change it, an application built with JDeveloper 12c uses some variation of the skyros skin.

When you define a custom skin, you must also choose a parent skin among the skins JDeveloper offers. This parent skin will define the look for all the components not explicitly defined in your skin.

Skinning capabilities

There are a few options to change the style of the individual components through their properties. However, with your own custom ADF skin, you can globally change almost every visual aspect of every instance of a specific component.

To see skinning in action, you can go to http://jdevadf.oracle.com/adf-richclient-demo. This site is a demonstration of lots of ADF features and components, and if you choose the Skinning header in the accordion to the right, you are presented with a tree of skinnable components, as shown in the following screenshot:

You can click on each component to see a page where you can experiment with various ways of skinning the component.

For example, you can select the very common InputText component to see a page with various representations of the input text components. On the left-hand side, you see a number of Style Selectors that are relevant for that component. For each selector, you can check the checkbox to see an example of what the component looks like if you change that selector. In the following example, the af|inputText:disabled::content selector is checked, thus setting its style to color: #00C0C0, as shown in the following screenshot:

As you might be able to deduce from the af|inputText:disabled::content style selector, this controls what the content field of the input text component looks like when it is set to disabled—in the demo application, it is set to a bluish color with the color code #00C0C0. The example application shows various values for the selectors but doesn't really explain them. The full documentation of all the selectors can be found online, at http://jdevadf.oracle.com/adf-richclient-demo/docs/skin-selectors.html. If it's not there, search for ADF skinning selectors.

On the menu in the demo application, you also find a Skin menu that you can use to select and test all the built-in skins. This application can also be downloaded and run on your own server. It could be found on the ADF download page at http://www.oracle.com/technetwork/developer-tools/adf/downloads/index.html, as shown in the following screenshot:

Skinning recommendations

If your graphics designer has produced sample screens showing what the application must look like, you need to find out which components you will use to implement the required look and define the look of these components in your skin.

If you don't have a detailed guideline from a graphics designer, look for some guidelines in your organization; you probably have web design guidelines for your public-facing website and/or intranet.

If you don't have any graphics guidelines, create a skin, as described later in this section, and choose to inherit from the latest skyros skin provided by Oracle. However, don't change anything—leave the CSS file empty. If you are a programmer, you are unlikely to be able to improve on the look that the professional graphics designers at Oracle in Redwood Shores have created.

The skinning process

The skinning process in ADF consists of the following steps:

  1. Create a skin CSS file.
  2. Optionally, provide images for your skin.
  3. Optionally, create a resource bundle for your skin.
  4. Package the skin in an ADF library.
  5. Import and use the skin in the application.

In JDeveloper 11g Release 1 ( 11.1.1.x) and earlier versions, this was very much a manual process. Fortunately, from 11g Release 2, JDeveloper has a built-in skinning editor.

Stand-alone skinning

If you are running JDeveloper 11g Release 1, don't despair. Oracle is making a stand-alone skinning editor available, containing the same functionality that is built into the later versions of JDeveloper. You can give this tool to your graphic designers and let them build the skin ADF library without having to give them the complete JDeveloper product.

ADF skinning is a huge topic, and Oracle delivers a whole manual that describes skinning in complete detail. This document is called Creating Skins with Oracle ADF Skin Editor and can be found at http://docs.oracle.com/middleware/1212/skineditor/ADFSG.

Creating a skin project

You should place your skin in a common workspace. If you are using the modular architecture, you create your skin in the application common workspace. If you are using the enterprise architecture, you create your enterprise common skin in the application common workspace and then possibly create application-specific adaptations of that skin in the application common workspaces.

The skin should be placed in its own project in the common workspace. Logically, it could be placed in the common UI workspace, but because the skin will often receive many small changes during certain phases of the project, it makes sense to keep it separate. Remember that changing the skin only affects the visual aspects of the application, but changing the page templates could conceivably change the functionality. By keeping the skin in a separate ADF library, you can be sure that you do not need to perform regression testing on the application functionality after deploying a new skin.

To create your skin, open the common workspace and navigate to File | New | Project. Choose the ADF ViewController project, give the project the name CommonSkin, and set the package to your application's package prefix followed by .skin (for example, com.dmcsol.xdm.skin).

Oracle ADF Enterprise Application Development – Made Simple: Second Edition Successfully plan, develop, test, and deploy enterprise applications with Oracle ADFwith this book and ebook
Published: February 2014
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

Skinning in practice

Now that we know what skinning is and what it can do, let's create and apply a skin to the example application.

Creating a skin CSS file

The most important part of your skin is the special ADF CSS file that defines the look of all the components you use in your application.

To create the CSS file, follow the ensuing steps:

  1. Select the CommonSkin project and navigate to File | New | From Gallery.... Under Web Tier | JSF/Facelets, choose ADF Skin. The Create ADF Skin dialog appears, as shown in the following screenshot:
  2. Give your CSS file a filename that includes –skin (for example, xdm-skin.css). You can leave the location at its default setting, and you don't have to change the value for Family either.

    Skin families

    Skins come in families—a collection of related skins. All skins in a family share the same family name, and each skin in the family has a unique Skin Id consisting of the family name and a platform suffix. You start with the .desktop member of the family—this is the version of the skin that will be used for normal browser access to your application. You can also define other family members, such as .mobile, for controlling how the application will look on a mobile device.

  3. In the second step of the wizard, you have the option to select various skins to base your own skin on. As you can read from the descriptions, Oracle recommends you base your own skin on the skyros-v1.desktop skin for most applications. If you are building an application that will work together with fusion applications, Oracle recommends that you base your skin on fusionFx-simple-v3.desktop.

Once you finish the wizard, your skin is opened. JDeveloper automatically recognizes your ADF skin CSS file as a special kind of CSS and shows it in a special skinning editor window, as shown in the following screenshot:

If your skin is based on the skyros or fusionFX-simple skin, the skin editor window contains a Design tab as well as a Selectors tab and a Source tab.

If you based your skin on another one of the Oracle-supplied skins, you will not see the Design tab. The Design tab makes it easier to make certain changes, but everything can also be done on the Selectors and Source tabs.

Working in the Design tab

The Design tab allows you to easily make a number of changes that apply to the whole application. The upper part of the window contains a number of tabs where you can change various values, and the lower part of this window can show some sample pages. You can click on the browser icon to open the sample page in your browser. The browsers available here are the ones that are set up in JDeveloper under Tools | Preferences | Web Browser.

On the tabs here, you can change various aspects of the application, as follows:

  • The General tab allows you to change the default font and text
  • The Branding Area and Global Area tabs affect the applications that use the default templates provided by Oracle (Oracle Three Column Layout and Oracle Dynamic Tabs Shell)
  • The remaining tabs allow you to change the default look of buttons, links, menus, and many other parts of your application

As you make changes, JDeveloper records your changes in the CSS file—you can always change to the Source tab at the bottom of the window to see the actual code JDeveloper writes.

Working in the Selectors tab

The Selectors tab allows you to style individual components with much more detailed control. This tab contains a tree selector to the left and a preview of the selected component to the right, as shown in the following screenshot:

For components that can be rendered in several different ways, there are tabs to the right that can be selected to view the component with a specific theme, and you can also select from the View as drop-down list. You can change the properties for the selected component in the Properties window.

The tree has five top-level nodes:

  • Style Classes
  • Global Selector Aliases
  • At-rules
  • Faces Component Selectors
  • Data Visualizations Component Selectors

Style Classes

The Style Classes are built-in styles intended for your use in the StyleClass attribute—these do no affect any components.

If you need to define your own styles classes, you can click on the plus sign above the navigator to the left and choose New Style Class to define a new class. It will be added to your CSS file and will show up under the Style Classes node. You can define the visual properties of the class using the Property Inspector or directly in the CSS source code by selecting the Source tab at the bottom of the skin editor panel.

Global Selector Aliases

The Global Selector Aliases are selectors that control many different components. Typically, you'd want to make these kinds of changes on the Design tab. However, if your skin is not based on skyros or fusionFx-simple, you don't have a Design tab and will have to make your global changes here.

At-Rules

At-Rules allows you to specify the style properties that will only be applied in specific environments, for example, a specific browser, platform, or locale. Defining an at-rule allows you to define, for example, that you want extra spacing if the browser is Internet Explorer.

Faces Component Selectors

Under the Faces Component Selectors node, you find all the individual ADF Faces components that you can change the visual appearance of. To change a component, expand the node corresponding to the component to see the different selectors you can control.

You can click on the component itself to set the general attributes for the component, or you can expand the Pseudo-Elements node to change some specific aspects. For example, if you want to change the actual field where the user enters data, you can select the content pseudo element. In the right-hand side of the ADF Skin dialog, you see the various subtypes of content styling that can apply to the component. As you select these subtypes, the Property Inspector shows the styling of that subtype, as shown in the following screenshot:

The preceding example shows the default styling of the entry field for an input text component. Notice the blue arrows that indicate a setting that is inherited from somewhere else—you can point to the arrow to see a pop up showing you where that setting inherits from.

If you want, for example, to change the border of a text field that contains a warning, scroll down among the examples of the InputText content to find the af|inputText:warning::content example and select it. In the Property Inspector, change the Border property, for example, to 4px dotted #FFFF00 to use a wider border as a series of dots in bright yellow, as shown in the following screenshot:

Data Visualizations Component Selectors

Finally, the Data Visualizations Component Selectors define the look of the various data visualization components (Gantt charts, graphs, maps, and so on.), as shown in the following screenshot:

Finding the selector at runtime

If you can't find the selector you want in the skinning editor, you can create a simple JSF page in JDeveloper and drop an instance of the component you want to skin onto this page and run the page in Firefox. Then, start the Firebug add-on and inspect the element you want to skin.

The right-hand panel in Firebug shows the styling that's applied to that element—if you set DISABLE_CONTENT_COMPRESSION to true, you will see a style class name such as .af_panelFormLayout_label-cell. This translates into the af|panelFormLayout component and the label-cell pseudo element. You can then look this up in the skinning editor and define the appearance you want.

Optionally providing images for your skin

If you want to change the images used in your application, first select the Design view (click on the tab at the bottom of the skin editor window). Then, select the General tab at the top of the window. On this tab, the right-most box is called Images. If you click on one of the images in this box, you get the Replace Icons dialog box, as shown in the following screenshot:

From this dialog, you can export all the images to a ZIP file. You can then open the file, replace the icons or other images you want to change, and import them again.

You can also change the images from the Selectors tab, but that's more complicated. It involves the following:

  • Selecting a pseudo element in the tree
  • Finding the image attribute (often Content, sometimes Background Image)
  • Using the settings icon (a little gearwheel) next to the attribute and selecting Copy Image

This places a copy of the image in your project—you can copy your own image into the same directory and change the relevant attribute, or simply overwrite the standard image with your own.

Optionally creating a resource bundle for your skin

You might have noticed that many ADF components display texts that you can't set through properties, for example, the pop up help that appears if you allow sorting in an af:table component and point to the table header, as shown in the following screenshot:

If you want to change these standard strings, you first need to go to the documentation and find the resource string you want to override. For table sorting, you need af_column.TIP_SORT_ASCENDING and af_column.TIP_SORT_DESCENDING.

Then, you need to open the resource bundle file that the skin editor has built for you, called skinBundle.properties by default, as shown in the following screenshot:

The default file contains a couple of examples, and you need to add your own resource strings to this file. It might look like the following code:

# This file may be used to define alternative text
# for resource strings that appear in the user
# interface of ADF Components.
# Example: To change the text that appears on the
# buttons of the af:dialog component from Ok and
# Cancel to Continue and Go Back, add the following
# to this file:
#  AF_DIALOG.LABEL_OK = Continue
#  AF_DIALOG.LABEL_CANCEL = Go Back
AF_COLUMN.TIP_SORT_ASCENDING = First things first
AF_COLUMN.TIP_SORT_DESCENDING = The last shall be first

Packaging the skin

Once you are done with your skin, you need to package it into an ADF library. To do this, you can right-click on your skin project and navigate to Deploy | New Deployment Profile. Choose ADF Library JAR File and give your deployment profile a name (for example, adflibXdmSkin).

In the Edit ADF Library JAR Deployment Profile Properties dialog that appears next, simply click on OK.

Then, right-click on your skin project again and choose the name of your deployment profile (for example, adflibXdmSkin), click on Next and then on Finish. Like for other ADF libraries, this creates a JAR file in the deploy directory under your project. As a developer, you should add it to your version control system, and your build/deployment manager will pick it up and have it tested and distributed to the various subsystem teams.

Using the skin

To use the skin, you simply need to add the ADF library to your project from the Components palette and change the trinidad-config.xml file in the project using the skin to refer to the skin in the library.

In the trinidad-config.xml file under Web Content/WEB-INF in your project, you need to change the <skin-family> tag to refer the skin family you defined:

<skin-family>xdm-skin</skin-family>

If you now run your application, you should see your skinning take effect, as shown in the following screenshot:

Summary

In this article, you've seen how ADF uses Cascading Style Sheets (CSS) for defining the appearance of components without affecting their functionality. For changing the look of an individual component, you can use inline styles, content styles, and style classes.

If you want to customize the look of the entire application, you define a skin. This used to be difficult and complex, but with the skinning editor available both as an integrated product in JDeveloper and as a stand-alone product, this has become much easier. You have a Design tab for quickly making application-wide changes and a Selectors tab with a tree navigator for selecting the components. You can use the Property Inspector to change the settings and immediately see what your component will look like. You final skin can include both global changes affecting the whole application, including the color scheme, and visual changes that affect only one specific component or even just one aspect of it.

When you are done with your application skin, you can deploy it as an ADF library using the normal procedures for working with ADF libraries to use it in your subsystems and master application.

Resources for Article:


Further resources on this subject:


Oracle ADF Enterprise Application Development – Made Simple: Second Edition Successfully plan, develop, test, and deploy enterprise applications with Oracle ADFwith this book and ebook
Published: February 2014
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

About the Author :


Sten E. Vesterli

Sten E. Vesterli picked up Oracle development as his first job after graduating from the Technical University of Denmark and hasn't looked back since. He has worked with almost every development tool and server Oracle has produced in the last two decades, including Oracle ADF, JDeveloper, WebLogic, SQL Developer, Oracle Portal, BPEL, Collaboration Suite, Designer, Forms, Reports, and even Oracle Power Objects.

He started sharing his knowledge with a conference presentation in 1997 and has given more than 100 conference presentations at Oracle OpenWorld and at ODTUG, IOUG, UKOUG, DOAG, DOUG, and other user group conferences around the world since. His presentations are highly rated by the participants, and in 2010 he received the ODTUG Best Speaker award.

He has also written numerous articles, participated in podcasts, and written Oracle Web Applications 101,  Oracle ADF Enterprise Application Development – Made Simple, and  Developing Web Applications with Oracle ADF Essentials. You can find his blog at www.vesterli.com and follow him on Twitter as  @stenvesterli.

Oracle has recognized Sten's skills as an expert communicator on Oracle technology by awarding him the prestigious title, Oracle ACE Director, carried by less than 100 people in the world. He is also an Oracle Fusion User Experience Advocate and sits on the Oracle Usability Advisory Board and participates in the Oracle WebLogic Partner Council.

Based in Denmark, Sten is a partner in the Oracle consulting company Scott/Tiger, where he works as a senior principal consultant. When not writing books or presenting, he is helping customers choose the appropriate technology for their needs, teaching, mentoring, and leading development projects. In his spare time, Sten enjoys triathlon and completed his first Ironman in 2012.

Books From Packt


Oracle Enterprise Manager 12c Administration Cookbook
Oracle Enterprise Manager 12c Administration Cookbook

Oracle E-Business Suite R12 Integration and OA Framework Development and Extension Cookbook
Oracle E-Business Suite R12 Integration and OA Framework Development and Extension Cookbook

Oracle ADF Faces Cookbook
Oracle ADF Faces Cookbook

 Oracle ADF Real World Developer’s Guide
Oracle ADF Real World Developer’s Guide

Developing Web Applications with Oracle ADF Essentials
Developing Web Applications with Oracle ADF Essentials

Oracle ADF 11gR2 Development Beginner's Guide
Oracle ADF 11gR2 Development Beginner's Guide

Oracle ADF Enterprise Application Development—Made Simple
Oracle ADF Enterprise Application Development—Made Simple

Oracle SOA Suite 11g Developer's Cookbook
Oracle SOA Suite 11g Developer's Cookbook


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software