Simple static breadcrumb in Django - django

How to create something like this:
If user is in:
http://127.0.0.1:8000/about/ then in my base.html I have:
You are here: <li>Home</li>
Etc.
Is there a simple way?

This can get tricky, depending on what you mean by "breadcrumbs".
Django's URL routing system has no inherent hierarchy since any URL can map to any view.
So the "hierarchy" has to be completely specified by you.
…and passed by you to the template in either your view, or in a context processor.
You'll want to assign both a URL AND a name for the URL (so you know /about/ is "Home").
There are a bajillion ways to do this, and it all sort of depends on how flexible you want it, how complicated your URL patterns get, whether you want to support nesting, etc.
Normally, I just use Django Breadcrumbs. This project handles all of the weirdness of breadcrumbs, has a very easy to use API, and handles even weird cases.
While a full code sample would probably be helpful, it's a long and thorny problem, so you're better off reading the documentation for django-breadcrumbs, and then returning here with questions.

Related

Dynamic templates with Django and Ajax

My question is a bit generic in that my problem is a broad one. I have been working with django for some time, and I really want to move more into doing very dynamic web pages where actual page reloads aren't common.
I have read about the different popular javascript frameworks available, and I always feel like I am missing part of the puzzle, particularly in templating.
What are some of the best practices for keeping my templating code as non redundant as possible. I get the impression that a lot of templating logic will make it's way into the JS in addition to my django templates. I want to avoid situations where I am writing templating code in two different places.
For a very basic example, let's say I am writing some template code inside Django for an input field that has a set number of attributes. I have then also written in JS that when I click on a button, another input field of the same type is generated with all the appropriate attributes. In practice this could be a form that takes an arbitrary amount of e-mail addresses. The problem I see is that when I want to change something about that input field, I need to do it in two places.
Is there a particular development paradigm or work flow that I am unaware of? How are issues like this generally avoided?
Recommendations on frameworks would be amazing too!
as you mentioned above:
Use Django Template language. Pass the data from view to template dynamically.
Read Django Template Language documentation.
For JS :
its better to write your js in home.html.... use {% include %} tag for other html

Alternate URL router for Django

How would you go about using django models and templates, but not the URL routing system? I'd like to swap out the urls.py system for something like PHP where the URL tells you exactly where the code is that's running. Or maybe something more automagic like rails uses -- where the URL always includes the same components like app name, model name and view name.
I just disagree with the line from the django philosophy statement that "Tying URLs to Python function names is a Bad And Ugly Thing." Pretty URLs just aren't all that important to me, and IMVHO not worth the complexity of climbing through a maze of indirection in multiple urls.py files and dozens of regexes to find out what code runs behind a particular URL. It's a personal choice, right? Django is generally pretty modular allowing you to swap out the major components for other ones. So, how would I swap out the part which takes the request URL and decides which view to run?
Are there any alternate URL routers for django out there?
All you need is one line in your urls.py that matches everything, and then just write your handler/dispatcher as a view. That handler does whatever you want based on the parts of the URL....
I've never heard of anyone successfully swapping out Django's URL routing system. There's certainly no hook for it - core.handlers.base.BaseHandler.get_response calls urlresolvers.RegexURLResolver directly. Conceivably, you could add a middleware at the bottom of the stack that dispatches to your own URL resolution system and returns the response, thus bypassing the Django system, but it's a bit kludgy.
If you're after something more like Rails, you might want to try one of the other frameworks - Pyramid, for example, uses a system of Routes very similar to Rails'. Pyramid is much more pluggable than Django, so you should be able to plug in the Jinja2 templating system, which is based on Django's. However, there's no way to use Django's ORM seperately, so you'd need to use SQLAlchemy (which can be used in a way that's not massively different).

Django - Static content display based on URL

I'm working on a Django site with a basic three column design. Left column navigation, center column content and right column URL specific content blocks.
My question is about the best method of controlling the URL specific content blocks in the right column.
I am thinking of something along the lines of the Flatpages app that will make the content available to the template context if the URL matches a pre-determined pattern (perhaps regex?).
Does anyone know if such an app already exists?
If not, I am looking for some advice about the best way to implement it. Particularly in relation to the matching of patterns to the current URL. Is there any good way to re-use parts of the Django URL dispatcher for this use?
Django CMS is a good suggestion, it depends on how deep you want to go. If this is just the beginning of different sorts of dynamic content you want then you should go that way for sure.
A simple one-off solution would be something like this:
You would just need to write a view and add some variables on the end of the URL that would define what showed up there. Depending on how fancy you need to get, you could just create a simple models, and just map the view to the model key
www.example.com/content/sidecontent/jokes/
so if "jokes" was your block of variable sidecontent (one of many in your sides model instances) the urls.py entry for that would be
(r'^content/sidecontent/(?P<side>)/$,sides.views.showsides),
and then in your sides app you have a view with a
def showsides(request, side):
Sides.objects.get(pk=side)
etc...
For something like this I personally would use Django CMS. It's like flatpages on steroids.
Django CMS has a concept of Pages, Templates, and Plugins. Each page has an associated template. Templates have placeholders where you can insert different plugins. Plugins are like mini-applications that can have dynamic model-based content.
Although Django-CMS is an interesting suggestion, there are quite a few projects that do specifically what you've requested - render blocks of content based on a URL. The main one that I know about is django-flatblocks.

How to conditionally skin an existing site (for partner branding)

I've got an existing Django site, with a largish variety of templates in use. We've agreed to offer a custom-skinned version of our site for use by one of our partners, who want the visual design to harmonize with their own website. This will be on a separate URL (which we can determine), using a subset of the functionality and data from our main site.
So my question is: what's the best way to add reskin functionality to my site, without duplicating a lot of code or templates?
As I see it, there are several components which need to work together:
URL: need to have a different set of URLs which points to the partner-branded version of the site, but which can contain all the standard path info the site needs to build pages.
Template 'extends': need to have the templates extend a different base, like {% extends 'partner.html' %} instead of {% extends 'base.html' %}
View logic: need to let the views know when this is the partner-branded version, so they can change the business logic appropriately
My idea so far is to put the partner site on a subdomain, then use a middleware to parse the domain name and add 'partner' and 'partner_template' variables to the request object. Thus, I can access request.partner inside my views, to handle business logic. Then, I have to edit all my templates to look like this:
{% extends request.partner_template|default:'base.html' %}
(According to this answer, 'extends' takes a variable just like any other template tag.)
Will this work properly? Is there a better way?
If you are using different settings.py for the different sites you can
specifiy different template loading directories. (Which may default to your unskinned pages.)
Personally I'm not convinced by having different business logic in the same view code, that smells like a hack to me - the same as extensive conditional compilation does in C.
So to sum up.
Use django.contrib.sites and different settings.py
Get a clear idea, how much this is a new app/website using the same data, or just different css/templates.

What's the best way to "embed" a page number in a URL?

I'm developing a blog application using Django. Currently, the URL /blog/ displays the front page of the blog (the first five posts). Visitors can then browse or "page through" the blog entries. This portion is mapped to /blog/browse/{page}/, where page, of course, is an integer that specifies which "page" of blog entries should be displayed.
It's occurred to me, though, that perhaps the "page number" should be an attribute of the querystring instead (e.g., /blog/browse/?page=2), since the content of the browse pages is not static (i.e., as soon as I add another post, /blog/browse/2/ will have different contents than it had before the post was added). This seems to be the way sites like Stack Overflow and Reddit do things. For example, when paging through questions on Stack Overflow, a "page" attribute is used; likewise, Reddit uses a "count" attribute.
Extending this thinking, I realize that I use the same template to render the contents of both /blog/ and /blog/browse/, so it might even make sense to just use a URL like /blog/?page=2 to page through the contents of the blog.
Any suggestions? Is there a "standard" way of doing this, or at least a "best practice" method to use?
For my money, the best general purpose approach to this issue is to use the django-pagination utility. It's incredibly easy to use and your URLs should have the format you desire.
I prefer to use the GET URL parameter, as in URL?pg=#. It's very common and provides a standard visual clue to users about what is going on. If, for instance, I want to bookmark one of those pages or make an external link, I know without thinking that I can drop the pg parameter to point at the "latest" front-page index. With an embedded #, this isn't as obvious... do I leave off the parameter? Do I always have to set it to 1? Is it a different base URL entirely? To me, having pagination through the GET parameter makes for a slightly more sensible URL, since there's an acceptable default if the parameter is omitted and the parameter doesn't affect the base URL.
Also, while I can't prove it, it gives me the warm fuzzy feeling that Google has a better chance at figuring out the nature of that page's content (i.e. that it is a paginated index into further data, and will potentially update frequently) versus a page # embedded inside the URL, which will be more opaque.
That said, I'd say this is 99% personal preference and I highly doubt there's any real functional difference, so go with whatever is easier for and fits in better with your current way of doing things.
EDIT: Forgot to mention that my opinion is Django specific... I have a few Django apps so I'm relatively familiar with the way they build their URLs, and I still use a "pg" GET parameter with those apps rather than embedding it in the URL directly.
It seems like there are two things going on. A static page, that won't change and can be used for permalinking, like an article, as well as a dynamic page that will update frequently. There is no reason you cannot use both. URL rewriting should allow this to work quite nicely. There's no reason to let the implementation control the interface, there is always at least one way to skin every cat.