Contents

Can you use AI to generate Oracle APEX themes? Yes, you can. Should you do it? Not necessarily, but it’s a fun experiment, and the results can be quite interesting!

I was eating some biscuits in the kitchen one afternoon when suddenly an idea struck me! ⚡ The idea was to use AI to generate theme-roller styles for Oracle APEX.

I’m not sure how butter biscuits and AI are related.. but that’s exactly how it happened! So, I started by exporting the Vita style from Theme Roller. 

By reading this article, you’ll learn how to ask AI to take the Vita Style from the APEX Universal Theme and make changes based on a prompt you write. You can then load these changes back into the APEX Theme Roller as a new Theme Style.

If you want to skip to the juicy parts, just copy my custom-built Vita Style Theme Roller Config at the end of this article and ask your favorite generative AI to make a theme from a prompt. Let’s go!

Step-by-step instructions

The first issue I encountered was when I exported the Vita theme style – unless the value is modified, all you see is this.

{"classes":[],"vars":{},"customCSS":"","useCustomLess":"N"}

Therefore, AI isn’t going to be much good at predicting the variables to use. So I had to modify each and every value – yes, it still hurts to think about it – and then export the file with all the user-modifiable settings intact.

After modifying the colors/settings, this produces an export. A snippet of that export looks like this:

{
    "classes": [],
    "vars": {
        "@g_Accent-BG": "#9400D3",
        "@g_Accent-OG": "#FA8072",
        "@g_Link-Base": "#0804AA",

My second issue is that since I have modified the values, it’s not Vita anymore! I really wanted AI to be impressed so much by Vita, that it was inspired to create an amazing new theme style. So, I had to get all the original values back. But what are they? Also, have you noticed that sometimes, when you tweak the colors in Theme Roller, some other colors are magically changed too? Why does that happen? All will be revealed shortly.

Having read Plamen’s blog article about how to copy APEX theme styles between applications, I noticed something in the Exploring the Theme Style configuration section called Input Parameter File URLs.

A screenshot showing APEX settings.

Long story short, this points to this file, which holds the Vita configuration. Using this, we can get each of Vita’s values back by searching for each variable one by one, i.e.:

  • g_Accent-BG
// Primary Accent
@g_Accent-BG: #056AC8;
  • g_Accent-OG
// Body Accent
@g_Accent-OG: #FDFDFD;
  • g_Link-Base
// Link Color
@g_Link-Base: @g_Accent-BG;

Oh, look! g_Link-Base‘s value is linked to g_Accent-BG. So when you use the Theme Roller and change g_Accent-BG, it actually changes the color for g_Link-Base too. This explains why some colors change “magically.” 

I put all the Vita values back one by one (AI didn’t want to cooperate 😞), and boom! We have Vita in a Theme Roller file. Let’s feed this into AI and check out the results.

The results – Were they worth the effort?

I imported the Opportunities app from the APEX Gallery into my workspace, then fired up Theme Roller and used the Import Feature to load in the AI-generated config file.

A screenshot showing APEX settings.

For each of the AI-generated themes, I’ll show you the exact prompt I used, as well as the result I got.

Note: all these Themes were generated with ChatGPT 3.5 only. Because…:

  • The config was too long for CoPilot to deal with
  • Gemini only wanted to give me half the theme back

AI-generated theme styles

  • The first attempt

This was the very first attempt, and a bit laughable at that. The prompt was:

Take this theme style and change the variable values ONLY to make a new theme style

The result:

A screenshot showing the theme.

  • The Dracula Theme rip-off

Here’s one based on my favorite theme, the Dracula Theme. It’s not so bad actually, but some of the text is nearly unreadable. Definitely needs some tuning! The prompt:

Can you make a theme based on the "Dracula Theme"?

The result:

A screenshot showing the theme.

  • A Leeds United Theme

How about a Leeds United Theme? The prompt I used:

Can you make a Leeds United Theme?

And the result:

A screenshot showing the theme.

  • The fabulous one

This one is quite fabulous, to be honest. The prompt was:

Can you make really modern, beautiful theme with the best color contrasts . Make it elegant, simple, yet awesome

The result:

A screenshot showing the theme.

  • The simple one

How about something simple? The prompt was just:

Create a pinky dark theme

The result:

A screenshot showing the theme.

  • The Neon Theme

Let’s try something more flashy. Here’s the prompt:

Incorporate bright neon colors, contrasts, and a dark background to give it that classic 80s vaporwave synth feel.

And the result:

A screenshot showing the theme.

  • The Chocolate Butter Biscuits Theme

And finally, the one that started all this craziness. The exact prompt I typed in was:

Can you make a style based on Tower Gate Milk Chocolate Butter Biscuits

And what I got in return:

A screenshot showing the theme.

Vita Style Theme Roller config

Want to create your own Theme Styles with AI? Just use a prompt like this with ChatGPT:

Take this theme roller config and make me a theme style based on the Tower Gate Milk Chocolate Butter Biscuits. Do not add any JSON comments.

[Paste in JSON from below]

Some additional tips:

  1. As Doug Gault points out, ChatGPT will occasionally add comments to JSON (which is not supported in the JSON specification), so you have to specifically ask it not to do it.
  2. ChatGPT sometimes likes to add, remove, change, or hallucinate extra variables. Therefore, you may have to ask it not to add, remove, or change any of the variable names.

The JSON content (copy it into your prompt):

{
    "classes": [],
    "vars": {
        "@g_Accent-BG": "#056AC8",
        "@g_Accent-OG": "#FDFDFD",
        "@g_Link-Base": "@g_Accent-BG",
        "@g_Focus": "@g_Accent-BG",
        "@g_Container-BorderRadius": ".125rem",
        "@g_Header-BG": "@g_Accent-BG",
        "@g_Header-FG": "contrast(@g_Header-BG, darken(@g_Header-BG,   80%), lighten(@g_Header-BG,   80%),  43%)",
        "@g_Body-BG": "@g_Accent-OG",
        "@g_Body-Text": "fade(contrast(@g_Body-BG, desaturate(darken(@g_Body-BG,  100%), 100%), desaturate(lighten(@g_Body-BG,  100%), 50%)), 100%)",
        "@g_Actions-Col-BG": "contrast(@g_Accent-OG, darken(@g_Accent-OG,   1.5%), lighten(@g_Accent-OG,   1.5%),  43%)",
        "@g_Actions-Col-Text": "fade(contrast(@g_Actions-Col-BG, desaturate(darken(@g_Actions-Col-BG,  100%), 100%), desaturate(lighten(@g_Actions-Col-BG,  100%), 50%)), 100%)",
        "@g_Body-Title-BG": "lighten(@g_Accent-OG, 3%)",
        "@g_Body-Title-FG": "fade(contrast(@g_Body-Title-BG, desaturate(darken(@g_Body-Title-BG,  100%), 100%), desaturate(lighten(@g_Body-Title-BG,  100%), 50%)), 100%)",
        "@l_Left-Col-BG": "lighten(@g_Accent-OG, 5%)",
        "@l_Left-Col-Text": "@g_Body-Text",
        "@g_Nav_Style": "dark",
        "@g_Nav-BGX": "desaturate(@g_Accent-BG, 85%)",
        "@g_Nav-BG": "darken(@g_Nav-BGX, 20%)",
        "@g_Nav-FG": "contrast(@g_Nav-BG, darken(@g_Nav-BG,   80%), lighten(@g_Nav-BG,   80%),  43%)",
        "@g_Nav-Active-BG": "darken(@g_Nav-BG, 10%)",
        "@g_Nav-Active-FG": "contrast(@g_Nav-Active-BG, darken(@g_Nav-Active-BG,   95%), lighten(@g_Nav-Active-BG,   95%),  43%)",
        "@g_Nav-Accent-BG": "@g_Accent-BG",
        "@g_Nav-Accent-FG": "@g_Accent-FG",
        "@g_Nav-Badge-BG": "@g_Accent-BG",
        "@g_Nav-Badge-FG": "@g_Accent-FG",
        "@g_NavBarMenu-Active-BG": "@g_Accent-BG",
        "@g_NavBarMenu-Active-FG": "@g_Accent-FG",
        "@g_NavBarMenu-BG": "#FFFFFF",
        "@g_NavBarMenu-FG": "fade(contrast(@g_NavBarMenu-BG, desaturate(darken(@g_NavBarMenu-BG,  85%), 100%), desaturate(lighten(@g_NavBarMenu-BG,  85%), 50%)), 100%)",
        "@g_Region-Header-BG": "lighten(@g_Accent-OG, 4%)",
        "@g_Region-Header-FG": "fade(contrast(@g_Region-Header-BG, desaturate(darken(@g_Region-Header-BG,  85%), 100%), desaturate(lighten(@g_Region-Header-BG,  85%), 50%)), 100%)",
        "@g_Region-BG": "lighten(@g_Region-Header-BG, 20%)",
        "@g_Region-FG": "fade(contrast(@g_Region-BG, desaturate(darken(@g_Region-BG,  85%), 100%), desaturate(lighten(@g_Region-BG,  85%), 50%)), 100%)",
        "@g_Disabled-BG": "#707070",
        "@g_Disabled-FG": "#FFFFFF",
        "@g_Primary-BG": "contrast(@g_Accent-BG, darken(@g_Accent-BG,   40%), lighten(@g_Accent-BG,   40%),  43%)",
        "@g_Primary-FG": "contrast(@g_Primary-BG, darken(@g_Primary-BG,   75%), lighten(@g_Primary-BG,   75%),  43%)",
        "@g_Success-BG": "#278701",
        "@g_Success-FG": "#FFF",
        "@g_Info-BG": "#056AC8",
        "@g_Info-FG": "#FFF",
        "@g_Warning-BG": "#FFC628",
        "@g_Warning-FG": "#000",
        "@g_Danger-BG": "#CB1100",
        "@g_Danger-FG": "#FFF",
        "@g_Color-Palette-1": "#309FDB",
        "@g_Color-Palette-1-FG": "fade(contrast(@g_Color-Palette-1, darken(@g_Color-Palette-1,  50%), lighten(@g_Color-Palette-1,  50%)), 100%)",
        "@g_Color-Palette-2": "#13B6CF",
        "@g_Color-Palette-2-FG": "fade(contrast(@g_Color-Palette-2, darken(@g_Color-Palette-2,  50%), lighten(@g_Color-Palette-2,  50%)), 100%)",
        "@g_Color-Palette-3": "#2EBFBC",
        "@g_Color-Palette-3-FG": "fade(contrast(@g_Color-Palette-3, darken(@g_Color-Palette-3,  50%), lighten(@g_Color-Palette-3,  50%)), 100%)",
        "@g_Color-Palette-4": "#3CAF85",
        "@g_Color-Palette-4-FG": "fade(contrast(@g_Color-Palette-4, darken(@g_Color-Palette-4,  50%), lighten(@g_Color-Palette-4,  50%)), 100%)",
        "@g_Color-Palette-5": "#81BB5F",
        "@g_Color-Palette-5-FG": "fade(contrast(@g_Color-Palette-5, darken(@g_Color-Palette-5,  50%), lighten(@g_Color-Palette-5,  50%)), 100%)",
        "@g_Color-Palette-6": "#DDDE53",
        "@g_Color-Palette-6-FG": "fade(contrast(@g_Color-Palette-6, darken(@g_Color-Palette-6,  50%), lighten(@g_Color-Palette-6,  50%)), 100%)",
        "@g_Color-Palette-7": "#FBCE4A",
        "@g_Color-Palette-7-FG": "fade(contrast(@g_Color-Palette-7, darken(@g_Color-Palette-7,  50%), lighten(@g_Color-Palette-7,  50%)), 100%)",
        "@g_Color-Palette-8": "#ED813E",
        "@g_Color-Palette-8-FG": "fade(contrast(@g_Color-Palette-8, darken(@g_Color-Palette-8,  50%), lighten(@g_Color-Palette-8,  50%)), 100%)",
        "@g_Color-Palette-9": "#E95B54",
        "@g_Color-Palette-9-FG": "fade(contrast(@g_Color-Palette-9, darken(@g_Color-Palette-9,  50%), lighten(@g_Color-Palette-9,  50%)), 100%)",
        "@g_Color-Palette-10": "#E85D88",
        "@g_Color-Palette-10-FG": "fade(contrast(@g_Color-Palette-10, darken(@g_Color-Palette-10,  50%), lighten(@g_Color-Palette-10,  50%)), 100%)",
        "@g_Color-Palette-11": "#CA589D",
        "@g_Color-Palette-11-FG": "fade(contrast(@g_Color-Palette-11, darken(@g_Color-Palette-11,  50%), lighten(@g_Color-Palette-11,  50%)), 100%)",
        "@g_Color-Palette-12": "#854E9B",
        "@g_Color-Palette-12-FG": "fade(contrast(@g_Color-Palette-12, darken(@g_Color-Palette-12,  50%), lighten(@g_Color-Palette-12,  50%)), 100%)",
        "@g_Color-Palette-13": "#5A68AD",
        "@g_Color-Palette-13-FG": "fade(contrast(@g_Color-Palette-13, darken(@g_Color-Palette-13,  50%), lighten(@g_Color-Palette-13,  50%)), 100%)",
        "@g_Color-Palette-14": "#AFBAC5",
        "@g_Color-Palette-14-FG": "fade(contrast(@g_Color-Palette-14, darken(@g_Color-Palette-14,  50%), lighten(@g_Color-Palette-14,  50%)), 100%)",
        "@g_Color-Palette-15": "#6E8598",
        "@g_Color-Palette-15-FG": "fade(contrast(@g_Color-Palette-15, darken(@g_Color-Palette-15,  50%), lighten(@g_Color-Palette-15,  50%)), 100%)",
        "@g_Button-BG": "mix(#F0F0F0, @g_Region-BG)",
        "@g_Button-Text": "contrast(@g_Button-BG, darken(@g_Button-BG,   75%), lighten(@g_Button-BG,   75%),  43%)",
        "@l_Button-Hot-BG": "@g_Accent-BG",
        "@l_Button-Hot-Text": "contrast(@l_Button-Hot-BG, darken(@l_Button-Hot-BG,   85%), lighten(@l_Button-Hot-BG,   85%),  43%)",
        "@l_Button-Simple-BG": "#FFFFFF",
        "@l_Button-Simple-Text": "fade(contrast(@l_Button-Simple-BG, darken(@l_Button-Simple-BG,  75%), lighten(@l_Button-Simple-BG,  75%)), 100%)",
        "@g_Form-Label": "@g_Region-FG",
        "@g_Form-BorderRadius": ".125rem",
        "@g_Form-Item-BG": "contrast(@g_Region-BG, darken(@g_Region-BG,   2.5%), lighten(@g_Region-BG,   2.5%),  43%)",
        "@g_Form-Item-FG": "fade(contrast(@g_Form-Item-BG, desaturate(darken(@g_Form-Item-BG,  85%), 100%), desaturate(lighten(@g_Form-Item-BG,  85%), 50%)), 100%)",
        "@Head-Height": "3rem",
        "@Nav-Exp": "15rem",
        "@Actions-Exp": "12.5rem",
        "@Side-Exp": "15rem"
    },
    "customCSS": "",
    "useCustomLess": "N"
}

Summary

And that’s about it. Keep in mind that ChatGPT doesn’t always get it right (as you’ve seen looking at the provided examples), but it’s still an interesting experiment. Try different stuff out, and have fun! Also, If you’re interested in other APEX-related content, check out my articles on the Pretius blog:

  1. Unlocking hidden colors in the Redwood Light APEX theme
  2. Oracle APEX new features – the low-code platform keeps evolving
  3. Using Auth0 Organizations with Oracle APEX: Create a single platform with access for multiple businesses
  4. Oracle APEX tutorial: Uncover Oracle’s best-kept low-code secret
  5. Oracle APEX + OKTA Identity Cloud Authentication & Authorization guide
Share