Odoo Images and Attachments — Explaining and Regenerating Assets

Odoo Images and Attachments — Explaining and Regenerating AssetsHow do assets and bundles actually workHolden RehgBlockedUnblockFollowFollowingMar 9If you have ever manually moved a filestore from one site to another, or migrated a database without the filestore, then you’ve probably had to deal with failing or missing assets.

It’s not obvious how assets are stored and served within the Odoo system.

There is no manual compilation process like you would expect coming from frontend utilities like npm , webpack , or even a simpler sass –watch process.

As developers, when we are writing stylesheets or javascript we just reload the page and everything has been minified and concatenated into these large asset bundles.

Automagically.

????I’m going to try to reveal a little bit of the magic going on behind the scenes and some tricks for regenerating assets bundles.

Viewing the bundlesOpen up developer tools on any Odoo instance.

In the <head/> you won’t see a ton of link or script tags from all of the different modules (assuming you are not in developer mode).

You will just see a few compiled files.

They are broken out into a few categories:web.

assets_commonweb.

assets_backendweb_editor.

summernoteweb_editor.

assets_editorAnd when you open up any of these files, they are an aggregated set of assets across multiple modules.

They aren’t completely abstracted though.

You can still see paths to where the assets came from.

This is how all of the assets are served up to Odoo when you are accessing the site as a normal, non-developer mode user.

We’ll get into why these are like this, but as a developer, you should always expect the assets to be compiled into these large, minified files by default.

Why are assets bundledI wasn’t in the room when the creators of Odoo decided to do this, but it’s most likely for performance and convenience.

PerformanceLoading in hundreds and hundreds of assets files isn’t smart.

Odoo isn’t a small application, so they concatenate everything together server side so that the client only has to load a few files.

This makes things faster obviously.

Fewer files and less content going over the network.

ConvenienceThere is a certain convenience about creating your module, defining your assets in xml, writing your css or js, reloading the page, and not having to worry about the bundling process at all.

No file watchers, no extra commands to run.

I don’t completely agree with this approach because there’s too much “magic” and it’s not explicit to the developer what’s going on.

If something is implicit then it needs to work 100% of the time.

In the case of asset bundles, there are still scenarios where developers have to manually work with them (the reason I’m writing this article).

But I do understand the benefits to this approach, and as a developer as long as you are slightly aware of the inner working, then you’ll be able to handle any scenario.

Revealing a little bit moreEven though we open up dev tools and see all of those assets compiled, there are built-in utilities in Odoo for getting around that immediately.

This is where the difference between Developer Mode and Developer Mode with Assets comes in.

I’m sure many users and even some developers have wondered why both of these modes exist.

Developer Mode leave the assets as is.

They continue to perform their default process of concatenation and minification of all assets.

But we’re going to focus on Developer Tools with Assets.

Let’s go ahead and enable is so that we can see exactly how it affects the asset bundling process.

You can enable it one of two ways.

:Go to Settings and select “Activate developer mode (with assets)”2.

Or add debug=assets to your url parameters.

Now check out dev tools again:Nothing has been combined into a bundle.

Frontend code has not been minified.

We are actually now loading in every asset file manually.

This obviously hurts performance but is very helpful as a developer.

If we need to search css or js, find the original source files from core, extend core frontend code, etc.

then we should be working with assets on.

Digging into coreMost developers probably understood what I explained above before they read this article.

They know that the assets get combined into large asset files like web.

assets_backend from an xml template, which they can inherit, stick their own <link/> or <script/> tag in, and then their code gets included on the page.

But I would suspect most developers don’t understand the full process behind the scenes.

If you start digging into core a bit, you can see how these are actually combined into bundles.

Attachmentsir.

attachment becomes important since all of these bundles that you see on the frontend are stored as attachment records.

Looking at the database, we can see the following records:odoo=# select id,name from ir_attachment where name like '/web/content/%%assets_backend%.

css%'; id | name—–+————————————————— 749 | /web/content/749-b02200e/web.

assets_backend.

0.

css 750 | /web/content/750-b02200e/web.

assets_backend.

1.

css(2 rows)odoo=# select id,name from ir_attachment where name like '/web/content/%'; id | name—–+——————————————————— 753 | /web/content/753-b02200e/web.

assets_backend.

js 754 | /web/content/754-60aed99/web_editor.

assets_editor.

js 681 | /web/content/681-875e871/web.

assets_frontend.

0.

css 683 | /web/content/683-875e871/web.

assets_frontend.

js 748 | /web/content/748-78450bf/web.

assets_common.

0.

css 749 | /web/content/749-b02200e/web.

assets_backend.

0.

css 750 | /web/content/750-b02200e/web.

assets_backend.

1.

css 751 | /web/content/751-60aed99/web_editor.

assets_editor.

0.

css 752 | /web/content/752-78450bf/web.

assets_common.

js 351 | /web/content/351-92b02fe/web_editor.

summernote.

0.

css 355 | /web/content/355-92b02fe/web_editor.

summernote.

js(11 rows)Looks familiar.

We have all of the same files that we see in dev tools when loading up a page.

All of these bundles start with /web/content which makes it simple to search for.

We can even see the exact paths to these files in our filestore.

So we know that when the client makes the request to the frontend, Odoo is looking at those attachment records, finding the file based on a path in the ir.

attachment record, and then serving that file to the frontend.

datas_fname | store_fname————————–+—————————————–web.

assets_backend.

0.

css | 13/1373c2eeb8edda69ac37a7ecfa5ba4a908fb94baweb.

assets_backend.

1.

css | 97/9733c7a9a67906f8ded8d8607155351d8d2881d1(2 rows)Asset creation and templatesSo we know how assets are loaded, via ir.

attachment but how do they actually get created? Like I said earlier, automagically.

These are automatically generated, lazily, on page load.

If you take a look at the web.

webclient_bootstrap template, you will see those bundles being loaded via the t-call-assets directive.

This directive is the main function that looks at the assets and auto creates them.

The IrQweb class is the one responsive for defining the _compile_directive_call_assets method.

This method is linked to the xml t-call-assets directive.

Check out the method yourself in core, because it does a lot but in terms of asset generation, the most important part of the method is that it calls _get_asset_nodes which then calls get_asset_bundle .

You can see that get_asset_bundle references the primary class AssetsBundle which is in charge of creating, updating, destroying, and generally managing the asset bundles that we’ve been looking at.

AssetsBundle is another class that you should take a look at yourself to see all of the different functionality provided.

But the main function that we are going to look at is save_attachment .

The save_attachment method creates ir.

attachment records based on binary strings generated from bundled content passed in.

You will notice that these are always prefixed with /web/content which is why we can search ir.

attachment records based on /web/content when looking for bundles generated from core.

The detailsThere are more details that occur between the XML directive and the save_attachment method so I highly recommend going through the methods to learn a little bit more about the actual concatenation and minification process.

That’s out of scope of this article :)The case for regenerating bundlesBefore getting into the process of actually regenerating the bundles, let’s review the scenarios when bundles need to be regenerated.

It’s not too often, depending on what you do day-to-day.

Migrating a filestore manually to a separate instance, via an scp, ftp , or even just a mv transfer.

Restoring a database from a sql dump without the filestore.

Corrupted assets.

How to regenerate assets from the GUIIf are on Odoo 12.

0+ then regenerating asset bundles is simple from the GUI (assuming that you can access the GUI.

)Enable developer modeOpen the debug menu from the toolbarSelect Regenerate Asset BundlesThis runs a JS function called regenerateAssets .

How to regenerate assets from Odoo ShellLooking at the JS function above, it’s not too difficult for us to just manually regenerate the assets ourselves from an Odoo shell instance.

If you are on Odoo 11.

0 or prior, then this is very helpful since you don’t have the GUI functions provided in 12.

0+.

After deleting the ir.

attachment records then you just need to reload the web page, which will call the t-call-assets directive again and regenerate the bundles.

Once the page is loaded you can look in the database and see that all of those attachments you just deleted are back.

How to regenerate assets from psqlAnd finally, we can do the same thing from a psql prompt as well.

The same applies here as when regenerating from Odoo shell.

Reload the web page and the system will recreate the asset bundle attachments.

Thanks For ReadingI hope this was helpful!Follow me on Twitter for random thoughts and articles about Odoo.

Or follow me directly here at Medium to stay up to date on my dev articles.

Holden.

. More details

Leave a Reply