Commits

Alexander Pugachev committed 3e72cde

first version.

  • Participants

Comments (0)

Files changed (22)

+Alexander Pugachev <alexander.pugachev@gmail.com>
+
+django-chunks authors:
+django-chunks was originally developed by Clint Ecker
+
+Caching code suggested by Kevin Fricovsky (howiworkdaily.com)

File AUTHORS.txt~

+Alexander Pugachev <alexander.pugachev@gmail.com>
+
+
+django-chunks authors:
+django-chunks was originally developed by Clint Ecker
+
+Caching code suggested by Kevin Fricovsky (howiworkdaily.com)
+Alexander Pugachev <alexander.pugachev@gmail.com>
+
+django-chunks:
+django-chunks was originally developed by Clint Ecker
+
+Caching code suggested by Kevin Fricovsky (howiworkdaily.com)
+Add 'infotips' to INSTALLED_APPS.
+Add 'infotips.middleware.InfotipSettings' to MIDDLEWARE_CLASSES.
+MAke sure caching is on.
+Add (r'', include('infotips.urls')) to urls.py.
+python manage.py syncdb
+
+This app uses django-flashcookie if available.

File INSTALL.txt~

+Add 'infotips' to INSTALLED_APPS.
+Add 'infotips.middleware.InfotipSettings' to MIDDLEWARE_CLASSES.
+Add (r'', include('infotips.urls')) to urls.py.
+python manage.py syncdb
+
+This app uses django-flashcookie if available.
+Copyright (c) 2008, Clint Ecker
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this 
+list of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or 
+other materials provided with the distribution.
+
+Neither the name of the <ORGANIZATION> nor the names of its contributors may 
+be used to endorse or promote products derived from this software without 
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+This application was forked from django-chunks. 
+It was written to be used in 3task (http://3task.com/).
+
+This application was forked from django-chunks. 
+It was written to be used in 3task http://3task.com/.
+
+To show infotips:
+
+{% load infotips_tags %}
+
+{% infotip "thekey" %}
+{% infotip "thekey" 3600 %}
+
+First use outputs content for infotip with key "thekey". Only logged in user who allowed to show infotip with this key will see this infotip.
+Second use does the same, with caching for 3600 seconds.
+
+To show infotips management form:
+
+{% load infotips_tags %}
+
+{% infotips_management %}
+To show infotips:
+
+{% load infotips_tags %}
+
+{% infotip "thekey" %}
+{% infotip "thekey" 3600 %}
+
+First use outputs content for infotip with key "thekey". Only logged in user who allowed to show infotip with this key will see this infotip.
+Second use does the same, with caching for 3600 seconds.
+
+To show infotips management form:
+
+{% load infotips_tags %}
+
+{% infotips_management %}
+{% load infotips_tags %}
+
+{% infotip "thekey" %}
+
+Think of it as flatpages for small bits of reusable content you might want to 
+insert into your templates and manage from the admin interface.
+
+This is really nothing more than a model and a template tag.
+
+By adding `chunks` to your installed apps list in your Django project and 
+performing a `./manage.py syncdb`, you'll be able to add as many "keyed" bits 
+of content chunks to your site.
+
+The idea here is that you can create a chunk of content, name it with a unique
+key (for example: `home_page_left_bottom`) and then you can call this content 
+from a normal template.
+
+Why would anyone want this?
+
+It essentially allows someone to define "chunks" (I had wanted to call it
+ blocks, but that would be very confusing for obvious reasons) of content in 
+your template that can be directly edited from the awesome Django admin 
+interface.  Throwing a rich text editor control on top of it make it even 
+easier.
+
+Template tag usage:
+
+{% load chunks %}
+<html>
+    <head>
+        <title>Test</title>
+    </head>
+    <body>
+        <h1> Blah blah blah</h1>
+        <div id="sidebar">
+            ...
+        </div>
+        <div id="left">
+            {% chunk "home_page_left" %}
+        </div>
+        <div id="right">
+            {% chunk "home_page_right" %}
+        </div>
+    </body>
+</html>
+
+This is really helpful in those cases where you want to use 
+`django.contrib.flatpages` but you need multiple content areas.  I hope this 
+is helpful to people and I'll be making minor edits as I see them necessary.
+
+Caching
+
+If you want to cache the content of your chunks you can pass along a caching
+time argument in your chunk tag.  Example:
+
+{% chunk "home_page_left" 3600 %}
+
+The caching time is specified in seconds.  For caching to work properly you 
+must configure a cache backend in your settings.py.  See the Django
+documentation for more information:
+
+http://www.djangoproject.com/documentation/cache/

File infotips/__init__.py

Empty file added.

File infotips/admin.py

+from django.contrib import admin
+from models import Infotip
+
+class InfotipAdmin(admin.ModelAdmin):
+  list_display = ('key',)
+  search_fields = ('key', 'content')
+
+admin.site.register(Infotip, InfotipAdmin)

File infotips/forms.py

+from django import forms
+from models import Infotip
+
+   
+class SaveForm(forms.Form):
+    next_path = forms.CharField(widget=forms.HiddenInput)
+    infotips = forms.MultipleChoiceField(
+        widget=forms.CheckboxSelectMultiple,
+        choices = [(str(x.id), x.key) for x in Infotip.objects.all()],
+        required=False)

File infotips/middleware.py

+from models import Infotip
+
+class InfotipSettings(object):
+    def process_request(self, request):
+        if request.user.is_authenticated:
+            request.infotips = Infotip.objects.exclude(
+                declined__id=request.user.id).values_list('key', flat=True)
+        else:
+            request.infotips = []

File infotips/models.py

+from django.db import models
+from django.contrib.auth.models import User
+
+class Infotip(models.Model):
+    key = models.CharField(help_text="A unique name for this chunk of content", blank=False, max_length=255, unique=True)
+    content = models.TextField(blank=True)
+    declined = models.ManyToManyField(User)
+    def __unicode__(self):
+        return u"%s" % (self.key,)
+
+    

File infotips/templates/infotips/management_include.html

+<br>
+<br>
+<form action="{% url infotips-save %}" method="post">
+{{ form.as_p }}
+<button name="submit" type="submit" class="button positive">Save</button>
+</form>

File infotips/templatetags/__init__.py

Empty file added.

File infotips/templatetags/infotips_tags.py

+from django import template
+from django.core.cache import cache
+
+from infotips.forms import SaveForm
+from infotips.models import Infotip
+
+register = template.Library()
+
+CACHE_PREFIX = "infotip_"
+
+def do_get_infotip(parser, token):
+    # split_contents() knows not to split quoted strings.
+    tokens = token.split_contents()
+    if len(tokens) < 2 or len(tokens) > 3:
+        raise template.TemplateSyntaxError, "%r tag should have either 2 or 3 arguments" % (tokens[0],)
+    if len(tokens) == 2:
+        tag_name, key = tokens
+        cache_time = 0
+    if len(tokens) == 3:
+        tag_name, key, cache_time = tokens
+    # Check to see if the key is properly double/single quoted
+    if not (key[0] == key[-1] and key[0] in ('"', "'")):
+        raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
+    # Send key without quotes and caching time
+    return InfotipNode(key[1:-1], cache_time)
+    
+class InfotipNode(template.Node):
+    def __init__(self, key, cache_time=0):
+        self.key = key
+        self.cache_time = cache_time
+        
+    def render(self, context):
+        request = template.Variable('request').resolve(context)
+        if self.key in request.infotips:
+            try:
+                cache_key = CACHE_PREFIX + self.key
+                c = cache.get(cache_key)
+                if c is None:
+                    try:
+                        c = Infotip.objects.get(key=self.key)
+                    except Infotip.DoesNotExist:
+                        c = ''
+                    cache.set(cache_key, c, int(self.cache_time))
+                content = c.content
+            except Infotip.DoesNotExist:
+                content = ''
+        else:
+            content = ''
+        return content
+        
+register.tag('infotip', do_get_infotip)
+
+def infotips_management(context):
+    request = context['request']
+    initial = {
+        'next_path': request.path,
+        'infotips': Infotip.objects.exclude(
+            id__in=request.user.infotip_set.values_list('id', flat=True)).values_list('id', flat=True)
+        }
+    form = SaveForm(initial=initial)
+    form.fields['infotips'].choices=[(str(x.id), x.key) for x in Infotip.objects.all()]
+    return {
+        'form': form
+        }
+    
+
+register.inclusion_tag('infotips/management_include.html', takes_context=True)(infotips_management)

File infotips/urls.py

+from django.conf.urls.defaults import *
+from infotips import views
+
+urlpatterns = patterns('',
+    url(r'^infotips/save/$',  views.save, name='infotips-save')
+)

File infotips/views.py

+from django.http import HttpResponseRedirect
+from django.contrib.auth.decorators import login_required 
+from django.shortcuts import get_object_or_404
+from django.utils.translation import ugettext as _
+from django.views.decorators.http import require_POST
+
+from models import Infotip
+from forms import SaveForm
+
+@login_required
+@require_POST
+def save(request):
+    form = SaveForm(request.POST)
+    form.fields['infotips'].choices=[(str(x.id), x.key) for x in Infotip.objects.all()]
+    if form.is_valid():
+        ids = [int(x) for x in form.cleaned_data['infotips']]
+        request.user.infotip_set.remove(*Infotip.objects.filter(id__in=ids))
+        request.user.infotip_set.add(*Infotip.objects.exclude(id__in=ids))
+        if hasattr(request, 'flash'):
+            request.flash.success = _('Infotips settings chaged')
+        return HttpResponseRedirect(form.cleaned_data['next_path'])
+    else:
+        if hasattr(request, 'flash'):
+            request.flash.error = str(form.errors)# HTML markup wont work properly, but we need to show something about error
+        if 'next_path' in request.POST:
+            return HttpResponseRedirect(request.POST['next_path'])
+        else:
+            return HttpResponseRedirect('/')
+    
+        
+from distutils.core import setup
+
+setup(name='chunks',
+      version='0.1',
+      description='Keyed blocks of content for use in your Django templates',
+      author='Clint Ecker',
+      author_email='me@clintecker.com',
+      url='http://code.google.com/p/django-chunks/',
+      packages=['chunks', 'chunks.templatetags'],
+      classifiers=['Development Status :: 4 - Beta',
+                   'Environment :: Web Environment',
+                   'Intended Audience :: Developers',
+                   'License :: OSI Approved :: BSD License',
+                   'Operating System :: OS Independent',
+                   'Programming Language :: Python',
+                   'Topic :: Utilities'],
+      )