0% found this document useful (0 votes)
4K views10 pages

Building A Custom ERPNext v15 Dashboard Theme (Odoo-Style)

This guide provides step-by-step instructions for creating a CSS-only custom theme app for ERPNext v15, styled similarly to Odoo. It covers prerequisites, project setup, theming architecture, asset configuration, and best practices for writing and testing CSS to ensure compatibility with future updates. The document emphasizes the importance of maintaining a clean separation from core ERPNext files and provides reusable CSS examples for common dashboard elements.

Uploaded by

mohammed ameer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4K views10 pages

Building A Custom ERPNext v15 Dashboard Theme (Odoo-Style)

This guide provides step-by-step instructions for creating a CSS-only custom theme app for ERPNext v15, styled similarly to Odoo. It covers prerequisites, project setup, theming architecture, asset configuration, and best practices for writing and testing CSS to ensure compatibility with future updates. The document emphasizes the importance of maintaining a clean separation from core ERPNext files and provides reusable CSS examples for common dashboard elements.

Uploaded by

mohammed ameer
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 10

Building a Custom ERPNext v15 Dashboard Theme

(Odoo-Style)
This guide walks you through creating a CSS-only custom theme app for ERPNext v15, focusing on restyling
the Desk dashboard to an Odoo-like look. We assume you have ERPNext/Frappe installed and know basic
terminal/Git. The process involves creating a Frappe app that bundles CSS assets and overrides core styles
safely. We’ll explain the app structure, how to configure assets, override styles, and ensure update
compatibility, plus provide example CSS for cards, charts, buttons, and layout.

Prerequisites
• Frappe/ERPNext v15 installed locally. You should have a running frappe-bench with ERPNext
v15.
• Bench CLI installed: If not, run pip install frappe-bench .
• Git & Python: Basic familiarity with cloning Git repos and Python.
• Text editor/IDE: For writing CSS and Python files.

No prior theming experience is needed; we’ll use plain CSS. For reference, the official Frappe docs show how
to create a new app with bench new-app 1 . We’ll build on that for our theme.

1. Project Setup
1. Open your bench folder:

cd ~/frappe-bench

2. Create a new Frappe app for the theme:

bench new-app my_theme

This scaffolds a new app named my_theme in apps/my_theme 1 . Follow the prompts (enter
app title, description, author, etc.).
3. Install the theme app on your site:

bench --site [your-site-name] install-app my_theme

This adds the app to your site and creates its database tables 2 .
4. Verify installation:

1
bench --site [your-site-name] list-apps

You should see my_theme listed under installed apps.

These commands set up the new theme app. It now exists in apps/my_theme and is registered on your
site (added to sites/apps.txt ). No code changes yet, just project scaffolding.

2. Understanding Frappe Theming Architecture


Frappe’s theming works by having each app supply CSS/JS assets that are automatically loaded into the
Desk. In practice:

• App public folder: Each app (including your theme app) has a public directory for static files (CSS,
images, etc.). This is symlinked into sites/assets/[appname] 3 . For example, a file
my_theme/public/css/style.css will be served at /assets/my_theme/css/style.css 3 .
• Hooks for assets: In your app’s hooks.py , you list any CSS/JS to include. Frappe reads these hooks
to inject your files. For example, setting app_include_css = "/assets/my_theme/css/
style.css" tells Frappe to load style.css for the Desk.
• Asset bundling: When you run bench build , Frappe compiles and bundles assets. All apps’ public
CSS/JS (plus your hooks) are processed into bundles under sites/assets . Bundled files (in
assets/[appname]/dist/ ) are what the browser actually uses 4 . Use bench watch during
development to auto-rebuild on changes 5 .

In summary, your theme app behaves like any Frappe app. Its public/css files become Desk CSS,
included via hooks, and served from the /assets folder 3 6 . We’ll leverage this pipeline to override
core styles safely.

3. Creating the Theme App


Treat your theme as a regular Frappe app. After bench new-app my_theme , the directory structure looks
like this:

frappe-bench/
└── apps/
└── my_theme/
├── hooks.py
├── my_theme/ (Python package folder)
│ ├── __init__.py
│ ├── config/
│ ├── public/
│ │ └── css/
│ │ └── style.css # (your custom CSS goes here)
│ └── templates/
│ └── ...

2
├── modules.txt
├── patches.txt
└── ...

This is the standard Frappe app layout 7 . Notably:

• hooks.py : This is where you register assets (CSS/JS) to include.


• public/css/ : Put your CSS files here. They’ll be served as /assets/my_theme/css/
[filename].css 3 .
• Other folders: You can also add images, fonts, or HTML templates if needed, but for a CSS-only
theme we focus on public/css/ .

When you run bench build , files in public/css/ are compiled (if SCSS) or copied to assets/
my_theme/dist/css . Since we use pure CSS, they’ll appear under assets/my_theme/css or dist/
css after building. The Frappe docs confirm that each app’s public folder is symlinked into sites/
assets/[appname] 3 , making static files accessible via the browser.

4. Configuring Assets & Bundling


Now let’s tell Frappe to load your CSS. Edit hooks.py in your app (apps/my_theme/my_theme/hooks.py)
and add:

app_name = "my_theme"
app_title = "My Theme"
app_publisher = "Your Name"
app_description = "Odoo-like dashboard theme"
# ...
# Load custom CSS into Desk (backend UI)
app_include_css = "/assets/my_theme/css/style.css"

This app_include_css hook injects your CSS globally in the Desk 6 . (You can list multiple files or use a
list, but one main CSS file is enough.) For example:

# my_theme/hooks.py
app_include_css = "/assets/my_theme/css/style.css"
# Optionally, include custom JS similarly:
# app_include_js = "/assets/my_theme/js/script.js"

Important: If you use multiple CSS files, all listed files will be loaded in the order given. Also ensure your
theme app is loaded after ERPNext in sites/apps.txt (Frappe processes apps in that list order) 8 .

After editing hooks, run:

3
bench build

to compile and bundle assets 9 . The console will rebuild your CSS and others. You can also use:

bench watch

which enters watch mode and recompiles on file changes 10 . (In v14+, the desk UI will auto-reload when
assets rebuild 11 .) This makes development much faster.

Once built, open your ERPNext Desk in a browser; your style.css will have been included. Frappe serves
it from /assets/my_theme/css/style.css 3 . You can now write CSS rules in style.css to
override or extend the default styling.

5. Writing Your Theme Styles


In my_theme/public/css/style.css , add your custom CSS. Since we’re using plain CSS, you can use
modern features like CSS variables. For example, to change the primary color and buttons:

:root {
/* Define a custom primary color for easier reuse */
--primary-color: #1e88e5;
}

/* Example: override primary button styles */


.btn-primary {
background-color: var(--primary-color);
border-color: var(--primary-color);
color: #fff;
border-radius: 4px;
transition: background 0.3s;
}

/* Hover state for buttons */


.btn-primary:hover {
background-color: #1669a3;
}

Use selectors to target the Desk elements you want to style. ERPNext’s Desk UI uses Bootstrap classes (like
.btn ) and custom classes (e.g. number cards use .widget.number-widget-box 12 ). For example, to
style the dashboard “Number Card” widgets, you might write:

4
.widget.number-widget-box {
background-color: #f0f8ff; /* pale blue background */
border: 1px solid var(--border-color);
box-shadow: 2px 2px 6px rgba(0,0,0,0.1);
border-radius: 8px;
padding: 12px;
transition: transform 0.2s;
}
.widget.number-widget-box:hover {
transform: translateY(-4px);
}

Here we use the existing class .widget.number-widget-box (from ERPNext code) to add backgrounds
and shadows 12 . You can do similar for charts or cards by inspecting their CSS classes (e.g. wrap chart
<div> s or use .chart container selectors in ERPNext).

Since we avoid SCSS, any variables or mixins are manual. You can use CSS custom properties ( :root {} )
or just hard-code colors/fonts. The key is specificity: more specific selectors (like my-theme .module-
button ) will override generic ones. Avoid using !important when possible; instead rely on selector
specificity and load order (your CSS loads after core CSS, so it wins if equal specificity).

6. Isolating Dashboard Styles


To avoid conflicts with other parts of ERPNext or future apps, scope your CSS whenever possible. For
example:

• Prefix with a unique parent class: Many themes wrap the body with a class. You could add a class
(e.g. my-theme-active ) on <body> and then prefix rules:
.my-theme-active .btn-primary { ... } . This ensures your styles only apply when that
class is present. (Injecting this class might require overriding a template or using a small JS snippet.)
• Target specific elements: Instead of styling generic tags (like button ), style known classes (like
.page-head h1 , .workspace .label , etc.) that appear on the Desk pages you want to change.
• Limit to Desk: Frappe’s desk and website have separate contexts. By default, app_include_css
affects the desk. If you also have a website, avoid naming classes that might appear there. Using a
unique namespace (e.g. prefix all your classes with erpnext- or similar) can help.

For example, in our CSS we might write:

/* Only affect elements inside the Desk workspace */


.desk .workspace {
background: #ffffff;
}
/* Or, if using a wrapper class: */
.my-theme .workspace {

5
background: #ffffff;
}

Even if you don’t add a wrapper class, ensure your selectors are as specific as needed. One useful tip:
always test your styles on a fresh site with ERPNext updates. Avoid deep selectors that may break if
ERPNext’s HTML structure changes. For number cards we saw .widget.number-widget-box in core,
which was stable enough to use 12 .

7. Integrating with ERPNext


With your CSS written and hooked, integration is automatic. Key steps:

• Rebuild assets after changes: Whenever you edit style.css , rerun bench build or keep
bench watch running. Then refresh the Desk.
• Install and update: On a production or other bench, deploy your app via Git or the marketplace.
Typically:

bench get-app https://github.com/your-org/my_theme.git


bench --site [site] install-app my_theme
bench build

This fetches your app and rebuilds assets.


• App order: As noted, ensure my_theme appears after erpnext in sites/apps.txt . This
ensures your CSS is included after the core CSS 8 .
• Theme Switching (Optional): ERPNext’s user settings allow switching between “Light” and “Dark”
themes, but custom themes aren’t listed by default. If you want a menu option, you’d extend
frappe.ui.ThemeSwitcher as shown in Frappe blogs 13 . (This involves JS and Python overrides,
which is more advanced and beyond our CSS-only scope.) For now, your theme CSS will apply
globally to the Desk once installed.

In summary, once app_include_css is set and your app is installed, ERPNext automatically loads your
CSS with every page load 6 . You don’t need to modify core files or use any hacks.

8. Testing & Debugging


During development:

• Use browser dev tools: Inspect elements in the ERPNext Desk to find class names and see CSS
impact. Modify your style.css and rebuild to try changes.
• bench watch : Run bench watch so that each save to your CSS auto-rebuilds assets 10 . In
modern Frappe, the Desk reloads automatically on rebuild (thanks to live-reload on v14+ 11 ).
• Check multiple views: Test your styles on different Desk pages (workspace, list view, form view) to
ensure nothing breaks. Try both light and dark modes if using ERPNext’s theme toggles.

6
• Cross-browser: Verify in at least Chrome and Firefox. Ensure responsive behavior on different
resolutions (ERPNext uses responsive grid, so your CSS should adapt or use media queries if
needed).

If styles aren’t showing, common issues include: forgetting bench build , wrong hook path (must match
/assets/app/css/filename.css ), or caching (try hard-refresh or clearing browser cache).

9. Best Practices & Update Compatibility


To ensure your theme remains maintainable:

• No core edits: Never modify ERPNext or Frappe source files. Keep all overrides in your theme app.
Future upgrades will overwrite core files, so local edits would be lost.
• Use stable selectors: Base your CSS on higher-level classes or data attributes rather than deeply
nested elements. For example, styling .btn-primary is safer than styling .btn.btn-
primary .icon .
• Namespace your CSS: If not already using a unique parent (like .my-theme ), at least prefix
custom class names (e.g. .dash-card , .mybtn ) to avoid collision with other apps.
• Minimize !important : Using !important can make future adjustments hard. Rely on Frappe’s
load order (your CSS is last) and specificity. Only use !important as a last resort.
• Document your overrides: Keep comments in your CSS (e.g. /* Changed button color for
sales graphs */ ) or a README in your theme repo. This helps when ERPNext updates change
class names.
• Test after upgrades: Whenever you update ERPNext to a new version, verify your theme still looks
correct. Pay special attention to renamed or removed classes. Frappe’s release notes sometimes
mention UI changes.
• Fallbacks for core changes: If a core selector you relied on changes, you may need to update your
CSS. For example, if ERPNext moves from .widget.number-widget-box to a new class, your rule
will break. Keep this in mind and track such overrides.

By following these practices, your theme will be more robust. The Frappe docs even suggest using variables
and partials for maintainability, but in our CSS-only setup you can mimic this with custom properties (as
shown) or reusable classes.

10. Reusable CSS Examples


Below are sample CSS snippets to improve the look of common Desk elements. You can adapt these to your
color scheme and style:

• Cards/Widgets: Add background, borders, and shadows to number cards and panels:

/* Style Number Card widgets */


.widget.number-widget-box {
background-color: #f0f8ff;
border: 1px solid var(--border-color);
box-shadow: 2px 2px 6px rgba(0,0,0,0.1);

7
border-radius: 8px;
padding: 12px;
}
/* Hover effect */
.widget.number-widget-box:hover {
background-color: #e6f2ff;
transform: translateY(-4px);
}

This uses the .widget.number-widget-box selector (ERPNext’s class for the stat cards 12 ) and
enhances it with a colored background and shadow.

• Charts: Target chart containers (you may need to inspect ERPNext’s HTML to find a class, here we
use a hypothetical .dashboard-chart ):

/* Style dashboard charts */


.dashboard-chart {
background: #ffffff;
border: 1px solid var(--border-color);
border-radius: 6px;
padding: 8px;
}
.dashboard-chart canvas {
max-width: 100%;
}

This gives charts a white card look with rounded corners. Replace .dashboard-chart with the
actual selector (e.g., if charts are in .flex-chart or similar).

• Buttons: Change default button styles to match your theme color:

/* Customize primary buttons */


.btn-primary {
background-color: #ff6600;
border-color: #e65c00;
color: #ffffff;
padding: 6px 14px;
border-radius: 4px;
}
.btn-primary:hover {
background-color: #e65c00;
}

This example sets a bright orange theme color for primary actions.

8
• Layout: Adjust spacing or grid on Dashboard pages. For instance, to add gap between dashboard
widgets:

/* Add gap between cards in dashboard grid */


.row.dashboard-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 16px;
}

Here, .row.dashboard-container is a guess; replace with the container class for your
dashboard cards or panels. Using CSS grid adds consistent spacing.

Each example above demonstrates overriding core visuals with simple CSS. You can reuse these patterns:
apply a background, border, and shadow to cards; change .btn-primary colors; and use modern CSS
layouts for grid spacing. By tweaking the colors and sizes, you can achieve a clean, modern (Odoo-like) look.

11. Deployment & Distribution


Once your theme app is ready:

• Version control: Push your my_theme app to a GitHub repository. Include a README.md with
install/build instructions.
• Marketplace (optional): You can publish your theme on the Frappe/ERPNext Marketplace for others
to use.
• Deploy to servers: On production servers, use Git and bench:

cd ~/frappe-bench
git clone https://github.com/your-org/my_theme.git apps/my_theme
bench --site [your-site] install-app my_theme
bench build

or with bench get-app as shown earlier.


• Reset assets cache: After deployment, you may also run bench --site [your-site] clear-
cache and restart Bench to ensure fresh assets.

With these steps, your custom theme will be active in ERPNext.

9
12. Conclusion
You’ve now created a reusable ERPNext v15 theme app that injects custom CSS into the Desk. Key points
covered:

• Frappe app structure: Your theme is a Frappe app with a public/css folder and hooks.py 7

6 .
• Asset pipeline: Use app_include_css to load your styles; run bench build/watch to compile
assets 9 4 .
• CSS overrides: Write targeted CSS (using existing classes) to override core styles. Prefix or scope
rules to avoid unwanted effects.
• Examples: We provided code for styling cards, charts, buttons, and layout to achieve a modern look.

Following this guide, even beginners can create sophisticated themes without SCSS or core hacking. Always
test after ERPNext updates and document your changes for future maintenance. With a well-structured
theme app, you can easily update ERPNext without losing your custom dashboard style.

Resources
• Frappe Documentation – Apps and Asset Bundling (see Creating an App and Asset Bundling
sections) 1 9 .
• Frappe Forum – discussions on custom CSS theming and overrides 8 12 .
• ERPNext Dashboard and Widget docs (for class references).
• ERPNext v15 code on GitHub – to inspect HTML/CSS structure for precise selectors.

By building on these principles and examples, you can iteratively refine your theme to perfectly match your
desired (e.g. Odoo-like) dashboard appearance. Good luck!

1 2 7 Apps
https://docs.frappe.io/framework/v15/user/en/basics/apps

3 4 Static Assets
https://docs.frappe.io/framework/user/en/basics/static-assets

5 9 10 11 Asset Bundling
https://docs.frappe.io/framework/user/en/basics/asset-bundling

6 8 Override some CSS rules in desk - Frappe Framework - Frappe Forum


https://discuss.frappe.io/t/override-some-css-rules-in-desk/7839

12 Number cards - very bland - how can we introduce background color - ERPNext - Frappe Forum
https://discuss.frappe.io/t/number-cards-very-bland-how-can-we-introduce-background-color/132686

13 Customising Frappe ERPNext UI: Part I — Adding a new theme | by Pratheesh Russell | Medium
https://medium.com/@pratheeshrussell/customising-frappe-erpnext-ui-part-i-adding-a-new-theme-74d7103df275

10

Common questions

Powered by AI

To ensure compatibility after ERPNext updates, developers should avoid editing core ERPNext or Frappe source files and keep all CSS overrides within their theme app. They should use stable selectors that rely on higher-level classes or data attributes, avoid deep nesting that may break with HTML changes, namespace CSS classes uniquely, and minimize the use of !important to ease future adjustments. Documenting CSS overrides with comments and README files is encouraged, and testing the theme app for correctness after each ERPNext update is crucial. Monitoring Frappe's release notes for any UI changes will help preemptively address potential issues .

To deploy a custom theme for ERPNext to a production server, developers should use Git to manage the theme app. They start by cloning the theme repository from GitHub to the apps directory in frappe-bench using git clone. Then, they need to install the app on the desired site with the command bench --site [site] install-app [app_name]. Next, they run bench build to compile assets, ensuring that all static files are bundled for production. Finally, to ensure new assets are served, a cache reset might be necessary using bench --site [your-site] clear-cache, and restarting the bench may be required .

Frappe's theming architecture manages asset bundling by allowing each app to supply CSS and JavaScript assets that are automatically loaded into the Desk. Each app has a public directory for static files that is symlinked into sites/assets/[appname]. These assets are managed through hooks in the app’s hooks.py file. The bench build command compiles and bundles these assets, creating bundles under sites/assets which are then used by the browser. This bundling is crucial because it ensures that all assets are correctly loaded and up-to-date, preventing issues with style and script rendering, especially in a modular environment like ERPNext .

In a Frappe app, the hooks.py file is critical because it enables the registration of assets such as CSS and JavaScript to be included in the app. It uses specific settings, like app_include_css, to specify CSS files that should be loaded on the Desk. This allows developers to inject their custom styles and scripts directly into ERPNext's interface without modifying core files, facilitating modular and manageable theme development. The hooks.py is integral for ensuring that assets are correctly bundled and included, employing Frappe's built-in asset management processes .

Developers can ensure their custom ERPNext themes do not conflict with future apps or updates by scoping their CSS to specific areas and elements within the Desk. This can be achieved by prefixing CSS rules with a unique parent class (or using a custom wrapper on the body element) to ensure styles only apply within that scope. Additionally, using specific selectors that target known classes rather than generic tags minimizes conflicts. Limiting styles to the Desk's context and avoiding overlap with website contexts also helps, along with avoiding deep selector paths prone to break if ERPNext HTML changes .

Testing ERPNext themes across different views and devices is essential to ensure that the custom styles are consistently applied and do not break the interface in various scenarios. This testing allows developers to check for responsive behavior, cross-browser compatibility, and that the UI remains intuitive and functional in diverse environments. Tools like browser dev tools are crucial for inspecting elements and styles, helping developers make real-time adjustments. Automation using bench watch for auto-rebuilding and testing on different browsers such as Chrome and Firefox ensures comprehensive evaluation of the theme's appearance and functionality .

Sample CSS snippets to enhance ERPNext Desk elements involve using selectors that target specific UI components. For widgets, one can style number cards by using the .widget.number-widget-box selector with properties like background-color, border, and box-shadow for visual improvement. Similarly, primary buttons can be styled by targeting .btn-primary and customizing the background-color, border-radius, and hover effects. These styles should be implemented in a structured manner, employing modern CSS practices such as CSS variables and grid for layout, ensuring a clean and maintainable design .

To integrate a custom theme app in ERPNext, developers should set the app_include_css in hooks.py to inject the custom CSS globally into the Desk. After editing their CSS, they need to run bench build or use bench watch to compile and bundle assets. It's crucial to refresh the Desk to observe the changes. Testing involves using browser dev tools to inspect elements and ensure appropriate styling, trying the styles across different Desk views, and checking for responsiveness and compatibility in major browsers like Chrome and Firefox. Version control through Git and clearing caches are also important steps during deployment .

To create a CSS-only custom theme app for ERPNext v15, you need Frappe/ERPNext v15 installed locally, a running frappe-bench with ERPNext v15, and Bench CLI installed (you can install it using pip install frappe-bench). Basic familiarity with Git and Python is required, as well as a text editor or IDE for writing CSS and Python files. No prior theming experience is needed since the guide uses plain CSS .

Using CSS variables is beneficial when styling ERPNext themes because they allow for consistent reuse of design values, such as colors and fonts, across the style sheet, simplifying updates and ensuring consistency. In ERPNext, they can be applied by defining them within the :root selector, which makes them globally accessible. For instance, to change the primary button color, a variable --primary-color could be defined and then reused: .btn-primary { background-color: var(--primary-color); } This approach enhances maintainability and customization capabilities in dynamic and large-scale projects .

You might also like