1

I have a table with address information. It has these fields.

  • address_1
  • address_2
  • city
  • state
  • zip

No field is required. I want to display this in a template and format it nicely. I want line breaks between address_1, address_2, and the city/state/zip line for any of those that exists. I also want a comma between city and state if both exist. What is the best way to accomplish this? I started writing an if statement in the template, but it seemed to be getting a bit unwieldy. The big problem is that the user could enter only a city and state, only a zip code, a full-formed address, or anything between.

raddevon
  • 3,290
  • 4
  • 39
  • 49
  • 1
    Do it in the handler, not the template. It'll be easier with the full expressiveness of python available – Rob Cowie Jul 29 '12 at 23:29
  • @RobCowie I had thought about this too. I seem to remember in the past having some trouble getting HTML from the handler to the template. Any suggestions on how to implement this? UPDATE: Just saw the other answer below. This is probably what I need. – raddevon Jul 29 '12 at 23:49

2 Answers2

3

Many ways of achieving this, none are likely to be that elegant. I'll throw this into the ring... Do this in your handler, and pass address_parts to the template context.

## Gather the address components in groups, removing any that are None
address_parts = filter(None, [
    model_obj.address_1,
    model_obj.address_2,
    u', '.join(filter(None, [model_obj.address_city, model_obj.state])),
    model_obj.zip,
])


## In the template, join the address groups
{{ address_parts|join:"<br>" }}
Rob Cowie
  • 22,259
  • 6
  • 62
  • 56
  • Very nice. This is far better than what I was attempting. Thank you! – raddevon Jul 29 '12 at 23:58
  • This is really very elegant. I learnt 2 new things from your 1 answer which I know can be applied to many parts of my project. Thanks very much! – super9 Jul 30 '12 at 01:42
1

If you add a simple custom filter to append text to variables if they exist:

@register.filter
def append(arg, suffix):
    return arg + suffix if arg else ''

then you can do something like

{{ address_1|append:"<br/>" }}
{{ address_2|append:"<br/>" }}
{{ city|append:", " }}{{ state|append:" " }}{{ zip }}

If you want to do this in a <table> or whatever, you can also use a similar prepend filter.

Danica
  • 28,423
  • 6
  • 90
  • 122
  • This is interesting, but I believe it will always append those tags or characters, correct? I only want to append the breaks, for example, if an address element follows the one being appended to. – raddevon Jul 29 '12 at 23:59
  • @raddevon This approach uses slightly different logic than you're thinking about but results in basically the same thing: if they give `address_1`, then there'll always be a `
    ` after it, but then the next actually present element is next. Two weird things: it'll end in a `
    ` if there's no `city`, `state`, or `zip` but not if there is, and if they give `city` but no `state` there'll be a stray comma after `city`. RobCowie's approach doesn't have these problems but also makes it harder to do custom formatting for each part (if you want to bold states, that'd need to go in the view).
    – Danica Jul 30 '12 at 00:09
  • You also need to make sure that your text is "safe". Otherwise the
    will be displayed as such.
    – Wurzelgogerer Oct 30 '12 at 18:01