def get_template_sources(self, template_name, template_dirs=None): """ Return possible absolute paths to "template_name" in the current theme and any themes it inherits from. Any paths that don't lie inside one of the template dirs are excluded from the result set for security reasons. """ request = get_current_request() mobile = (request and request.mobile) active_theme = get_active_theme() theme = get_theme(active_theme) cached_theme, theme_search_info = self.cached_theme_search_info # If the theme changed or the user is previewing a different theme, # recalculate theme_search_info. # Note that this Loader instance may be shared between multiple threads, # so you must be careful when reading/writing # self.cached_theme_search_info to ensure that writes in one thread # cannot cause unexpected behavior in another thread that is # reading/writing self.cached_theme_search_info at the same time. if cached_theme != theme: theme_search_info = [] for cur_theme in get_theme_search_order(theme): if is_builtin_theme(cur_theme) or not settings.USE_S3_THEME: theme_search_info.append( (cur_theme, get_theme_root(cur_theme), False)) else: theme_search_info.append((cur_theme, cur_theme, True)) if theme == active_theme: self.cached_theme_search_info = (theme, theme_search_info) for cur_theme, cur_theme_root, use_s3_theme in theme_search_info: for template_path in (['mobile', 'templates'] if mobile else ['templates']): if not use_s3_theme: try: template_file = safe_join(cur_theme_root, template_path, template_name) except SuspiciousFileOperation: # The joined path was located outside of template_path, # although it might be inside another one, so this isn't # fatal. continue else: template_file = os.path.join(cur_theme_root, template_path, template_name) origin = Origin(name=template_file, template_name=template_name, loader=self) origin.theme = cur_theme origin.use_s3_theme = use_s3_theme yield origin
def app_list(request, template_name="theme_editor/app_list.html"): selected_theme = request.GET.get("theme_edit", get_theme()) if not is_valid_theme(selected_theme): raise Http404(_('Specified theme does not exist')) if is_theme_read_only(selected_theme): raise Http403 theme_list = get_theme_search_order(selected_theme)[1:] app_list = app_templates.keys() return render_to_resp(request=request, template_name=template_name, context={ 'current_theme': selected_theme, 'apps': theme_list + sorted(app_list, key=lambda app: app[0]), })
def get_default_template_choices(): newsletters_relative_path = 'newsletters/templates/default/' default_templates = [] for cur_theme in get_theme_search_order(): template_path = os.path.join(get_theme_root(cur_theme), 'templates', newsletters_relative_path) if os.path.isdir(template_path): default_templates += os.listdir(template_path) default_templates = list(set(default_templates)) default_templates.sort() template_choices = [] for template in default_templates: template_choices.append((newsletters_relative_path + template, os.path.splitext(template)[0])) return template_choices
def handle_simple(cls, path, local_only, template=None, theme=None): active_theme = get_active_theme() theme = get_theme(active_theme) global _cached_theme_search_info cached_theme, theme_search_info = _cached_theme_search_info # If the theme changed or the user is previewing a different theme, # update _cached_theme_search_info. # Note that _cached_theme_search_info may be shared between multiple # threads, so you must be careful when reading/writing # _cached_theme_search_info to ensure that writes in one thread cannot # cause unexpected behavior in another thread that is reading/writing # _cached_theme_search_info at the same time. if cached_theme != theme: theme_search_info = [] for cur_theme in get_theme_search_order(theme): if is_builtin_theme(cur_theme): cur_theme_dir = get_builtin_theme_dir(cur_theme) static_path = os.path.join(settings.STATIC_ROOT, 'themes', cur_theme_dir) if not os.path.isdir(static_path): continue local_static_url = '%sthemes/%s/' % ( settings.LOCAL_STATIC_URL, cur_theme_dir) static_url = '%sthemes/%s/' % (settings.STATIC_URL, cur_theme_dir) theme_search_info.append( (static_path, local_static_url, static_url)) else: cur_theme_root = get_theme_root(cur_theme) for static_dir in ['media', 'static']: static_path = os.path.join(cur_theme_root, static_dir) if not os.path.isdir(static_path): continue local_static_url = static_url = '/themes/' + cur_theme + '/' + static_dir + '/' if settings.USE_S3_STORAGE: static_url = '%s/%s/%s/themes/%s/%s/' % ( settings.S3_ROOT_URL, settings.AWS_STORAGE_BUCKET_NAME, settings.AWS_LOCATION, cur_theme, static_dir) theme_search_info.append( (static_path, local_static_url, static_url)) if theme == active_theme: _cached_theme_search_info = (theme, theme_search_info) # Search for static file in themes for static_path, local_static_url, static_url in theme_search_info: if not os.path.exists(os.path.join(static_path, path)): continue return urljoin((local_static_url if local_only else static_url), quote(path)) # Warn about static files that don't exist in either a theme or # STATIC_ROOT if not os.path.exists(os.path.join(settings.STATIC_ROOT, path)): if not template: call = ('local_static' if local_only else 'static') warn('%s() call references non-existent static path "%s"' % (call, path)) else: tag = ('{% local_static %}' if local_only else '{% static %}') theme_str = ('theme "%s"' % (theme) if theme else 'an installed Django app') warn( '%s in template "%s" in %s references non-existent static path "%s"' % (tag, template, theme_str, path)) # Handle {% local_static %} for files not found in a theme if local_only: return urljoin(settings.LOCAL_STATIC_URL, quote(path)) # Default to standard Django {% static %} behavior return super(ThemeStaticNode, cls).handle_simple(path)