text: Opened 6 years ago
  Closed 4 years ago
  Last modified 3 years ago
  #17199 closed Bug (invalid)
  Base Template Loader should return the origin
  Description
  I've been trying to get the origin from the loaders, but the origin was lost when BaseLoader didn't return it. I believe it should return origin... any thoughts? I'm attaching a patch.
  Attachments (1)
  Change History (11)
  comment:1 Changed 6 years ago by
  Changed 6 years ago by
  comment:2 Changed 6 years ago by
  comment:3 Changed 6 years ago by
  Custom
  Loaderclasses should inherit from
  django.template.loader.BaseLoaderand override the
  load_template_source()method, which takes a
  template_nameargument, loads the template from disk (or elsewhere), and returns a tuple:
  (template_string, template_origin).
  The
  load_template()method of the
  Loaderclass retrieves the template string by calling
  load_template_source(), instantiates a
  Templatefrom the template source, and returns a tuple:
  (template, template_origin)
  I hope this clarifies the expected behavior. With this new information, could you explain what Django does wrong exactly, and provide some steps to reproduce the issue -- or upload a test case? Thanks!
  comment:4 Changed 6 years ago by
  Using
  TEMPLATE_DEBUG = True (so that origin is returned, otherwise origin is never actually returned, see
  make_origin() in
  django.template.loader), if I do:
  template, origin = loader.find_template('mytemplate.html'), it does not return origin (this is because
  load_template() in
  BaseLoader explicitly returns None instead of the origin). Same thing with the
  load_template() in the "cached" loader. It returns the tuple
  (template, None).
  After reading that bit of documentation, I can see
  load_template() doesn't even remotely return (as it should) a template_origin, but a string with the
  display_name (and only if the template is not found). I could also make a new patch that would make django consistent with said behavior in the documentation, however,
  BaseLoader.load_template() currently already returns
  display_name instead of the
  origin, and simply changing that could break some things.
  In my opinion, as I said first,
  load_template() should always return origin (as stated in the documentation) and not
  display_name... and only when the template is not found. Whether it should always return origin (even if
  TEMPLATE_DEBUG is not enabled) is yet another dilemma, as the documentation never states
  load_template() returns
  template_origin *only* if
  TEMPLATE_DEBUG is enabled.
  comment:5 Changed 6 years ago by
  I'm reopening because I truly see this being wrong in some way... or I might be. After further digging, it truly seems there are some inconsistencies, and I need the be able to get origin of the template while using
  django.template.loader.find_template(), which I currently can't, the way django code is now.
  comment:6 Changed 6 years ago by
  comment:7 Changed 6 years ago by
  comment:8 Changed 4 years ago by
  #16096 (filed by a core dev) suggests that
  origin
  is purely for debug puposes. That would explain why it's set only when the template isn't found and when
  TEMPLATE_DEBUG = True
  .
  As far as I can tell, you're trying to use the
  origin
  returned by
  BaseLoader.find_template()
  for much more than its purpose.
  Wouldn't #16096 be a much more simple solution for the problem you're trying to solve?
  comment:9 Changed 3 years ago by
  It is true that
  origin is currently used only for debugging purposes, but it could be used for much more. For example, in django-overextends it would allow to better detect cycles between templates. If a tag could know what is the filename of the current template it would know which templates it has to find when extending templates with the same name (should it hide the current one to prevent a cycle or not - it should hide only if current template filename is the same as the filename in
  extends).
  It is true that only origin name would be needed, not whole origin (with template content).
  comment:10 Changed 3 years ago by
  See an example implementation of a
  extends tag which allows arbitrary nesting of extends and prevents import cycles. But for it to work, origin information is needed.
  I'm now not sure if template loaders should return the tempalte and the origin, or the template and the display_name. I guess they should return the origin instead, as it has more information... My doubt rises from the fact BaseLoader returns display_name, but seemingly, cached template loader returns origin when load_template() fails to find the template... My patch returns display_name (from origin.name) as it seems to be consistent with all the other load_template() methods.