Skip to main content

Cloning your Corporate UI with HTML DB - Part I (Re-Post)

The following is a re-post of the "Cloning your Corporate UI with HTML DB" series that I blogged about back in 2005 on the now-defunct Orablogs site. Most of the content and advise is still the same today, and has been reposted here exactly as it was on the old site. Enjoy!

June 8, 2005

I've often been asked how to create custom Themes & Templates with Oracle HTML DB. The truth is that it’s one half Art, and one half Science. (Note: Percentages may vary based on what you consider “Art” and “Science”). And since the desired look and feel varies from site to site, there’s no easy way to document these steps.

Thus, I am going to attempt to “blog” my way through it, using a real-world example.

As you may know, the look & feel of was recently updated as part of the re-launch of, OTN, etc. I believe that this is now the 4th UI in 2 years for

Three sites that I manage - Oracle HTML DB Studio, Oracle HTML DB References, and Best Practices PL/SQL – are running in the previous “livery”, and need to be updated. I figured that this is as good an example as any to illustrate how to change the look & feel of an HTML DB application without changing the underlying functionality.

Like any good craftsman, you need good tools in order to do a good job. (Hint: never buy the cheapest ANYTHING at Home Depot – it will break, and then you will end up re-buying the more expensive one anyways) Here’s what I plan on using:
  • Mozilla Firefox w/these extensions:
    • Web Developer
    • ColorZilla
    • ieview
  • DreamWeaver MX
  • PaintShop Pro
Getting Started
Since it gets the most traffic of the three, I am going to use HTML DB Studio as the baseline application. Truth be told – it really doesn’t matter which one I use, as once I have my theme completed, I can apply it to all three.

As a first step, I exported HTML DB Studio and then re-imported it as a new application. This way, the production site won’t reflect any of my changes until I am completely done. Feel free to pop in on the Work in Progress.

The next step is to determine which Templates in my Theme will need to be re-worked. Overall, I have 33 templates in my FY06 Theme. If you navigate to this page:

Workspace HTML DB STUDIO > Builder - Application 20530 > Shared Components > Themes > Templates > Template Utilization

You can see which of your templates are actually being used by a specific application. In my Theme, there are 13 templates which are not used. Thus, I need to initially only be concerned with the 20 which are referenced, as the “unused” 13 may be referenced in another application. Either way, this reduces the amount of work required.

Now that I have a short list, I’m going to try to make it even shorter. In some cases – such as my button template – I will not need to make any changes, as the template will look OK in both the new and old UI’s. I can further reduce my list by one or two more templates here. Sometimes you’ll be able to do better…

Where to Start
I’ve found that the best place to start is with the Page Template. Replicating the structure of your desired UI makes assembling all of the components that much easier. Unfortunately, this is typically the most time-consuming task, as Page Templates can be rather large. Depending on how much the target page differs from your current page, you’ll need to decide whether to try to retrofit it or start from scratch. Since it looks like the new look is simpler than the previous one, I am going to start from scratch.

An Oracle HTML DB Page Template is nothing more than HTML sprinkled with HTML DB-specific tokens, used to substitute sub-templates and/or values. Thus, you could go to, save the HTML Source, paste it into an HTML DB Page Template, and the results should be similar, save the relative image & CSS references which would break. That’s exactly what I’m going to do!


Your browser sent a request that this server could not understand. mod_plsql: /pls/otn/wwv_flow.accept HTTP-400 Value param too long. Length is 43467. Upper limit is 32512

Looks like I need to slim down the code, as I am around 10k over the 32k limit. I’ll take that same source and paste it into DreamWeaver, and then remove any content. Remember, we’re just trying to build the structure of the page – we’ll use HTML DB Regions to populate the page with content.

Cutting out all of the content from the center region of the OTN Home page got us well under the 32k limit. I also took a couple of minutes and ensured that the token #BOX_BODY# was placed in the newly-empty center region. #BOX_BODY# will be substituted with the HTML DB Regions for a specific page – reports, forms, HTML, PL/SQL, etc.

Next, let’s set the Theme to use our new Page Template as the Default Page Template. From the Themes page, click on the edit icon next to your Theme, and then select your Page Template as the default Page Template and Apply Changes. If pages in your application are set to use the Default Page Theme, then you should instantly see the new Theme in action – as ugly as it may be.

I’ll have to say that this was the BEST first draft that I have seen in a while:

However, we’re a long way from being done, as things like Authentication, Tabs, Region Templates, CSSs, and Lists still need to be translated over.

Continue to Part II


Popular posts from this blog

Logging APEX Report Downloads

A customer recently asked how APEX could track who clicked “download” from an Interactive Grid.  After some quick searching of the logs, I realized that APEX simply does not record this type of activity, aside from a simple page view type of “AJAX” entry.  This was not specific enough, and of course, led to the next question - can we prevent users from downloading data from a grid entirely?

I knew that any Javascript-based solution would fall short of their security requirements, since it is trivial to reconstruct the URL pattern required to initiate a download, even if the Javascript had removed the option from the menu.  Thus, I had to consider a PL/SQL-based approach - one that could not be bypassed by a malicious end user.

To solve this problem, I turned to APEX’s Initialization PL/SQL Code parameter.  Any PL/SQL code entered in this region will be executed before any other APEX-related process.  Thus, it is literally the first place that a developer can interact with an APEX page…

Custom Export to CSV

It's been a while since I've updated my blog. I've been quite busy lately, and just have not had the time that I used to. We're expecting our 1st child in just a few short weeks now, so most of my free time has been spent learning Lamaze breathing, making the weekly run to Babies R Us, and relocating my office from the larger room upstairs to the smaller one downstairs - which I do happen to like MUCH more than I had anticipated. I have everything I need within a short walk - a bathroom, beer fridge, and 52" HD TV. I only need to go upstairs to eat and sleep now, but alas, this will all change soon...

Recently, I was asked if you could change the way Export to CSV in ApEx works. The short answer is, of course, no. But it's not too difficult to "roll your own" CSV export procedure.

Why would you want to do this? Well, the customer's requirement was to manipulate some data when the Export link was clicked, and then export it to CSV in a format…

Refreshing PL/SQL Regions in APEX

If you've been using APEX long enough, you've probably used a PL/SQL Region to render some sort of HTML that the APEX built-in components simply can't handle. Perhaps a complex chart or region that has a lot of custom content and/or layout. While best practices may be to use an APEX component, or if not, build a plugin, we all know that sometimes reality doesn't give us that kind of time or flexibility.While the PL/SQL Region is quite powerful, it still lacks a key feature: the ability to be refreshed by a Dynamic Action. This is true even in APEX 5. Fortunately, there's a simple workaround that only requires a small change to your code: change your procedure to a function and call it from a Classic Report region.In changing your procedure to a function, you'll likely only need to make one type of change: converting and htp.prn calls to instead populate and return a variable at the end of the function. Most, if not all of the rest of the code can remain un…