** Help me get better! If you vote (either way) please leave a comment if you have time and say what was good or bad. I appreciate any and all feedback. Thanks! **
I keep finding places in my apps where I need an isolated snippet of text that can periodically be changed from the admin interface. Most often it's html but sometimes it's text, javascript, or css.
Use it like so:
(Assuming this snippet lives in snippy_snip/models.py and there is a snippet named "Welcome Message" in the database)
from snippy_snip.models import snip
msg = snip("Welcome Message")
Or, you might populate a parameter hash for a template:
def showpage(request):
params = {
'welcome': snip('Welcome Message'),
'video1': snip('Video 1'),
'NavHeader': snip('Nav.SectionHeader'),
}
return render_to_response("main.html", params)
For clarity, *params* might look something like this:
welcome -> "Welcome to our site. Please use the menu on the left..."
video1 - > a YouTube snippet
NavHeader -> Some HTML which comprises the top of a navigation menu.
This is a very simple bit of code but I've found it very useful. It isn't intended for instant changes... Your snippets will cache like anything else, which may cause confusion if you expect immediate changes. And it's probably not great for a high traffic site, but for my moderate traffic sites and workgroup apps I've found it useful.
(This code was created for 0.96, but I'm working to bring it into alignment with the latest svn version of Django, see comments.)
This widget will render a chained select menu powered by JavaScript to make it easier to identify foreign keys. This widget includes danjak's form decorator (http://www.djangosnippets.org/snippets/59/), and Xin Yang's chained select javascript functions (http://www.yxscripts.com/).
I developed this to be used with an IT inventory system. See screenshot here: http://bayimg.com/cAjAGAabN
The models are laid out that location -> area -> room. But the __str__ of area and room did not include unique fields, so the built-in single select box that django uses for ForeignKey's did not work for me.
A few notes:
1: I will not be maintaining this, I am only putting it out here in case it helps others.
2: The chained select menus will only be available to the first form on the page. Reason being: the template names the form, not the django backend. So, I had to reference the form in javascript as document.forms[0].
3: Due to the javascript processing, the chain select menu will not show current values other than the default specified in the javascript. Thus, form_for_instance and a dict of values passed to form_for_model will not pre-set the chained select.
4: The rendered selects are put into a vertical table. No other layout is supported.
5: The select field names for upper-leveled options are "chain_to_[destination_field_name]__[current_selects_model_name].
6: The select name for the destination option is the name that django sends internally, which is usually the field name. The value of each option in the select is the primary key associated with that object.
7: I tried to get this built in to the native form_for_model helper function for use with the default admin site, but failed miserably.
How to get it working (quick version):
1: Define your models
2: From your view, import the form_decorator and ChainSelectWidget (I put them in CustomWidgets.py and made sure it was in the path).
3: Build arguments for the form_decorator eg:
widget_overwrite=dict(field=ChainSelectWidget(order=[(top, 'order_field'), (next, 'order_field'), (field, 'order_field)]
4: Send arguments to form_decorator eg:
callback = form_decorator(widgets=widget_overwrite)
5: Build modified form eg:
mod_formclass = form_for_model(field, formfield_callback=callback)
6: Instance the modified form eg:
instanced_form = mod_formclass()
7: Send instanced form to the templating engine
8: From the template, import the chainedselects function file (replace [] with <>) eg:
[head][script language="javascript" src="path/to/chainedselects.js"][/script]
9: Display the form object as you normally would.
**Attention: this snippet depends on jQuery library to works**
The Admin templates hierarchy does not allow you change the submit line (that buttons bar in the footer of the change view of a model class).
This code shows how to resolve this, using a simple javascript trick. You can read the code and implement using your favorite javascript library (instead of jQuery) or pure JavaScript.
This example regards to User Profile, a common used model class that adds custom fields to a user in the authentication system.
To use this, you must put this template code in a file with the following name:
templates/admin/auth/user/change_form.html
Hello,
This is a port of a php class used to generate XML taconite command documents, useful for (very) easy and powerful ajaxy stuff, if you don't know what that is just check it there in french : http://www.desfrenes.com/playground/taconite/ or there in english : http://www.malsup.com/jquery/taconite/.
Basically what it does is generate an XML document that is later processed by a javascript plugin which executes a serie of DOM modifications.
About the code, I'm a Django beginner as well as a Python beginner so kind advices are welcome.
Cheers.
When you need to include a specific javascript file/code snippet in your page, it's always better to do it at the bottom of your page to avoid to block the rendering too soon. This tag provide you a nice way to include and launch only what is needed:
Example in an included template that need to display google maps:
{% dict js_file google_api %}
<script src="http://www.google.com/jsapi?key={{ MAPS_API_KEY }}" type="text/javascript" charset="utf-8"></script>
<script src="{{MEDIA_URL}}js/map.display.js" type="text/javascript">...</script>
{% enddict %}
{% dict js_code link_map %}
$('.show-map').click(function() {
...
});
$('.hide-map').click(function() {
...
});
{% enddict %}
Finaly you just have to add this to the very bottom of your base.html file:
....
</body>
{% for k,v in js_file.items %}
{{v}}
{% endfor %}
<script type="text/javascript">
/* <![CDATA[ */
{% for k,v in js_code.items %}
{{v}}
{% endfor %}
/* ]]> */
</script>
</html>
This snippet is an example of an ajax progress bar (using jquery) that you might use in conjunction with <http://www.djangosnippets.org/snippets/678/>.
1. Generates a uuid and adds X-Progress-ID to the forms action url.
2. Adds the progress bar to the page. (you'll have to add some css styling for this)
3. Makes period ajax requests to update the progress bar.
Block tag version of [escapejs](http://www.djangoproject.com/documentation/templates/#escapejs). Handy when using inclusion tags to generate AJAX responses.
Uses jsmin or jspacker to compact javascript files (usage example in [this blog post](http://pedro.valelima.com/blog/2008/jan/17/deploying-compacted-javascript-django/))
Based on jspacker by Dean Edwards,
Python port by Florian Schulze: http://www.crowproductions.de/repos/main/public/packer/jspacker.py
Packs javascript
Example usage::
{% packjs %}
var a = 1;
var b = 2;
var c = 3;
alert(a+b);
{% endpackjs %}
This example would return this script::
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[c]=k[c]||c;k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp("\\b"+e(c)+"\\b","g"),k[c]);return p}('0 5 = 1;\n 0 4 = 2;\n 0 7 = 3;\n 6(5+4);\n',8,8,'var||||b|a|alert|c'.split('|'),0,{}))
**Javascript merging and compression templatetag**
One of the most important things for improving web performance is to reduce the number of HTTP requests. This is a templatetag that merges several javascript files (compressing its code) into only one javascript.
It checks if this merged file is up to date, comparing modification time with the other javascripts to merge.
Usage:
{% load jsmerge %}
{% jsmerge mergedfile js/file1.js js/file2.js js/file3.js %}
The previous code will:
1. Search in `settings.MEDIA_ROOT` for all files passed by parameter.
2. Create a `/path/to/media_root/mergedfile.js` (if it doesn't exist or it's not up to date). This file is a merging plus compression of all javascripts.
3. Return this HTML fragment: `<script type="text/javascript" src="/media_url/mergedfile.js"></script>`
This snippet allows you to use YUI's autocomplete widget in a easy way.
1. Download YUI (http://developer.yahoo.com/yui/) library and put it into MEDIA folder (in my case I put YUI/build/ directory as base/yui/ in my MEDIA folder)
2. Create lookup view for your autocomplete field.
See 'test_ajax_ac' function to see how this lookup view may be built. You have to define JsonResponse somewhere in your files. JsonResponse is taken from: http://www.djangosnippets.org/snippets/154/
3. Define url for newly created view in urls.py (in usual way)
4. Include necessary .js and .css files in your page (see example in test_ajax.html)
5. Assign widget to a field - see form's __init__ at UserForm in the example.
Additional (optional) parameters are: format_result_fname (name of javascript function for formatting results - see YUI docs for examples)), item_select_handler_fname (name of javascript function for handling item select event (see YUI docs)).
When using YUI take care about proper skin - you'll possibly need to define wrapper like:
`<div class="yui-skin-sam">....</div>`
around your html code.
I've been using this along with [prototype](http://www.prototypejs.org) to make simple ajax calls. In essence you make the calls from the client with...
new Ajax.Request('url',{parameters:{'someparam':$('someparam').value}}); return false;
On the onsubmit event of a form, onclick or whatever. Note that the return false is important to prevent the page from reloading. Sending some javascript to be executed back to the client is then as simple as setting up your view to return:
return HttpJavascriptResponse('alert("boing");')
So, yeah, prototype does the real work and this class does little other than make it clear what our intentions are and reduce the opportunities for typos. But it works for me.
newforms widget for autocompleting text fields using jquery autocomplete plugin: http://jquery.bassistance.de/autocomplete/
to be implemented:
- store the pk value into an hidden field
- handling ChoiceFields and many others
massimo dot scamarcia at gmail.com
This is a reasonably straight forward port of functionality provided by the `django.utils.dateformat` module into a method extending JavaScript's Date object. Its intended use is to allow client-side dynamic content to share the same date & time string formatting as Django template markup. By using this in conjunction with a context processor (to pass a format string to all templates) you can switch formats for both server-generated & client-generated dates across a complete site with a single setting.
The function supports *almost* the entire format -- as listed by the Django documentation for the [now template tag](http://www.djangoproject.com/documentation/templates/#now) -- with the exception of "I" & "T".
As a 'dumb' illustration, the following template tag usage:
It is {% now "jS F Y H:i" %}
...could equate to the following:
It is <script type="text/javascript">var now = new Date(); document.write(now.strfdate('jS F Y H:i'));</script>
It's not extensively tested (I only wrote it over the weekend), but seems to be working okay. Feel free to leave any corrections or suggestions in the comments, and I'll try to keep this entry updated if I make any fixes or changes.
If you use javascript code with Django-template filter or other related things, it will be not sufficient to qoute string in javascript. This filter escape the string and quote it.