Use Django template syntax in a css file

后端 未结 3 422
旧巷少年郎
旧巷少年郎 2020-12-19 05:28

I have a css file home_global.css which has the following in it:

body {
    background-image: url(\"{% static \'citator/citator.jpg\' %}\");
}
         


        
3条回答
  •  暖寄归人
    2020-12-19 05:41

    Okay well after a month and a half I decided to just go through the docs and see whether I could figure this one out myself. And I have a working solution. Here's how to do it.

    STEP 1: add some directories and setup some new variables in settings.

    First, I assume that you already have a directory structure like this for static files:

    //static/
    

    Add another sub-directory called "templates". This is where we will make our templates. This is not where they will be saved. So you should now have this:

    //static//templates
    

    In this directory, add your css template. Here's my example, saved as "test.css":

    {% load static %}
    body {
        background-image: url("{% static 'citator/citator.jpg %}");
    }
    

    Now add these variables to settings. Note, I only have one app. If you have more, find a more manageable way of doing this:

    APP_NAME = ""
    STATIC_TEMPLATE_PATH = os.path.join(BASE_DIR, APP_NAME, "static", APP_NAME, "templates")
    

    Next we need to write a custom command that will run the Django Template Engine on these templates. To do this, navigate to:

    //management/commands
    

    If you don't have these directories, make them.

    Then you need to make a file, call it something like "render_static_templates.py", with this in it, in this directory:

    from django.core.management.base import BaseCommand 
    from django.template import engines
    from .settings import STATIC_TEMPLATE_PATH, APP_NAME
    import glob 
    import os
    
    def find_templates(stem: str):
        """
        Custom template finder that just looks in 
        your new static templates directories for templates
        """
        leaf = "*"
        path = os.path.join(stem, leaf)
        all_templates = glob.glob(path)
        return all_templates
    
    
    class Command(BaseCommand):
        def handle(self, *args, **options):
    
            # Get the file paths for all our new static templates:    
            all_templates = find_templates(STATIC_TEMPLATE_PATH)
    
            # See docs: https://docs.djangoproject.com/en/2.1/topics/templates/    
            django_engine = engines['django']
    
            for path in all_templates:
                template = django_engine.get_template(path)
                # Debug if you want. The URL should now be resolved in this print output.
                print(template.render())
    
                # Now we need to save the RENDERED template somewhere. I save it up one level from the templates folder, so that collectstatic can find it. You can put it elsewhere.
                leaf = path.split("/")[-1]
                save_path = os.path.join(APP_NAME, "static", APP_NAME, leaf)
                # Debug
                print(save_path)
    
                with open(save_path, "w") as f:
                    f.write(template.render())
    

    What you do next is run this new management command:

    python manage.py render_static_templates
    

    You should now be able to see the rendered template in

    /app/static/app
    

    Next run

    python manage.py collectstatic
    

    Assuming you have your STATIC_ROOT and STATIC_URL set up correctly, you will have the rendered template moved to where it should be. In my case:

    /static/
    

    From there, the RENDERED template will be served using whatever you use to serve. (I use whitenoise). And if all has gone well, you should see a background image on your page!

    Possible improvements: - Better directory structures. - Integrating into the "collect_static" command.

提交回复
热议问题