Dynamic Theme Switching in Oracle APEX via PL/SQL only

Dynamic Theme Switching in Oracle APEX via PL/SQL only

Customizing the look and feel of your application can significantly enhance user experience. Oracle APEX provides a flexible way to control the appearance of applications through Themes and Theme Styles. In this blog post, we'll delve into dynamic theme switching in Oracle APEX by analyzing a provided PL/SQL code that implements this concept in practice.

Introduction to Theme Switching in Oracle APEX

In Oracle APEX, Themes define the overall design of an application, while Theme Styles are specific variations within a theme. Dynamically switching themes or theme styles allows developers to change the application's appearance at runtime, which can be particularly useful for different environments such as development, testing, and production.

Overview of the PL/SQL Code

The provided PL/SQL code consists of two main procedures:

  1. set_theme_env: Determines the appropriate theme based on an input parameter and applies it to the application.

  2. set_theme: Activates or deactivates theme styles and sets the current theme style for the application.

We'll analyze these procedures in detail to understand how they work together to enable theme switching.

Detailed Analysis of the set_theme_env Procedure

PROCEDURE set_theme_env(p_theme IN VARCHAR2)
AS
    v_env_type VARCHAR2(20);
BEGIN
    v_env_type := p_theme;

    apex_session.create_session (
        p_app_id   => 1000, --- our main app in each enviroment
        p_page_id  => 1,
        p_username => 'SWITCHTHEME'
    );

    FOR c_rows IN (
        SELECT sa.application_oid, s.application_id, s.name, s.theme_style_id r
        FROM apex_application_theme_styles s,
             apex_application_themes t,
             sec_applications sa
        WHERE s.application_id = sa.app_id
          AND t.application_id = s.application_id
          AND t.theme_number   = s.theme_number
          AND t.is_current     = 'Yes'
          AND s.name = v_env_type
        ORDER BY 1
    ) LOOP
        set_theme(c_rows.application_oid, c_rows.r, 'No');
    END LOOP;

    apex_session.delete_session;
END;

Explanation

  • Purpose of the Procedure: set_theme_env sets the application's theme based on the input parameter p_type.

  • Variables:

    • v_env_type: Determines the name of the theme style.
  • Flow:

    1. Session Creation: Creates an APEX session with application ID 1000 and username 'SWITCHTHEME'. This is necessary to use APEX APIs that require a session.

    2. Querying Relevant Theme Styles: Opens a cursor (c_rows) that selects theme styles matching the specified v_env_type.

    3. Calling the set_theme Procedure: For each found theme style, it calls the set_theme procedure to apply the theme accordingly.

    4. Session Deletion: Deletes the created session after completion.

Key Points

  • APEX Session: Some APEX APIs require a valid session. Therefore, a session is created before executing actions and deleted afterward.

  • Dynamic Theme Selection: By using v_env_type, the theme can be dynamically selected based on the environment or other criteria.

Detailed Analysis of the set_theme Procedure

PROCEDURE set_theme(p_application_oid IN NUMBER, p_default_theme_id IN VARCHAR2, p_enable_swith_theme IN VARCHAR2)
AS
    l_enabled BOOLEAN := CASE WHEN p_enable_swith_theme = 'Yes' THEN TRUE ELSE FALSE END;
BEGIN
    -- Initialize logging
    p_log.set_log_object('set_theme_env');
    p_log.set_log_action('START');

    FOR l_theme IN (
        SELECT application_id, theme_number
        FROM apex_applications, sec_applications sa
        WHERE application_id = sa.app_id
          AND sa.application_oid = p_application_oid
    ) LOOP
        IF l_enabled THEN
            -- Enable user style
            p_log.set_log_action('ENABLE_USER_STYLE');

            apex_theme.enable_user_style (
                p_application_id => l_theme.application_id,
                p_theme_number   => l_theme.theme_number
            );
        ELSE
            -- Disable user style
            p_log.set_log_action('DISABLE_USER_STYLE');

            apex_theme.disable_user_style (
                p_application_id => l_theme.application_id,
                p_theme_number   => l_theme.theme_number
            );

            -- Clear all user styles
            p_log.set_log_action('CLEAR_USER_STYLES');
            p_log.log_debug('Clearing all user styles for Application ID: ' || l_theme.application_id);
            apex_theme.clear_all_users_style(l_theme.application_id);
        END IF;
    END LOOP;

    IF p_default_theme_id IS NOT NULL THEN
        FOR l_theme IN (
            SELECT theme_number, application_id
            FROM apex_application_themes aat, sec_applications sa
            WHERE aat.application_id = sa.app_id
              AND sa.application_oid = p_application_oid
              AND is_current = 'Yes'
        ) LOOP
            -- Switch theme style
            p_log.set_log_action('SWITCH_THEME_STYLE');

            apex_theme.set_current_style (
                l_theme.application_id,
                l_theme.theme_number,
                p_default_theme_id
            );
            COMMIT;

            -- Log completion
            p_log.log_debug('Theme style switch completed for Application ID: ' || l_theme.application_id);
        END LOOP;
    END IF;

    -- Finalize logging
    p_log.set_log_action('');
    p_log.set_log_object('');
END;

Explanation

  • Purpose of the Procedure: set_theme activates or deactivates user style switching and sets the current theme style for the application.

  • Parameters:

    • p_application_oid: The unique identifier of the application.

    • p_default_theme_id: The ID of the theme style to be set.

    • p_enable_swith_theme: Indicates whether to enable ('Yes') or disable ('No') user style switching.

  • Variables:

    • l_enabled: A boolean set based on p_enable_swith_theme.
  • Flow:

    1. Initialize Logging: Sets the log object and action for the procedure.

    2. Loop Over Themes: For each application matching p_application_oid, either enable or disable user style switching.

      • Enable: Calls apex_theme.enable_user_style.

      • Disable: Calls apex_theme.disable_user_style and apex_theme.clear_all_users_style to remove all custom styles.

    3. Set Current Theme Style: If p_default_theme_id is not null, calls apex_theme.set_current_style to set the theme style.

    4. Logging: Logs messages throughout the process to document the flow.

Key Points

  • APEX Theme APIs: The procedure uses APEX APIs like apex_theme.enable_user_style, apex_theme.disable_user_style, apex_theme.clear_all_users_style, and apex_theme.set_current_style to manipulate theme settings.

  • Logging: Extensive logging enables tracking the process and debugging if necessary.

Implementing the Code in Your APEX Application

To use this code in your application, ensure that:

  • The tables sec_applications, apex_application_themes, apex_application_theme_styles, and apex_applications exist and are properly populated.

  • The procedures are correctly installed in your database with the necessary permissions.

  • A logging mechanism (p_log) is implemented to handle log messages.

Sample Invocation

BEGIN
    set_theme_env('TEST');
END;

This call would set the theme for the 'TEST' environment. Which is also called TEST in our case