def translate_url(context, language): """ Translates the current URL for the given language code, eg: {% translate_url "de" %} """ try: request = context["request"] except KeyError: return "" view = resolve(request.path) current_language = translation.get_language() translation.activate(language) if not view.namespace and view.url_name == "home": url = home_slug() else: try: url = reverse(view.func, args=view.args, kwargs=view.kwargs) except NoReverseMatch: try: url_name = (view.url_name if not view.namespace else '%s:%s' % (view.namespace, view.url_name)) url = reverse(url_name, args=view.args, kwargs=view.kwargs) except NoReverseMatch: url_name = "admin:" + view.url_name url = reverse(url_name, args=view.args, kwargs=view.kwargs) translation.activate(current_language) qs = context['request'].META.get("QUERY_STRING", "") if qs: url += "?" + qs return url
def page(request, slug, template=u"pages/page.html", extra_context=None): """ Select a template for a page and render it. The request object should have a ``page`` attribute that's added via ``mezzanine.pages.middleware.PageMiddleware``. The page is loaded earlier via middleware to perform various other functions. The urlpattern that maps to this view is a catch-all pattern, in which case the page attribute won't exist, so raise a 404 then. For template selection, a list of possible templates is built up based on the current page. This list is order from most granular match, starting with a custom template for the exact page, then adding templates based on the page's parent page, that could be used for sections of a site (eg all children of the parent). Finally at the broadest level, a template for the page's content type (it's model class) is checked for, and then if none of these templates match, the default pages/page.html is used. """ from mezzanine.pages.middleware import PageMiddleware if not PageMiddleware.installed(): raise ImproperlyConfigured("mezzanine.pages.middleware.PageMiddleware " "(or a subclass of it) is missing from " + "settings.MIDDLEWARE_CLASSES or " + "settings.MIDDLEWARE") if not hasattr(request, "page") or request.page.slug != slug: raise Http404 # Check for a template name matching the page's slug. If the homepage # is configured as a page instance, the template "pages/index.html" is # used, since the slug "/" won't match a template name. template_name = str(slug) if slug != home_slug() else "index" templates = [u"pages/%s.html" % template_name] method_template = request.page.get_content_model().get_template_name() if method_template: templates.insert(0, method_template) if request.page.content_model is not None: templates.append(u"pages/%s/%s.html" % (template_name, request.page.content_model)) for parent in request.page.get_ascendants(for_user=request.user): parent_template_name = str(parent.slug) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append( u"pages/%s/%s.html" % (parent_template_name, request.page.content_model)) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append(u"pages/%s.html" % request.page.content_model) templates.append(template) if request.is_ajax() or (template != "pages/unifypage.html" and template != "pages/page.html"): templates = template return TemplateResponse(request, templates, extra_context or {})
def page(request, slug, template=u"pages/page.html", extra_context=None): """ Select a template for a page and render it. The ``extra_context`` arg will include a ``page`` object that's added via ``mezzanine.pages.middleware.PageMiddleware``. The page is loaded via the middleware so that other apps with urlpatterns that match the current page can include a page in their template context. The urlpattern that maps to this view is a catch-all pattern, in which case the page instance will be None, so raise a 404 then. For template selection, a list of possible templates is built up based on the current page. This list is order from most granular match, starting with a custom template for the exact page, then adding templates based on the page's parent page, that could be used for sections of a site (eg all children of the parent). Finally at the broadest level, a template for the page's content type (it's model class) is checked for, and then if none of these templates match, the default pages/page.html is used. """ from mezzanine.pages.middleware import PageMiddleware if not PageMiddleware.installed(): raise ImproperlyConfigured("mezzanine.pages.middleware.PageMiddleware " "(or a subclass of it) is missing from " + "settings.MIDDLEWARE_CLASSES") extra_context = extra_context or {} try: page = extra_context["page"] except KeyError: raise Http404 # Check for a template name matching the page's slug. If the homepage # is configured as a page instance, the template "pages/index.html" is # used, since the slug "/" won't match a template name. template_name = str(slug) if slug != home_slug() else "index" templates = [u"pages/%s.html" % template_name] method_template = page.get_content_model().get_template_name() if method_template: templates.insert(0, method_template) if page.content_model is not None: templates.append(u"pages/%s/%s.html" % (template_name, page.content_model)) for parent in page.get_ascendants(for_user=request.user): parent_template_name = str(parent.slug) # Check for a template matching the page's content model. if page.content_model is not None: templates.append(u"pages/%s/%s.html" % (parent_template_name, page.content_model)) # Check for a template matching the page's content model. if page.content_model is not None: templates.append(u"pages/%s.html" % page.content_model) templates.append(template) return render(request, templates, extra_context)
def with_ascendants_for_slug(self, slug, **kwargs): """ Given a slug, returns a list of pages from ascendants to descendants, that form the parent/child page relationships for that slug. The main concern is to do this in a single database query rather than querying the database for parents of a given page. Primarily used in ``PageMiddleware`` to provide the current page, which in the case of non-page views, won't match the slug exactly, but will likely match a page that has been created for linking to the entry point for the app, eg the blog page when viewing blog posts. Also used within ``Page.get_ascendants``, which gets called in the ``pages.views`` view, for building a list of possible templates that can be used for the page. If a valid chain of pages is found, we also assign the pages to the ``page._ascendants`` attr of the main/first/deepest page, so that when its ``get_ascendants`` method is called, the ascendants chain can be re-used without querying the database again. This occurs at least once, given the second use-case described above. """ if slug == "/": slugs = [home_slug()] else: # Create a list of slugs within this slug, # eg: ['about', 'about/team', 'about/team/mike'] parts = slug.split("/") slugs = ["/".join(parts[:i]) for i in range(1, len(parts) + 1)] # Find the deepest page that matches one of our slugs. # Sorting by "-slug" should ensure that the pages are in # descendant -> ascendant order. pages_for_user = self.published(**kwargs) pages = list(pages_for_user.filter(slug__in=slugs).order_by("-slug")) if not pages: return [] # Check to see if the other pages retrieved form a valid path # in the page tree, i.e. pages[0].parent == pages[1], # pages[1].parent == pages[2], and so on. If they do, assign # the ascendants to the main/first/deepest page, so that it # can be re-used on calls to its get_ascendants method. pages[0]._ascendants = [] for i, page in enumerate(pages): try: parent = pages[i + 1] except IndexError: # IndexError indicates that this is the last page in # the list, so it should have no parent. if page.parent_id: break # Invalid parent else: if page.parent_id != parent.id: break # Invalid parent else: # Valid parents pages[0]._ascendants = pages[1:] return pages
def page_menu(context, token): """ Return a list of child pages for the given parent, storing all pages in a dict in the context when first called using parents as keys for retrieval on subsequent recursive calls from the menu template. """ # First arg could be the menu template file name, or the parent page. # Also allow for both to be used. template_name = None parent_page = None parts = token.split_contents()[1:] for part in parts: part = Variable(part).resolve(context) if isinstance(part, unicode): template_name = part elif isinstance(part, Page): parent_page = part if template_name is None: try: template_name = context["menu_template_name"] except KeyError: error = "No template found for page_menu in: %s" % parts raise TemplateSyntaxError(error) context["menu_template_name"] = template_name if "menu_pages" not in context: try: user = context["request"].user slug = context["request"].path except KeyError: user = None slug = "" num_children = lambda id: lambda: len(context["menu_pages"][id]) has_children = lambda id: lambda: num_children(id)() > 0 published = Page.objects.published(for_user=user) if slug == admin_url(Page, "changelist"): related = [m.__name__.lower() for m in Page.get_content_models()] published = published.select_related(*related) else: published = published.select_related(depth=2) # Store the current page being viewed in the context. Used # for comparisons in page.set_menu_helpers. if "page" not in context: try: context["_current_page"] = published.get(slug=slug) except Page.DoesNotExist: context["_current_page"] = None elif slug: context["_current_page"] = context["page"] # Some homepage related context flags. on_home is just a helper # indicated we're on the homepage. has_home indicates an actual # page object exists for the homepage, which can be used to # determine whether or not to show a hard-coded homepage link # in the page menu. home = home_slug() context["on_home"] = slug == home context["has_home"] = False # Maintain a dict of page IDs -> parent IDs for fast # lookup in setting page.is_current_or_ascendant in # page.set_menu_helpers. context["_parent_page_ids"] = {} pages = defaultdict(list) for page in published.order_by("_order"): page.set_helpers(context) context["_parent_page_ids"][page.id] = page.parent_id setattr(page, "num_children", num_children(page.id)) setattr(page, "has_children", has_children(page.id)) pages[page.parent_id].append(page) if page.slug == home: context["has_home"] = True context["menu_pages"] = pages # ``branch_level`` must be stored against each page so that the # calculation of it is correctly applied. This looks weird but if we do # the ``branch_level`` as a separate arg to the template tag with the # addition performed on it, the addition occurs each time the template # tag is called rather than once per level. context["branch_level"] = 0 parent_page_id = None if parent_page is not None: context["branch_level"] = getattr(parent_page, "branch_level", 0) + 1 parent_page_id = parent_page.id # Build the ``page_branch`` template variable, which is the list of # pages for the current parent. Here we also assign the attributes # to the page object that determines whether it belongs in the # current menu template being rendered. context["page_branch"] = context["menu_pages"].get(parent_page_id, []) context["page_branch_in_menu"] = False for page in context["page_branch"]: page.in_menu = page.in_menu_template(template_name) page.num_children_in_menu = 0 if page.in_menu: context["page_branch_in_menu"] = True for child in context["menu_pages"].get(page.id, []): if child.in_menu_template(template_name): page.num_children_in_menu += 1 page.has_children_in_menu = page.num_children_in_menu > 0 page.branch_level = context["branch_level"] page.parent = parent_page # Prior to pages having the ``in_menus`` field, pages had two # boolean fields ``in_navigation`` and ``in_footer`` for # controlling menu inclusion. Attributes and variables # simulating these are maintained here for backwards # compatibility in templates, but will be removed eventually. page.in_navigation = page.in_menu page.in_footer = not (not page.in_menu and "footer" in template_name) if page.in_navigation: context["page_branch_in_navigation"] = True if page.in_footer: context["page_branch_in_footer"] = True t = get_template(template_name) return t.render(Context(context))
def page_menu(context, token): """ Return a list of child pages for the given parent, storing all pages in a dict in the context when first called using parents as keys for retrieval on subsequent recursive calls from the menu template. """ # First arg could be the menu template file name, or the parent page. # Also allow for both to be used. template_name = None parent_page = None parts = token.split_contents()[1:] for part in parts: part = Variable(part).resolve(context) if isinstance(part, unicode): template_name = part elif isinstance(part, Page): parent_page = part if template_name is None: try: template_name = context["menu_template_name"] except KeyError: error = "No template found for page_menu in: %s" % parts raise TemplateSyntaxError(error) context["menu_template_name"] = template_name if "menu_pages" not in context: try: user = context["request"].user slug = context["request"].path except KeyError: user = None slug = "" num_children = lambda id: lambda: len(context["menu_pages"][id]) has_children = lambda id: lambda: num_children(id)() > 0 rel = [m.__name__.lower() for m in Page.get_content_models()] published = Page.objects.published(for_user=user).select_related(*rel) # Store the current page being viewed in the context. Used # for comparisons in page.set_menu_helpers. if "page" not in context: try: context["_current_page"] = published.get(slug=slug) except Page.DoesNotExist: context["_current_page"] = None elif slug: context["_current_page"] = context["page"] # Some homepage related context flags. on_home is just a helper # indicated we're on the homepage. has_home indicates an actual # page object exists for the homepage, which can be used to # determine whether or not to show a hard-coded homepage link # in the page menu. home = home_slug() context["on_home"] = slug == home context["has_home"] = False # Maintain a dict of page IDs -> parent IDs for fast # lookup in setting page.is_current_or_ascendant in # page.set_menu_helpers. context["_parent_page_ids"] = {} pages = defaultdict(list) for page in published.order_by("_order"): page.set_helpers(context) context["_parent_page_ids"][page.id] = page.parent_id setattr(page, "num_children", num_children(page.id)) setattr(page, "has_children", has_children(page.id)) pages[page.parent_id].append(page) if page.slug == home: context["has_home"] = True context["menu_pages"] = pages # ``branch_level`` must be stored against each page so that the # calculation of it is correctly applied. This looks weird but if we do # the ``branch_level`` as a separate arg to the template tag with the # addition performed on it, the addition occurs each time the template # tag is called rather than once per level. context["branch_level"] = 0 parent_page_id = None if parent_page is not None: context["branch_level"] = getattr(parent_page, "branch_level", 0) + 1 parent_page_id = parent_page.id # Build the ``page_branch`` template variable, which is the list of # pages for the current parent. Here we also assign the attributes # to the page object that determines whether it belongs in the # current menu template being rendered. context["page_branch"] = context["menu_pages"].get(parent_page_id, []) context["page_branch_in_menu"] = False for page in context["page_branch"]: page.in_menu = page.in_menu_template(template_name) page.num_children_in_menu = 0 if page.in_menu: context["page_branch_in_menu"] = True for child in context["menu_pages"].get(page.id, []): if child.in_menu_template(template_name): page.num_children_in_menu += 1 page.has_children_in_menu = page.num_children_in_menu > 0 page.branch_level = context["branch_level"] page.parent = parent_page # Prior to pages having the ``in_menus`` field, pages had two # boolean fields ``in_navigation`` and ``in_footer`` for # controlling menu inclusion. Attributes and variables # simulating these are maintained here for backwards # compatibility in templates, but will be removed eventually. page.in_navigation = page.in_menu page.in_footer = not (not page.in_menu and "footer" in template_name) if page.in_navigation: context["page_branch_in_navigation"] = True if page.in_footer: context["page_branch_in_footer"] = True t = get_template(template_name) return t.render(Context(context))
def page(request, slug, template="pages/page.html", extra_context=None): """ Select a template for a page and render it. The request object should have a ``page`` attribute that's added via ``mezzanine.pages.middleware.PageMiddleware``. The page is loaded earlier via middleware to perform various other functions. The urlpattern that maps to this view is a catch-all pattern, in which case the page attribute won't exist, so raise a 404 then. For template selection, a list of possible templates is built up based on the current page. This list is order from most granular match, starting with a custom template for the exact page, then adding templates based on the page's parent page, that could be used for sections of a site (eg all children of the parent). Finally at the broadest level, a template for the page's content type (it's model class) is checked for, and then if none of these templates match, the default pages/page.html is used. """ from mezzanine.pages.middleware import PageMiddleware if not PageMiddleware.installed(): raise ImproperlyConfigured( "mezzanine.pages.middleware.PageMiddleware " "(or a subclass of it) is missing from " + "settings.MIDDLEWARE_CLASSES" ) if not hasattr(request, "page") or request.page.slug != slug: raise Http404 # Check for a template name matching the page's slug. If the homepage # is configured as a page instance, the template "pages/index.html" is # used, since the slug "/" won't match a template name. template_name = str(slug) if slug != home_slug() else "index" templates = ["pages/%s.html" % template_name] method_template = request.page.get_content_model().get_template_name() if method_template: templates.insert(0, method_template) if request.page.content_model is not None: templates.append("pages/%s/%s.html" % (template_name, request.page.content_model)) for parent in request.page.get_ascendants(for_user=request.user): parent_template_name = str(parent.slug) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append("pages/%s/%s.html" % (parent_template_name, request.page.content_model)) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append("pages/%s.html" % request.page.content_model) templates.append(template) # added by RobinWang ss = slug.split("/") if len(ss) == 1: categorys = BlogCategory.objects.all() categoryslug = "" for c in categorys: if c.slug == ss[0]: categoryslug = ss[0] break if categoryslug != "": blogs = getposts(request, category=categoryslug) extra_context["blog_posts"] = blogs return render(request, templates, extra_context or {})
def page(request, slug, template=u"pages/page.html", extra_context=None): """ Select a template for a page and render it. The request object should have a ``page`` attribute that's added via ``mezzanine.pages.middleware.PageMiddleware``. The page is loaded earlier via middleware to perform various other functions. The urlpattern that maps to this view is a catch-all pattern, in which case the page attribute won't exist, so raise a 404 then. For template selection, a list of possible templates is built up based on the current page. This list is order from most granular match, starting with a custom template for the exact page, then adding templates based on the page's parent page, that could be used for sections of a site (eg all children of the parent). Finally at the broadest level, a template for the page's content type (it's model class) is checked for, and then if none of these templates match, the default pages/page.html is used. """ from mezzanine.pages.middleware import PageMiddleware if not PageMiddleware.installed(): raise ImproperlyConfigured("mezzanine.pages.middleware.PageMiddleware " "(or a subclass of it) is missing from " + "settings.MIDDLEWARE_CLASSES") obj=None if not hasattr(request, "page") or request.page.slug != slug: split=slug.split('/') article=split.pop(-1) obj=get_object_or_404(Article,slug=article) if obj: slug="/".join(split)+"/detail" # Check for a template name matching the page's slug. If the homepage # is configured as a page instance, the template "pages/index.html" is # used, since the slug "/" won't match a template name. template_name = str(slug) if slug != home_slug() else "index" templates = [u"pages/%s.html" % template_name] if obj: templates.append("pages/detail.html") obj.prepare_content(request) return TemplateResponse(request, templates, {'article':obj}) method_template = request.page.get_content_model().get_template_name() if method_template: templates.insert(0, method_template) if request.page.content_model is not None: templates.append(u"pages/%s/%s.html" % (template_name, request.page.content_model)) for parent in request.page.get_ascendants(for_user=request.user): parent_template_name = str(parent.slug) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append(u"pages/%s/%s.html" % (parent_template_name, request.page.content_model)) # Check for a template matching the page's content model. if request.page.content_model is not None: templates.append(u"pages/%s.html" % request.page.content_model) templates.append(template) return TemplateResponse(request, templates, extra_context or {})