Footer with Keyword Links

400 views
Skip to first unread message

ne...@vidyasource.com

unread,
Apr 25, 2013, 12:28:52 AM4/25/13
to mezzani...@googlegroups.com
I want to create a custom footer where there are keywords (representing popular search terms) linking to pages with all items tagged with those keywords. In other words, I could have the word "Cake" in the footer as a hyperlink, and clicking that link would take me to the same page as would typing "Cake" in the search box in the upper right and clicking "Go."

At the moment, I would like to hardcode these keywords according to what I imagine people would most likely want to click on, so there is no need for any major intelligence. However, I am not sure how to generate the hyperlinks. I suppose ideally I would like to write a function where I pass an array of strings (the keywords) and it returns the HTML for the list of hyperlinks that each map to the corresponding tagged content like so:

<div>
<ul>
  <li><a href="/cakestuff">Cake</a</li>
  <li><a href="/cookiestuff">Cookies</a</li>
</ul>
</div>

I am at a loss on how to do this.

Any insight is appreciated.

Thanks.

Stephen McDonald

unread,
Apr 25, 2013, 12:37:04 AM4/25/13
to mezzani...@googlegroups.com
I guess you'd need a urlpattern and view for listing pages by keyword. You could use the blog app as a guide, as it already does this and uses the same base classes as pages do, so all the code's already there:

--
You received this message because you are subscribed to the Google Groups "Mezzanine Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mezzanine-use...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Stephen McDonald
http://jupo.org

ne...@vidyasource.com

unread,
May 3, 2013, 10:52:35 PM5/3/13
to mezzani...@googlegroups.com, st...@jupo.org
To bring back some context, my goal is to create a snippet of HTML with a collection of keywords and links for each. Each link takes you to the same page you would go to if you used the search functionality on the upper right of the screen. For example, clicking on "Cake" in this HTML snippet would take you to the same page that searching on the term "Cake" on "Everything" would.

To solve this I have followed Stephen's advice. I created an app called "keywords" with urls.py and views.py

In views.py I have the following:

def keyword_list(request, template="keywords/popular_keywords.html"):
    templates = []
    templates.append(template)
    context = {"popular_keywords": _popular_keywords()}
    return  render(request, templates, context)

where  _popular_keywords() is a function that returns a dictionary of keywords (map of string to array of strings). Trust me this dictionary is populated.


In popular_keywords.html I have this

<ul>
        {% for category, keywords in popular_keywords.items %}
            <li>
                <div class="subtitle">{{ category }}</div>
                <ul>
                    {% for keyword in keywords %}
                        <li><a href="{% url "matching_items_list" keyword %}">{{ keyword }}</a></li>
                    {% endfor %}
                </ul>
            </li>
        {% endfor %}
    </ul>

Meanwhile in urls.py I have this:

urlpatterns = patterns("vidya.keywords.views",
                       url("^%stag/(?P<tag>.*)%s$" % _slashes, "matching_items_list",
                           name="matching_item_list_tag")
)


Finally, matching_items_list is in views.py and rips off some Mezzanine code as Stephen suggested:

def matching_items_list(request, tag=None, template="keywords/keyword_matched_list.html"):
    settings.use_editable()
    templates = []
    blog_posts = BlogPost.objects.published(for_user=request.user)
    if tag is not None:
        tag = get_object_or_404(Keyword, slug=tag)
        blog_posts = blog_posts.filter(keywords__in=tag.assignments.all())
    prefetch = ("keywords__keyword")
    blog_posts = blog_posts.select_related("user").prefetch_related(*prefetch)
    blog_posts = paginate(blog_posts, request.GET.get("page", 1),
                          settings.BLOG_POST_PER_PAGE,
                          settings.MAX_PAGING_LINKS)
    context = {"blog_posts": blog_posts, "tag": tag}
    templates.append(template)
    return render(request, templates, context)


After all this, when I try to add the content to the base.html template 

{% include "keywords/popular_keywords.html" %}

I don't get an error, but I don't see the generated content. I just see the "Popular Topics" hardcoded HTML at the top of my popular_keywords.html template.

Can anyone tell me how I can be generating nothing? I presume there is something basic I am missing, so any pointers in the right direction are appreciated.

Thanks.

Stephen McDonald

unread,
May 3, 2013, 10:58:00 PM5/3/13
to mezzani...@googlegroups.com
Just including the template isn't going to run the view function you wrote.

I'd have a read up on the Django docs - if you're going to include it in the base template, you probably want to write a custom inclusion tag instead of a view function.

Neil Chaudhuri

unread,
May 3, 2013, 11:11:05 PM5/3/13
to mezzani...@googlegroups.com
Sounds like my reading has been incomplete thus far.

I've started reading (https://docs.djangoproject.com/en/dev/howto/custom-template-tags/) and it seems fairly involved. That's cool, but I just want to make sure I am not going over-the-top for something that strikes me as relatively trivial. I have two questions:
  • What are the situations where merely including a template is sufficient? (As my situation is apparently not one of them)
  • I may be reading too much into it, but your phrasing suggested to me that there are different strategies for including in the base template vs. other templates. Is that correct? If so, can you elaborate?

And with that, I will do my best to focus my questions on Mezzanine proper.

Thanks.


You received this message because you are subscribed to a topic in the Google Groups "Mezzanine Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mezzanine-users/Pr53CYGEjVM/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to mezzanine-use...@googlegroups.com.

Stephen McDonald

unread,
May 3, 2013, 11:33:37 PM5/3/13
to mezzani...@googlegroups.com
On Sat, May 4, 2013 at 1:11 PM, Neil Chaudhuri <ne...@vidyasource.com> wrote:
Sounds like my reading has been incomplete thus far.

I've started reading (https://docs.djangoproject.com/en/dev/howto/custom-template-tags/) and it seems fairly involved. That's cool, but I just want to make sure I am not going over-the-top for something that strikes me as relatively trivial. I have two questions:
  • What are the situations where merely including a template is sufficient? (As my situation is apparently not one of them)

When they don't need any extra data and it's simply a dumb include for the sake of repeating some HTML. In your case you're trying to load extra data for use in the include file though, so there's more to it, but you're actually doing that in a view function, which is the wrong spot - view functions are bound to particular urls (via urlpatterns), but you're including the template in every single page (by way of using base.html).
 
  • I may be reading too much into it, but your phrasing suggested to me that there are different strategies for including in the base template vs. other templates. Is that correct? If so, can you elaborate?
It depends entirely on what you're trying to do. If you want something visible in every single page, then base.html since all other templates extend from it by default. If you want something on one particular page, then use its specific template.

But please - there's nothing mentioned here that isn't covered in the exhaustive Django docs. Please read them thoroughly :-)
Reply all
Reply to author
Forward
0 new messages