django-statici18n icon indicating copy to clipboard operation
django-statici18n copied to clipboard

Save the timestamp of the last file compile

Open ssobczak opened this issue 2 years ago • 3 comments

This solves the following problem:

I want the end-user to cache the complied translations file (via Cache-Control response header). But I need the filename to contain revision (content hash or timestamp) to have user's browser download the updated file after release.

This allows me to override STATICI18N_FILENAME_FUNCTION setting in my project and use the timestamp of the file generation as part of filename.

I think this entire feature of adding timestamp in the generated filename could be built-in in the library, but for now I'm sending this minimal change. What do you think?

The neat part is that in my project I can still have the i18n file regenerated "on the fly" during development by adding this to my urls.py:

if settings.DEBUG:
    # make i18n dynamically refreshed during development by serving from Django, rather than collected static files
    urlpatterns += (
        path(
            "static/jsi18n/<slug:lang_code_ignored>/djangojs.<int:timestamp_ignored>.js",
            JavaScriptCatalog.as_view(),
            name="javascript-catalog",
        ),
    )

ssobczak avatar Oct 27 '22 13:10 ssobczak

Thanks for your interest.

AFAIU what you need is a way to override the current filename generated in order to append a timestamp. You can definitely use a tailored STATICI18N_FILENAME_FUNCTION to handle it. Something along the lines:

# app/i18.py file
import os.path
import time


def filename_with_timestamp(language_code, domain, output_format="js"):
    timestamp = time.time()
    return os.path.join(language_code, f"{domain}-{timestamp}.{output_format}")


# settings.py file
STATICI18N_FILENAME_FUNCTION = "app.i18n.filename_with_timestamp"

Would it achieve what you are looking for?

zyegfryed avatar Nov 02 '22 17:11 zyegfryed

@zyegfryed correct, this is part of the solution, but the timestamp in filename should represent the time when the static assets were last re-compiled. This way user's browser can keep using the cached file as long as the filename stays the same.

This MR saves the timestamp of last asset re-compilation, so I can use it in the way you described.

ssobczak avatar Nov 02 '22 17:11 ssobczak

@ssobczak Do you use the staticfiles app to manage your static files?

I want the end-user to cache the complied translations file (via Cache-Control response header). But I need the filename to contain revision (content hash or timestamp) to have user's browser download the updated file after release.

Do we agree you need that revision when you deploy your static files (translations included)?

The neat part is that in my project I can still have the i18n file regenerated "on the fly" during development by adding this to my urls.py:

if settings.DEBUG:
    # make i18n dynamically refreshed during development by serving from Django, rather than collected static files
    urlpatterns += (
        path(
            "static/jsi18n/<slug:lang_code_ignored>/djangojs.<int:timestamp_ignored>.js",
            JavaScriptCatalog.as_view(),
            name="javascript-catalog",
        ),
    )

This comment bugs me: in the development environment you should not care about how static files are deployed, i.e. you should not have to explicitly use and serve those files.

Regarding that last point, can you show me how you reference your translations (and static files) in your templates?

zyegfryed avatar Nov 11 '22 09:11 zyegfryed