Re: How to use different templates for different sites/domains

2024-05-29 Thread Faisal Mahmood
You're right, using a single Django instance to serve multiple sites with
overridden templates can be tricky. While a custom template loader might
seem appealing, it's true that it doesn't accept the request object by
default. Here's the breakdown and some alternative solutions:

The Challenge:

   - Django's default template loader doesn't consider the current domain
   when searching for templates.
   - You want to use a single Django instance but have domain-specific
   templates.

Less Ugly Solutions:

   1.

   Template Name Prefixing:
   - Prefix your template names with the domain name. For example,
  domain1/home.html and domain2/home.html.
  - In your views, construct the full template name based on the
  current domain (using get_current_site).
  - This approach is simple but can make template names lengthy and
  less readable.
   2.

   Template Inheritance with Context Processors:
   - Create a base template with common elements.
  - Inherit from the base template for each domain-specific template.
  - Use a context processor to inject the current domain information
  into the context.
  - In your domain-specific templates, use the domain information to
  conditionally render specific content.
  - This approach offers flexibility but requires more code in
  templates and context processors.
   3.

   Third-Party Packages:
   - Consider packages like django-sites-templates or
  django-multihost-template-loader.
  - These packages provide custom template loaders that can leverage
  the request object to determine the appropriate template based on the
  domain.
  - This approach can be a good option if the built-in solutions don't
  meet your needs.

Middleware with Context Variables (Least Ugly Hack):

   - While not ideal, storing the request object in a context variable
   using middleware is a workable solution.
   - However, be mindful of potential issues like variable name conflicts
   and unnecessary data passed to every template.

Choosing the Best Approach:

The best solution depends on your project's complexity and preference.
Here's a quick guide:

   - Simple Projects: Template Name Prefixing might suffice.
   - More Complex Projects: Consider Template Inheritance with Context
   Processors or Third-Party Packages for better maintainability.
   - Last Resort: Use the Middleware approach cautiously if other options
   aren't feasible.

Remember, the key is to find a balance between simplicity and
maintainability. Leverage built-in features and explore third-party
packages before resorting to complex hacks.

I'm available if you want further assistance or questions about it๐Ÿ˜Ž

Have a good day ahead.

On Wed, May 29, 2024, 5:52 AM Mike Dewhirst  wrote:

> On 28/05/2024 9:09 pm, Antonis Christofides wrote:
>
> Hello,
>
> I use the sites framework for a Django project that serves many different
> domains. But each of those domains has some templates overridden.
>
>
> Might depend on what you are overriding - entire templates or just
> includes or just vars.
>
> I would probably start by refactoring the templates so they were identical
> for all sites and reduce/extract the differences to includes which can be
> selected via contextvars after calling get_current_site() from the view.
>
> Have you looked at template tags?
>
> I use them for displaying additional information on the staging and dev
> sites versus production. Not what you are doing so I haven't thought too
> hard about that. Only worth a thought if you haven't considered it.
>
>
> If I used a different instance of Django (i.e. a different gunicorn
> service) for each domain, I'd have different settings for each site. But
> I'm using a single instance to serve all sites and, wherever I need to, I
> use things that extract the domain from the request, like
> `get_current_site()`. But this doesn't seem to work with templates. A
> custom template loader won't work without a fight because its methods don't
> accept the request object as an argument.
>
> All solutions I've thought about are ugly hacks.
>
>
> Practicality beats purity
>
> The least ugly seems to be to create middleware that stores the request
> object in a contextvar
> . But it strikes me
> that I can't find a simpler solution for this. Is what I want that
> uncommon, or am I missing something?
>
> There's an old closed "wontfix" ticket
>  about this but without
> adequate explanation.
> --
> You received this message because you are subscribed to the Google Groups
> "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-users/175b4601-2038-479b-9581-48d9c196df7cn%40googlegroups.com
> 

Re: How to use different templates for different sites/domains

2024-05-28 Thread Mike Dewhirst

On 28/05/2024 9:09 pm, Antonis Christofides wrote:

Hello,

I use the sites framework for a Django project that serves many 
different domains. But each of those domains has some templates 
overridden.


Might depend on what you are overriding - entire templates or just 
includes or just vars.


I would probably start by refactoring the templates so they were 
identical for all sites and reduce/extract the differences to includes 
which can be selected via contextvars after calling get_current_site() 
from the view.


Have you looked at template tags?

I use them for displaying additional information on the staging and dev 
sites versus production. Not what you are doing so I haven't thought too 
hard about that. Only worth a thought if you haven't considered it.




If I used a different instance of Django (i.e. a different gunicorn 
service) for each domain, I'd have different settings for each site. 
But I'm using a single instance to serve all sites and, wherever I 
need to, I use things that extract the domain from the request, like 
`get_current_site()`. But this doesn't seem to work with templates. A 
custom template loader won't work without a fight because its methods 
don't accept the request object as an argument.


All solutions I've thought about are ugly hacks.


Practicality beats purity

The least ugly seems to be to create middleware that stores the 
request object in a contextvar 
. But it strikes 
me that I can't find a simpler solution for this. Is what I want that 
uncommon, or am I missing something?


There's an old closed "wontfix" ticket 
 about this but without 
adequate explanation.

--
You received this message because you are subscribed to the Google 
Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send 
an email to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/175b4601-2038-479b-9581-48d9c196df7cn%40googlegroups.com 
.



--
We recommend signal.org

Signed email is an absolute defence against phishing. This email has
been signed with my private key. If you import my public key you can
automatically decrypt my signature and be sure it came from me. Your
email software can handle signing.

--
You received this message because you are subscribed to the Google Groups "Django 
users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/befa4ac2-40b8-44da-87c2-cbbe3ed307c6%40dewhirst.com.au.


OpenPGP_signature.asc
Description: OpenPGP digital signature