]> git.openstreetmap.org Git - osqa.git/commitdiff
Merge pull request #26 from udacity/remove_dj_version
authorJavyer Der Derian <javier@tribalo.net>
Thu, 17 Apr 2014 21:57:23 +0000 (18:57 -0300)
committerJavyer Der Derian <javier@tribalo.net>
Thu, 17 Apr 2014 21:57:23 +0000 (18:57 -0300)
Remove DJANGO_VERSION from the recommended settings

144 files changed:
forum/__init__.py
forum/actions/node.py
forum/actions/user.py
forum/context.py
forum/forms/general.py
forum/forms/qanda.py
forum/middleware/admin_messages.py
forum/middleware/anon_user.py
forum/middleware/cancel.py
forum/models/action.py
forum/models/base.py
forum/models/node.py
forum/models/tag.py
forum/models/user.py
forum/models/utils.py
forum/modules/__init__.py
forum/settings/__init__.py
forum/settings/basic.py
forum/settings/email.py
forum/settings/extkeys.py
forum/settings/minrep.py
forum/settings/repgain.py
forum/settings/upload.py
forum/settings/voting.py
forum/skins/default/media/iepngfix/iepngfix.htc
forum/skins/default/media/iepngfix/iepngfix_tilebg.js
forum/skins/default/media/js/jquery.caret.js
forum/skins/default/media/js/osqa.admin.js
forum/skins/default/media/js/osqa.main.js
forum/skins/default/media/js/viewbox.css
forum/skins/default/templates/401.html
forum/skins/default/templates/403.html
forum/skins/default/templates/404.html
forum/skins/default/templates/500.html
forum/skins/default/templates/account_settings.html
forum/skins/default/templates/answer_edit.html
forum/skins/default/templates/answer_edit_tips.html
forum/skins/default/templates/ask.html
forum/skins/default/templates/auth/auth_settings.html
forum/skins/default/templates/auth/complete.html
forum/skins/default/templates/auth/mail_validation.html
forum/skins/default/templates/auth/signin.html
forum/skins/default/templates/auth/temp_login_email.html
forum/skins/default/templates/auth/temp_login_request.html
forum/skins/default/templates/auth/welcome_email.html
forum/skins/default/templates/base_content.html
forum/skins/default/templates/close.html
forum/skins/default/templates/feedback.html
forum/skins/default/templates/footer.html
forum/skins/default/templates/header.html
forum/skins/default/templates/index.html
forum/skins/default/templates/logout.html
forum/skins/default/templates/node/accept_button.html
forum/skins/default/templates/node/comment_skeleton.html
forum/skins/default/templates/node/comments.html
forum/skins/default/templates/node/favorite_mark.html
forum/skins/default/templates/node/post_controls.html
forum/skins/default/templates/node/report.html
forum/skins/default/templates/node/reviser_info.html
forum/skins/default/templates/node/revision.html
forum/skins/default/templates/node/vote_buttons.html
forum/skins/default/templates/osqaadmin/base.html
forum/skins/default/templates/osqaadmin/dashboard.html
forum/skins/default/templates/osqaadmin/djstyle_base.html
forum/skins/default/templates/osqaadmin/edit_page.html
forum/skins/default/templates/osqaadmin/index.html
forum/skins/default/templates/osqaadmin/moderation.html
forum/skins/default/templates/osqaadmin/nodeman.html
forum/skins/default/templates/osqaadmin/set.html
forum/skins/default/templates/osqaadmin/static_pages.html
forum/skins/default/templates/page.html
forum/skins/default/templates/question.html
forum/skins/default/templates/question_edit.html
forum/skins/default/templates/question_edit_tips.html
forum/skins/default/templates/question_list/count.html
forum/skins/default/templates/question_list/item.html
forum/skins/default/templates/question_list/related_tags.html
forum/skins/default/templates/question_list/sort_tabs.html
forum/skins/default/templates/question_list/subscription_item.html
forum/skins/default/templates/question_list/tag_selector.html
forum/skins/default/templates/question_list/title.html
forum/skins/default/templates/question_retag.html
forum/skins/default/templates/question_summary_list_roll.html
forum/skins/default/templates/questions.html
forum/skins/default/templates/reopen.html
forum/skins/default/templates/search.html
forum/skins/default/templates/sidebar/markdown_help.html
forum/skins/default/templates/sidebar/recent_awards.html
forum/skins/default/templates/sidebar/recent_tags.html
forum/skins/default/templates/sidebar/user_blocks.html
forum/skins/default/templates/static.html
forum/skins/default/templates/subscription_status.html
forum/skins/default/templates/tags.html
forum/skins/default/templates/users/activity.html
forum/skins/default/templates/users/edit.html
forum/skins/default/templates/users/info.html
forum/skins/default/templates/users/menu.html
forum/skins/default/templates/users/signature.html
forum/skins/default/templates/users/stats.html
forum/skins/default/templates/users/subscriptions_management.html
forum/skins/default/templates/users/subscriptions_settings.html
forum/templatetags/__init__.py
forum/templatetags/extra_filters.py
forum/templatetags/extra_tags.py
forum/templatetags/general_sidebar_tags.py
forum/templatetags/node_tags.py
forum/templatetags/question_list_tags.py
forum/templatetags/user_tags.py
forum/urls.py
forum/user_messages/context_processors.py
forum/utils/decorators.py
forum/utils/html.py
forum/utils/html2text.py
forum/views/admin.py
forum/views/auth.py
forum/views/commands.py
forum/views/decorators.py
forum/views/meta.py
forum/views/readers.py
forum/views/users.py
forum/views/writers.py
forum_modules/akismet/startup.py
forum_modules/exporter/templates/running.html
forum_modules/exporter/urls.py
forum_modules/exporter/views.py
forum_modules/facebookauth/authentication.py
forum_modules/facebookauth/templates/button.html
forum_modules/localauth/templates/loginform.html
forum_modules/localauth/urls.py
forum_modules/oauthauth/authentication.py
forum_modules/openidauth/consumer.py
forum_modules/openidauth/templates/openidurl.html
forum_modules/robotstxt/urls.py
forum_modules/sximporter/templates/page.html
forum_modules/sximporter/urls.py
forum_modules/sximporter/views.py
forum_modules/updates/base.py
forum_modules/updates/startup.py
forum_modules/updates/templates/index.html
forum_modules/updates/urls.py
manage.py
settings.py
settings_local.py.dist
urls.py

index 51c0c431c26bb68ed2ccf20fd1374e6a2239938d..fa60dba1d3f1cec275f057e83ae5c545f1bb4476 100644 (file)
@@ -1,5 +1,15 @@
+import threading
+
+
 class RequestHolder(object):
-    def __init__(self):
-        self.request = None
+    _requests = threading.local()
+
+    @property
+    def request(self):
+        return self._requests.request
+
+    @request.setter
+    def request(self, value):
+        self._requests.request = value
 
-REQUEST_HOLDER = RequestHolder()
\ No newline at end of file
+REQUEST_HOLDER = RequestHolder()
index 5ba6e2bfe0f1904f6571d6974bdecf5aff0ec5b9..8a4760b0aa72e0cd0ca48b4730fb1cae7731840d 100644 (file)
@@ -2,7 +2,9 @@ from django.utils.html import strip_tags
 from django.utils.translation import ugettext as _
 from forum.models.action import ActionProxy
 from forum.models import Comment, Question, Answer, NodeRevision
-import logging
+from forum import settings, REQUEST_HOLDER
+
+from django.contrib import messages
 
 class NodeEditAction(ActionProxy):
     def create_revision_data(self, initial=False, **data):
@@ -28,7 +30,7 @@ class AskAction(NodeEditAction):
         question.save()
         self.node = question
 
-        self.user.message_set.create(message=self.describe(self.user))
+        messages.info(REQUEST_HOLDER.request, self.describe(self.user))
 
     def describe(self, viewer=None):
         return _("%(user)s asked %(question)s") % {
@@ -47,7 +49,7 @@ class AnswerAction(NodeEditAction):
     def process_action(self):
         self.node.question.reset_answer_count_cache()
 
-        self.user.message_set.create(message=self.describe(self.user))
+        messages.info(REQUEST_HOLDER.request, self.describe(self.user))
 
 
     def describe(self, viewer=None):
index 7d636be0fcce12e4a78976bc7cfca4b7dc098478..a9ec71ae605309bf6cd961a42d196fcf2a536dc1 100644 (file)
@@ -1,12 +1,15 @@
 from django.utils.translation import ungettext, ugettext as _
 from django.core.urlresolvers import reverse
 from django.db.models import F
+from django.contrib import messages
 from forum.models.action import ActionProxy
 from forum.models import Award, Badge, ValidationHash, User
-from forum import settings
+from forum import settings, REQUEST_HOLDER
 from forum.settings import APP_SHORT_NAME
 from forum.utils.mail import send_template_email
 
+from django.contrib import messages
+
 class UserJoinsAction(ActionProxy):
     verb = _("joined")
 
@@ -76,8 +79,7 @@ class BonusRepAction(ActionProxy):
                     message=_("Congratulations, you have been awarded an extra %s reputation points.") % self._value +
                     '<br />%s' % self.extra.get('message', _('Thank you')))
         else:
-            self._affected.message_set.create(
-                    message=_("You have been penalized in %s reputation points.") % self._value +
+            messages.info(REQUEST_HOLDER.request, _("You have penalized %s in %s reputation points.") % (self._affected, self._value) +
                     '<br />%s' % self.extra.get('message', ''))
 
     def describe(self, viewer=None):
@@ -110,7 +112,6 @@ class AwardPointsAction(ActionProxy):
         self.repute(self._affected, self._value)
         self.repute(self.user, -self._value)
 
-
         self._affected.message_set.create(
                 message=_("Congratulations, you have been awarded an extra %(points)s reputation %(points_label)s on <a href=\"%(answer_url)s\">this</a> answer.") % {
                         'points': self._value,
@@ -252,4 +253,4 @@ class SuspendAction(ActionProxy):
         return _("%(user)s suspended %(users)s %(suspension)s: %(msg)s") % {
         'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
         'users': self.affected_links(viewer), 'suspension': suspension, 'msg': self.extra.get('publicmsg', _('Bad behaviour'))
-        }
\ No newline at end of file
+        }
index 641af38243d484d10d338e9ed8c57fdead6b78a4..957b5f91d800c55d2a5924f0d50abdd958dffe90 100644 (file)
@@ -6,18 +6,12 @@ def application_settings(context):
 def auth_processor(request):
     if hasattr(request, 'user'):
         user = request.user
-        if user.is_authenticated():
-            messages = user.message_set.all()
-        else:
-            messages = None
     else:
         from django.contrib.auth.models import AnonymousUser
         user = AnonymousUser()
-        messages = None
 
     from django.core.context_processors import PermWrapper
     return {
         'user': user,
-        'messages': messages,
         'perms': PermWrapper(user),
     }
index 01c528bb854a7295e05e6ad6cd0523d6150358af..06ee23c0d9ff423fe1dd80dccb254f39ce0a28f9 100644 (file)
@@ -3,7 +3,6 @@ import re
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
 from forum import settings
-from django.http import str_to_unicode
 from forum.models import User
 from forum.modules import call_all_handlers
 import urllib
@@ -13,7 +12,9 @@ DEFAULT_NEXT = getattr(settings, 'APP_BASE_URL')
 def clean_next(next):
     if next is None:
         return DEFAULT_NEXT
-    next = str_to_unicode(urllib.unquote(next), 'utf-8')
+    next = urllib.unquote(next)
+    if not isinstance(next, unicode):
+        next = unicode(next, 'utf-8')
     next = next.strip()
     if next.startswith('/'):
         return next
index d2cc837c701af8710c9788808c87b51638b83b2a..ea75ddd59c577e1ecf09ebdd97b9dfecb4ccf198 100644 (file)
@@ -354,6 +354,7 @@ class SubscriptionSettingsForm(forms.ModelForm):
 
     class Meta:
         model = SubscriptionSettings
+        fields = ['enable_notifications', 'member_joins', 'new_question', 'new_question_watched_tags', 'subscribed_questions']
 
 class UserPreferencesForm(forms.Form):
     sticky_sorts = forms.BooleanField(required=False, initial=False)
index 2d391defc44823174ab29bb1cbef9ff51a86f334..71af55fba4c8a5dc6b29abb87019e0d2f6952083 100644 (file)
@@ -1,7 +1,7 @@
-from forum.user_messages import create_message
 from django.utils.translation import ugettext as _
 from django.core.urlresolvers import reverse
 from django.core.exceptions import ObjectDoesNotExist
+from django.contrib import messages
 
 from forum.settings import EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, \
         APP_URL
@@ -29,14 +29,8 @@ class AdminMessagesMiddleware(object):
 
             # We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
             # add it. That's why first of all we're going the check if it is there.
-            try:
-                # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
-                request.user.message_set.all().get(message=msg)
-            except ObjectDoesNotExist:
-                # Let's create the message.
-                request.user.message_set.create(message=msg)
-            except:
-                pass
+            if msg not in [m.message for m in messages.api.get_messages(request)]:
+                messages.info(request, msg)
 
     def check_app_url(self, request):
         # We consider the APP_URL setting not configured if it contains only the protocol
@@ -50,11 +44,5 @@ class AdminMessagesMiddleware(object):
 
             # We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
             # add it. That's why first of all we're going the check if it is there.
-            try:
-                # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
-                request.user.message_set.all().get(message=msg)
-            except ObjectDoesNotExist:
-                # Let's create the message.
-                request.user.message_set.create(message=msg)
-            except:
-                pass
+            if msg not in [m.message for m in messages.api.get_messages(request)]:
+                messages.info(request, msg)
index 25f192a00f94f83adaeec97d785352e943e60038..dafca3e854e755ef1b5f0a17d2b1ce3e27f115da 100644 (file)
@@ -1,11 +1,12 @@
 from django.http import HttpResponseRedirect, HttpResponse
 from forum.forms import get_next_url
 from django.utils.translation import ugettext as _
-from forum.user_messages import create_message, get_and_delete_messages
 from forum import settings
 from django.core.urlresolvers import reverse
 import logging
 
+from django.contrib import messages
+
 class AnonymousMessageManager(object):
     def __init__(self,request):
         self.request = request
@@ -25,8 +26,6 @@ class ConnectToSessionMessagesMiddleware(object):
     def process_request(self, request):
         if not request.user.is_authenticated():
             request.user.__deepcopy__ = dummy_deepcopy #plug on deepcopy which may be called by django db "driver"
-            request.user.message_set = AnonymousMessageManager(request) #here request is linked to anon user
-            request.user.get_and_delete_messages = request.user.message_set.get_and_delete
 
             #also set the first greeting one time per session only
             if 'greeting_set' not in request.session:
@@ -37,7 +36,7 @@ class ConnectToSessionMessagesMiddleware(object):
                 # If the store greeting in cookie setting is activated make sure that the greeting_set cookies isn't set
                 if (settings.STORE_GREETING_IN_COOKIE and not request.COOKIES.has_key('greeting_set')) or \
                   not settings.STORE_GREETING_IN_COOKIE:
-                    request.user.message_set.create(message=msg)
+                    messages.info(request, msg)
 
                 if settings.STORE_GREETING_IN_COOKIE:
                     request.COOKIES.set(key='greeting_set', value=True)
index 2d78a171c5e811ae4c9845a6a06a27ec1e72ec25..9d8f8702e66ad1b25507b72b90449a23d99642eb 100644 (file)
@@ -1,6 +1,8 @@
 from django.http import HttpResponseRedirect
 from forum.forms import get_next_url
 import logging
+from django.contrib import messages
+
 class CancelActionMiddleware(object):
     def process_view(self, request, view_func, view_args, view_kwargs):
         if 'cancel' in request.REQUEST:
@@ -9,7 +11,7 @@ class CancelActionMiddleware(object):
                 msg = getattr(view_func,'CANCEL_MESSAGE')
             except AttributeError:
                 msg = 'action canceled'
-            request.user.message_set.create(message=msg)
+            messages.info(request, msg)
             return HttpResponseRedirect(get_next_url(request))
         else:
             return None
index 7e887452dcd0451909cc618f834179ade80fd2a4..b3cfd260f33ef8d147e6214245da998f3ac9bd58 100644 (file)
@@ -28,7 +28,7 @@ class ActionQuerySet(CachedQuerySet):
 class ActionManager(CachedManager):
     use_for_related_fields = True
 
-    def get_query_set(self):
+    def get_queryset(self):
         qs = ActionQuerySet(self.model)
 
         if self.model is not Action:
index 912c21ac768129ce66b8d955b5ee751e4869f3ea..9c328c597a27712632d7067eaff029381512338c 100644 (file)
@@ -190,7 +190,7 @@ class CachedQuerySet(models.query.QuerySet):
 class CachedManager(models.Manager):
     use_for_related_fields = True
 
-    def get_query_set(self):
+    def get_queryset(self):
         return CachedQuerySet(self.model)
 
     def get_or_create(self, *args, **kwargs):
@@ -226,7 +226,7 @@ class DenormalizedField(object):
         cls.add_to_class("reset_%s_cache" % name, reset_cache)
 
 
-class BaseMetaClass(models.Model.__metaclass__):
+class BaseMetaClass(type(models.Model)):
     to_denormalize = []
 
     def __new__(cls, *args, **kwargs):
index 5b6cdb512a0554edac61d303594e15a11f65f494..20ede477f2c95a826745b4a93dfec5bf87b2a00b 100644 (file)
@@ -152,7 +152,7 @@ class NodeQuerySet(CachedQuerySet):
 class NodeManager(CachedManager):
     use_for_related_fields = True
 
-    def get_query_set(self):
+    def get_queryset(self):
         qs = NodeQuerySet(self.model)
 
         # If the node is an answer, question or comment we filter the Node model by type
index 73b1e30a2a92f3dcee60b85671cfdb91f7c1e3ac..eca23e468ae8d186605b5989831191284a8fed77 100644 (file)
@@ -11,8 +11,8 @@ from forum import modules
 class ActiveTagManager(CachedManager):
     use_for_related_fields = True
 
-    def get_query_set(self):
-        return super(ActiveTagManager, self).get_query_set().exclude(used_count__lt=1)
+    def get_queryset(self):
+        return super(ActiveTagManager, self).get_queryset().exclude(used_count__lt=1)
 
 class Tag(BaseModel):
     name            = models.CharField(max_length=255, unique=True)
index cf47c6653e78b2eaae6f68b5e8ae5039b5c5b8a4..043761481eae3a81989c341eb15ae2e992e05ace 100644 (file)
@@ -209,15 +209,6 @@ class User(BaseModel, DjangoUser):
             sub_settings = SubscriptionSettings(user=self)
             sub_settings.save()
 
-    def get_messages(self):
-        messages = []
-        for m in self.message_set.all():
-            messages.append(m.message)
-        return messages
-
-    def delete_messages(self):
-        self.message_set.all().delete()
-
     @models.permalink
     def get_profile_url(self):
         keyword_arguments = {
index 1fbda58e4f2d3cd3b20edc8bffc6d31e4f0d7937..5a1912c818b1fd12616b8ade891470ba973c7453 100644 (file)
@@ -81,7 +81,7 @@ class PickledObjectField(models.Field):
                     raise
         return value
 
-    def get_db_prep_value(self, value):
+    def get_db_prep_value(self, value, connection, prepared=False):
         if value is not None and not isinstance(value, PickledObject):
             if type(value).__name__ in self.markable_types and not (isinstance(value, basestring) and len(value
                                                                                                           ) > MAX_MARKABLE_STRING_LENGTH):
index f1ad7d96bb167a936ea87756b8dfb695a7384cf4..6942c9115e491886b5bcf6a6f104ec7aaaa07bd3 100644 (file)
@@ -16,15 +16,10 @@ def get_modules_script(script_name):
 
         try:
             all.append(__import__('%s.%s' % (m.__name__, script_name), globals(), locals(), [m.__name__]))
-        except ImportError, e:
-            #print repr(type(e)) + m.__name__ + ":" + str(e)
-            pass
-        except:
-            import traceback
-            msg = "Error importing %s from module %s: \n %s" % (
-                script_name, m, traceback.format_exc()
-            )
-            logging.error(msg)
+        except Exception, e:
+            if isinstance(e, ImportError) and str(e).endswith(script_name):
+                continue
+            logging.exception("Error importing %s from module %s", script_name, m)
 
     return all
 
index 218f1140f609f8f14df6856b4029af8066fa8eee..4120d2ba6737f5df56ac3b01466aa641e0898193 100644 (file)
@@ -4,17 +4,17 @@ from base import Setting, SettingSet, BaseSetting
 from django.forms.widgets import Textarea
 from django.utils.translation import ugettext_lazy as _
 from django.conf import settings as djsettings
-from django.utils.version import get_svn_revision
+from django.utils.version import get_git_changeset
 
 from forum.modules import get_modules_script_implementations
 
 OSQA_VERSION = "Development Build"
 
-SVN_REVISION = get_svn_revision(djsettings.SITE_SRC_ROOT)
+VCS_REVISION = get_git_changeset()
 
 # We'll have to keep in mind this variable on every release.
-if SVN_REVISION == u'SVN-unknown':
-    SVN_REVISION = u'SVN-1000'
+if VCS_REVISION == u'SVN-unknown':
+    VCS_REVISION = u'SVN-1000'
 
 MAINTAINANCE_MODE = Setting('MAINTAINANCE_MODE', None)
 
@@ -27,7 +27,6 @@ APP_BASE_URL = djsettings.APP_BASE_URL
 FORCE_SCRIPT_NAME = djsettings.FORCE_SCRIPT_NAME
 OSQA_SKIN = djsettings.OSQA_DEFAULT_SKIN
 LANGUAGE_CODE = djsettings.LANGUAGE_CODE
-ADMIN_MEDIA_PREFIX = djsettings.ADMIN_MEDIA_PREFIX
 ONLINE_USERS = Setting('ONLINE_USERS', {})
 
 
index a4efd6f105eb78af4e459e0b1f11f75c760f8784..1f9ddc90214217060033882eff931da998575f06 100644 (file)
@@ -1,52 +1,52 @@
-import os.path\r
-\r
-from base import Setting, SettingSet\r
-from forms import ImageFormWidget\r
-\r
-from django.utils.translation import ugettext_lazy as _\r
-from django.forms.widgets import Textarea\r
-\r
-BASIC_SET = SettingSet('basic', _('Basic settings'), _("The basic settings for your application"), 1)\r
-\r
-APP_LOGO = Setting('APP_LOGO', '/upfiles/logo.png', BASIC_SET, dict(\r
-label = _("Application logo"),\r
-help_text = _("Your site main logo."),\r
-widget=ImageFormWidget))\r
-\r
-APP_FAVICON = Setting('APP_FAVICON', '/m/default/media/images/favicon.ico', BASIC_SET, dict(\r
-label = _("Favicon"),\r
-help_text = _("Your site favicon."),\r
-widget=ImageFormWidget))\r
-\r
-APP_TITLE = Setting('APP_TITLE', u'OSQA: Open Source Q&A Forum', BASIC_SET, dict(\r
-label = _("Application title"),\r
-help_text = _("The title of your application that will show in the browsers title bar")))\r
-\r
-APP_SHORT_NAME = Setting(u'APP_SHORT_NAME', 'OSQA', BASIC_SET, dict(\r
-label = _("Application short name"),\r
-help_text = "The short name for your application that will show up in many places."))\r
-\r
-APP_KEYWORDS = Setting('APP_KEYWORDS', u'OSQA,CNPROG,forum,community', BASIC_SET, dict(\r
-label = _("Application keywords"),\r
-help_text = _("The meta keywords that will be available through the HTML meta tags.")))\r
-\r
-APP_DESCRIPTION = Setting('APP_DESCRIPTION', u'Ask and answer questions.', BASIC_SET, dict(\r
-label = _("Application description"),\r
-help_text = _("The description of your application"),\r
-widget=Textarea))\r
-\r
-APP_COPYRIGHT = Setting('APP_COPYRIGHT', u'Copyright OSQA, 2010. Some rights reserved under creative commons license.', BASIC_SET, dict(\r
-label = _("Copyright notice"),\r
-help_text = _("The copyright notice visible at the footer of your page.")))\r
-\r
-SUPPORT_URL = Setting('SUPPORT_URL', '', BASIC_SET, dict(\r
-label = _("Support URL"),\r
-help_text = _("The URL provided for users to get support. It can be http: or mailto: or whatever your preferred support scheme is."),\r
-required=False))\r
-\r
-CONTACT_URL = Setting('CONTACT_URL', '', BASIC_SET, dict(\r
-label = _("Contact URL"),\r
-help_text = _("The URL provided for users to contact you. It can be http: or mailto: or whatever your preferred contact scheme is."),\r
-required=False))\r
-\r
-\r
+import os.path
+
+from base import Setting, SettingSet
+from forms import ImageFormWidget
+
+from django.utils.translation import ugettext_lazy as _
+from django.forms.widgets import Textarea
+
+BASIC_SET = SettingSet('basic', _('Basic settings'), _("The basic settings for your application"), 1)
+
+APP_LOGO = Setting('APP_LOGO', '/upfiles/logo.png', BASIC_SET, dict(
+label = _("Application logo"),
+help_text = _("Your site main logo."),
+widget=ImageFormWidget))
+
+APP_FAVICON = Setting('APP_FAVICON', '/m/default/media/images/favicon.ico', BASIC_SET, dict(
+label = _("Favicon"),
+help_text = _("Your site favicon."),
+widget=ImageFormWidget))
+
+APP_TITLE = Setting('APP_TITLE', u'OSQA: Open Source Q&A Forum', BASIC_SET, dict(
+label = _("Application title"),
+help_text = _("The title of your application that will show in the browsers title bar")))
+
+APP_SHORT_NAME = Setting(u'APP_SHORT_NAME', 'OSQA', BASIC_SET, dict(
+label = _("Application short name"),
+help_text = "The short name for your application that will show up in many places."))
+
+APP_KEYWORDS = Setting('APP_KEYWORDS', u'OSQA,CNPROG,forum,community', BASIC_SET, dict(
+label = _("Application keywords"),
+help_text = _("The meta keywords that will be available through the HTML meta tags.")))
+
+APP_DESCRIPTION = Setting('APP_DESCRIPTION', u'Ask and answer questions.', BASIC_SET, dict(
+label = _("Application description"),
+help_text = _("The description of your application"),
+widget=Textarea))
+
+APP_COPYRIGHT = Setting('APP_COPYRIGHT', u'Copyright OSQA, 2010. Some rights reserved under creative commons license.', BASIC_SET, dict(
+label = _("Copyright notice"),
+help_text = _("The copyright notice visible at the footer of your page.")))
+
+SUPPORT_URL = Setting('SUPPORT_URL', '', BASIC_SET, dict(
+label = _("Support URL"),
+help_text = _("The URL provided for users to get support. It can be http: or mailto: or whatever your preferred support scheme is."),
+required=False))
+
+CONTACT_URL = Setting('CONTACT_URL', '', BASIC_SET, dict(
+label = _("Contact URL"),
+help_text = _("The URL provided for users to contact you. It can be http: or mailto: or whatever your preferred contact scheme is."),
+required=False))
+
+
index 71a7136df5b280daaedee55237043dccf0fcc762..896efbdba1aeb0571c6741345fc46317a0456809 100644 (file)
@@ -1,86 +1,86 @@
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-from django.forms.widgets import PasswordInput\r
-from django.forms.widgets import RadioSelect\r
-from forms import TestEmailSettingsWidget\r
-\r
-EMAIL_SET = SettingSet('email', _('Email settings'), _("Email server and other email related settings."), 50)\r
-\r
-TEST_EMAIL_SETTINGS = Setting('TEST_EMAIL_SETTINGS', '', EMAIL_SET, dict(\r
-label = _("E-Mail settings test"),\r
-help_text = _("Test the current E-Mail configuration."),\r
-required=False,\r
-widget=TestEmailSettingsWidget))\r
-\r
-EMAIL_HOST = Setting('EMAIL_HOST', '', EMAIL_SET, dict(\r
-label = _("Email Server"),\r
-help_text = _("The SMTP server through which your application will be sending emails."),\r
-required=False))\r
-\r
-EMAIL_PORT = Setting('EMAIL_PORT', 25, EMAIL_SET, dict(\r
-label = _("Email Port"),\r
-help_text = _("The port on which your SMTP server is listening to. Usually this is 25, but can be something else."),\r
-required=False))\r
-\r
-EMAIL_HOST_USER = Setting('EMAIL_HOST_USER', '', EMAIL_SET, dict(\r
-label = _("Email User"),\r
-help_text = _("The username for your SMTP connection."),\r
-required=False))\r
-\r
-EMAIL_HOST_PASSWORD = Setting('EMAIL_HOST_PASSWORD', '', EMAIL_SET, dict(\r
-label = _("Email Password"),\r
-help_text = _("The password for your SMTP connection."),\r
-required=False,\r
-widget=PasswordInput(render_value=True)))\r
-\r
-EMAIL_USE_TLS = Setting('EMAIL_USE_TLS', False, EMAIL_SET, dict(\r
-label = _("Use TLS"),\r
-help_text = _("Whether to use TLS for authentication with your SMTP server."),\r
-required=False))\r
-\r
-DEFAULT_FROM_EMAIL = Setting('DEFAULT_FROM_EMAIL', '', EMAIL_SET, dict(\r
-label = _("Site 'from' Email Address"),\r
-help_text = _("The address that will show up on the 'from' field on emails sent by your website."),\r
-required=False))\r
-\r
-DEFAULT_REPLY_TO_EMAIL = Setting('DEFAULT_REPLY_TO_EMAIL', '', EMAIL_SET, dict(\r
-label = _("Site 'reply-to' Email Address"),\r
-help_text = _("The address that will show up on the 'reply-to' field on emails sent by your website."),\r
-required=False))\r
-\r
-EMAIL_SUBJECT_PREFIX = Setting('EMAIL_SUBJECT_PREFIX', '', EMAIL_SET, dict(\r
-label = _("Email Subject Prefix"),\r
-help_text = _("Every email sent through your website will have the subject prefixed by this string. It's usually a good idea to have such a prefix so your users can easily set up a filter on their email clients."),\r
-required=False))\r
-\r
-EMAIL_FOOTER_TEXT = Setting(u'EMAIL_FOOTER_TEXT', '', EMAIL_SET, dict(\r
-label = _("Email Footer Text"),\r
-help_text = _("Email footer text, usually \"CAN SPAM\" compliance, or the physical address of the organization running the website. See <a href=\"http://en.wikipedia.org/wiki/CAN-SPAM_Act_of_2003\">this Wikipedia article</a> for more info."),\r
-required=False))\r
-\r
-EMAIL_BORDER_COLOR = Setting('EMAIL_BORDER_COLOR', '#e5ebf8', EMAIL_SET, dict(\r
-label = _("Email Border Color"),\r
-help_text = _("The outter border color of the email base template"),\r
-required=False))\r
-\r
-EMAIL_PARAGRAPH_STYLE = Setting('EMAIL_PARAGRAPH_STYLE', "color:#333333;font-family:'helvetica neue', arial, Helvetica, sans-serif;line-height:18px;font-size:14px;margin-top:10px;", EMAIL_SET, dict(\r
-label = _("Email Paragraph Style"),\r
-help_text = _("A valid css string to be used to style email paragraphs (the P tag)."),\r
-required=False))\r
-\r
-EMAIL_ANCHOR_STYLE = Setting('EMAIL_ANCHOR_STYLE', "text-decoration:none;color:#3060a8;font-weight:bold;", EMAIL_SET, dict(\r
-label = _("Email Link Style"),\r
-help_text = _("A valid css string to be used to style email links (the A tag)."),\r
-required=False))\r
-\r
-SEND_DIGEST_ONLY_TO_ACTIVE_USERS = Setting('SEND_DIGEST_ONLY_TO_ACTIVE_USERS', True, EMAIL_SET, dict(\r
-label = _("Send digest only to active users"),\r
-help_text = _("If checked the daily digest won't be sent to users that have been suspended."),\r
-required=False))\r
-\r
-SEND_DIGEST_ONLY_TO_VALIDATED_USERS = Setting('SEND_DIGEST_ONLY_TO_VALIDATED_USERS', True, EMAIL_SET, dict(\r
-label = _("Send digest only to validated users"),\r
-help_text = _("If checked the daily digest won't be sent to users that haven't validated their emails."),\r
-required=False))\r
-\r
-EMAIL_DIGEST_FLAG = Setting('EMAIL_DIGEST_FLAG', None)\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+from django.forms.widgets import PasswordInput
+from django.forms.widgets import RadioSelect
+from forms import TestEmailSettingsWidget
+
+EMAIL_SET = SettingSet('email', _('Email settings'), _("Email server and other email related settings."), 50)
+
+TEST_EMAIL_SETTINGS = Setting('TEST_EMAIL_SETTINGS', '', EMAIL_SET, dict(
+label = _("E-Mail settings test"),
+help_text = _("Test the current E-Mail configuration."),
+required=False,
+widget=TestEmailSettingsWidget))
+
+EMAIL_HOST = Setting('EMAIL_HOST', '', EMAIL_SET, dict(
+label = _("Email Server"),
+help_text = _("The SMTP server through which your application will be sending emails."),
+required=False))
+
+EMAIL_PORT = Setting('EMAIL_PORT', 25, EMAIL_SET, dict(
+label = _("Email Port"),
+help_text = _("The port on which your SMTP server is listening to. Usually this is 25, but can be something else."),
+required=False))
+
+EMAIL_HOST_USER = Setting('EMAIL_HOST_USER', '', EMAIL_SET, dict(
+label = _("Email User"),
+help_text = _("The username for your SMTP connection."),
+required=False))
+
+EMAIL_HOST_PASSWORD = Setting('EMAIL_HOST_PASSWORD', '', EMAIL_SET, dict(
+label = _("Email Password"),
+help_text = _("The password for your SMTP connection."),
+required=False,
+widget=PasswordInput(render_value=True)))
+
+EMAIL_USE_TLS = Setting('EMAIL_USE_TLS', False, EMAIL_SET, dict(
+label = _("Use TLS"),
+help_text = _("Whether to use TLS for authentication with your SMTP server."),
+required=False))
+
+DEFAULT_FROM_EMAIL = Setting('DEFAULT_FROM_EMAIL', '', EMAIL_SET, dict(
+label = _("Site 'from' Email Address"),
+help_text = _("The address that will show up on the 'from' field on emails sent by your website."),
+required=False))
+
+DEFAULT_REPLY_TO_EMAIL = Setting('DEFAULT_REPLY_TO_EMAIL', '', EMAIL_SET, dict(
+label = _("Site 'reply-to' Email Address"),
+help_text = _("The address that will show up on the 'reply-to' field on emails sent by your website."),
+required=False))
+
+EMAIL_SUBJECT_PREFIX = Setting('EMAIL_SUBJECT_PREFIX', '', EMAIL_SET, dict(
+label = _("Email Subject Prefix"),
+help_text = _("Every email sent through your website will have the subject prefixed by this string. It's usually a good idea to have such a prefix so your users can easily set up a filter on their email clients."),
+required=False))
+
+EMAIL_FOOTER_TEXT = Setting(u'EMAIL_FOOTER_TEXT', '', EMAIL_SET, dict(
+label = _("Email Footer Text"),
+help_text = _("Email footer text, usually \"CAN SPAM\" compliance, or the physical address of the organization running the website. See <a href=\"http://en.wikipedia.org/wiki/CAN-SPAM_Act_of_2003\">this Wikipedia article</a> for more info."),
+required=False))
+
+EMAIL_BORDER_COLOR = Setting('EMAIL_BORDER_COLOR', '#e5ebf8', EMAIL_SET, dict(
+label = _("Email Border Color"),
+help_text = _("The outter border color of the email base template"),
+required=False))
+
+EMAIL_PARAGRAPH_STYLE = Setting('EMAIL_PARAGRAPH_STYLE', "color:#333333;font-family:'helvetica neue', arial, Helvetica, sans-serif;line-height:18px;font-size:14px;margin-top:10px;", EMAIL_SET, dict(
+label = _("Email Paragraph Style"),
+help_text = _("A valid css string to be used to style email paragraphs (the P tag)."),
+required=False))
+
+EMAIL_ANCHOR_STYLE = Setting('EMAIL_ANCHOR_STYLE', "text-decoration:none;color:#3060a8;font-weight:bold;", EMAIL_SET, dict(
+label = _("Email Link Style"),
+help_text = _("A valid css string to be used to style email links (the A tag)."),
+required=False))
+
+SEND_DIGEST_ONLY_TO_ACTIVE_USERS = Setting('SEND_DIGEST_ONLY_TO_ACTIVE_USERS', True, EMAIL_SET, dict(
+label = _("Send digest only to active users"),
+help_text = _("If checked the daily digest won't be sent to users that have been suspended."),
+required=False))
+
+SEND_DIGEST_ONLY_TO_VALIDATED_USERS = Setting('SEND_DIGEST_ONLY_TO_VALIDATED_USERS', True, EMAIL_SET, dict(
+label = _("Send digest only to validated users"),
+help_text = _("If checked the daily digest won't be sent to users that haven't validated their emails."),
+required=False))
+
+EMAIL_DIGEST_FLAG = Setting('EMAIL_DIGEST_FLAG', None)
index 9d439df0b7ba5939d391a0da7cccea6cfa6a6e54..11b43e311d7543d3cb50497f9f3dbb7549de0ea8 100644 (file)
@@ -1,15 +1,15 @@
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-EXT_KEYS_SET = SettingSet('extkeys', _('External Keys'), _("Keys for various external providers that your application may optionally use."), 100)\r
-\r
-GOOGLE_SITEMAP_CODE = Setting('GOOGLE_SITEMAP_CODE', '', EXT_KEYS_SET, dict(\r
-label = _("Google sitemap code"),\r
-help_text = _("This is the code you get when you register your site at <a href='https://www.google.com/webmasters/tools/'>Google webmaster central</a>."),\r
-required=False))\r
-\r
-GOOGLE_ANALYTICS_KEY = Setting('GOOGLE_ANALYTICS_KEY', '', EXT_KEYS_SET, dict(\r
-label = _("Google analytics key"),\r
-help_text = _("Your Google analytics key. You can get one at the <a href='http://www.google.com/analytics/'>Google analytics official website</a>"),\r
-required=False))\r
-\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+EXT_KEYS_SET = SettingSet('extkeys', _('External Keys'), _("Keys for various external providers that your application may optionally use."), 100)
+
+GOOGLE_SITEMAP_CODE = Setting('GOOGLE_SITEMAP_CODE', '', EXT_KEYS_SET, dict(
+label = _("Google sitemap code"),
+help_text = _("This is the code you get when you register your site at <a href='https://www.google.com/webmasters/tools/'>Google webmaster central</a>."),
+required=False))
+
+GOOGLE_ANALYTICS_KEY = Setting('GOOGLE_ANALYTICS_KEY', '', EXT_KEYS_SET, dict(
+label = _("Google analytics key"),
+help_text = _("Your Google analytics key. You can get one at the <a href='http://www.google.com/analytics/'>Google analytics official website</a>"),
+required=False))
+
index 1c9e17d34d697b2094a2c801df5ec103902306b1..a8dac0d3a3cdc07064ff9598a9d951ed426fc6d6 100644 (file)
@@ -1,95 +1,95 @@
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-MIN_REP_SET = SettingSet('minrep', _('Minimum reputation config'), _("Configure the minimum reputation required to perform certain actions on your site."), 300)\r
-\r
-CAPTCHA_IF_REP_LESS_THAN = Setting('CAPTCHA_IF_REP_LESS_THAN', 0, MIN_REP_SET, dict(\r
-label = _("Show captcha if user with less reputation than"),\r
-help_text = _("If the user has less reputation, captcha is used to when adding new content.")))\r
-\r
-REP_TO_VOTE_UP = Setting('REP_TO_VOTE_UP', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to vote up"),\r
-help_text = _("The minimum reputation an user must have to be allowed to vote up.")))\r
-\r
-REP_TO_VOTE_DOWN = Setting('REP_TO_VOTE_DOWN', 100, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to vote down"),\r
-help_text = _("The minimum reputation an user must have to be allowed to vote down.")))\r
-\r
-REP_TO_FLAG = Setting('REP_TO_FLAG', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to flag a post"),\r
-help_text = _("The minimum reputation an user must have to be allowed to flag a post.")))\r
-\r
-REP_TO_COMMENT = Setting('REP_TO_COMMENT', 50, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to comment a post.")))\r
-\r
-REP_TO_LIKE_COMMENT = Setting('REP_TO_LIKE_COMMENT', 15, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to like a comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to \"like\" a comment.")))\r
-\r
-REP_TO_UPLOAD = Setting('REP_TO_UPLOAD', 60, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to upload"),\r
-help_text = _("The minimum reputation an user must have to be allowed to upload a file.")))\r
-\r
-REP_TO_CREATE_TAGS = Setting('REP_TO_CREATE_TAGS', 250, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to create tags"),\r
-help_text = _("The minimum reputation an user must have to be allowed to create new tags.")))\r
-\r
-REP_TO_CLOSE_OWN = Setting('REP_TO_CLOSE_OWN', 250, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to close own question"),\r
-help_text = _("The minimum reputation an user must have to be allowed to close his own question.")))\r
-\r
-UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN = Setting('UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN', True, MIN_REP_SET, dict(\r
-label = _("Unify close and reopen permissions"),\r
-help_text = _("If checked the same permissions as the ones to close question will be required to reopen it."),\r
-required=False))\r
-\r
-REP_TO_REOPEN_OWN = Setting('REP_TO_REOPEN_OWN', 500, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to reopen own question"),\r
-help_text = _("The minimum reputation an user must have to be allowed to reopen his own question.")))\r
-\r
-REP_TO_RETAG = Setting('REP_TO_RETAG', 500, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to retag others questions"),\r
-help_text = _("The minimum reputation an user must have to be allowed to retag others questions.")))\r
-\r
-REP_TO_EDIT_WIKI = Setting('REP_TO_EDIT_WIKI', 750, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to edit wiki posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to edit community wiki posts.")))\r
-\r
-REP_TO_WIKIFY = Setting('REP_TO_WIKIFY', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to mark post as community wiki"),\r
-help_text = _("The minimum reputation an user must have to be allowed to mark a post as community wiki.")))\r
-\r
-REP_TO_EDIT_OTHERS = Setting('REP_TO_EDIT_OTHERS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to edit others posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to edit others posts.")))\r
-\r
-REP_TO_CLOSE_OTHERS = Setting('REP_TO_CLOSE_OTHERS', 3000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to close others posts"),\r
-help_text = _("The minimum reputation an user must have to be allowed to close others posts.")))\r
-\r
-REP_TO_DELETE_COMMENTS = Setting('REP_TO_DELETE_COMMENTS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to delete comments"),\r
-help_text = _("The minimum reputation an user must have to be allowed to delete comments.")))\r
-\r
-REP_TO_CONVERT_TO_COMMENT = Setting('REP_TO_CONVERT_TO_COMMENT', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert answers to comment"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a comment.")))\r
-\r
-REP_TO_CONVERT_COMMENTS_TO_ANSWERS = Setting('REP_TO_CONVERT_COMMENTS_TO_ANSWERS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert comments to answers"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert comments into an answer.")))\r
-\r
-REP_TO_CONVERT_TO_QUESTION = Setting('REP_TO_CONVERT_TO_QUESTION', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to convert answers to questions"),\r
-help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a question.")))\r
-\r
-REP_TO_VIEW_FLAGS = Setting('REP_TO_VIEW_FLAGS', 2000, MIN_REP_SET, dict(\r
-label = _("Minimum reputation to view offensive flags"),\r
-help_text = _("The minimum reputation an user must have to view offensive flags.")))\r
-\r
-#REP_TO_DISABLE_NOFOLLOW = Setting('REP_TO_DISABLE_NOFOLLOW', 2000, MIN_REP_SET, dict(\r
-#label = _("Minimum reputation to disable nofollow"),\r
-#help_text = _("""\r
-#The minimum reputation an user must have to be allowed to disable the nofollow attribute of a post link.\r
-#""")))\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+MIN_REP_SET = SettingSet('minrep', _('Minimum reputation config'), _("Configure the minimum reputation required to perform certain actions on your site."), 300)
+
+CAPTCHA_IF_REP_LESS_THAN = Setting('CAPTCHA_IF_REP_LESS_THAN', 0, MIN_REP_SET, dict(
+label = _("Show captcha if user with less reputation than"),
+help_text = _("If the user has less reputation, captcha is used to when adding new content.")))
+
+REP_TO_VOTE_UP = Setting('REP_TO_VOTE_UP', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to vote up"),
+help_text = _("The minimum reputation an user must have to be allowed to vote up.")))
+
+REP_TO_VOTE_DOWN = Setting('REP_TO_VOTE_DOWN', 100, MIN_REP_SET, dict(
+label = _("Minimum reputation to vote down"),
+help_text = _("The minimum reputation an user must have to be allowed to vote down.")))
+
+REP_TO_FLAG = Setting('REP_TO_FLAG', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to flag a post"),
+help_text = _("The minimum reputation an user must have to be allowed to flag a post.")))
+
+REP_TO_COMMENT = Setting('REP_TO_COMMENT', 50, MIN_REP_SET, dict(
+label = _("Minimum reputation to comment"),
+help_text = _("The minimum reputation an user must have to be allowed to comment a post.")))
+
+REP_TO_LIKE_COMMENT = Setting('REP_TO_LIKE_COMMENT', 15, MIN_REP_SET, dict(
+label = _("Minimum reputation to like a comment"),
+help_text = _("The minimum reputation an user must have to be allowed to \"like\" a comment.")))
+
+REP_TO_UPLOAD = Setting('REP_TO_UPLOAD', 60, MIN_REP_SET, dict(
+label = _("Minimum reputation to upload"),
+help_text = _("The minimum reputation an user must have to be allowed to upload a file.")))
+
+REP_TO_CREATE_TAGS = Setting('REP_TO_CREATE_TAGS', 250, MIN_REP_SET, dict(
+label = _("Minimum reputation to create tags"),
+help_text = _("The minimum reputation an user must have to be allowed to create new tags.")))
+
+REP_TO_CLOSE_OWN = Setting('REP_TO_CLOSE_OWN', 250, MIN_REP_SET, dict(
+label = _("Minimum reputation to close own question"),
+help_text = _("The minimum reputation an user must have to be allowed to close his own question.")))
+
+UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN = Setting('UNIFY_PERMISSIONS_TO_CLOSE_AND_REOPEN', True, MIN_REP_SET, dict(
+label = _("Unify close and reopen permissions"),
+help_text = _("If checked the same permissions as the ones to close question will be required to reopen it."),
+required=False))
+
+REP_TO_REOPEN_OWN = Setting('REP_TO_REOPEN_OWN', 500, MIN_REP_SET, dict(
+label = _("Minimum reputation to reopen own question"),
+help_text = _("The minimum reputation an user must have to be allowed to reopen his own question.")))
+
+REP_TO_RETAG = Setting('REP_TO_RETAG', 500, MIN_REP_SET, dict(
+label = _("Minimum reputation to retag others questions"),
+help_text = _("The minimum reputation an user must have to be allowed to retag others questions.")))
+
+REP_TO_EDIT_WIKI = Setting('REP_TO_EDIT_WIKI', 750, MIN_REP_SET, dict(
+label = _("Minimum reputation to edit wiki posts"),
+help_text = _("The minimum reputation an user must have to be allowed to edit community wiki posts.")))
+
+REP_TO_WIKIFY = Setting('REP_TO_WIKIFY', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to mark post as community wiki"),
+help_text = _("The minimum reputation an user must have to be allowed to mark a post as community wiki.")))
+
+REP_TO_EDIT_OTHERS = Setting('REP_TO_EDIT_OTHERS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to edit others posts"),
+help_text = _("The minimum reputation an user must have to be allowed to edit others posts.")))
+
+REP_TO_CLOSE_OTHERS = Setting('REP_TO_CLOSE_OTHERS', 3000, MIN_REP_SET, dict(
+label = _("Minimum reputation to close others posts"),
+help_text = _("The minimum reputation an user must have to be allowed to close others posts.")))
+
+REP_TO_DELETE_COMMENTS = Setting('REP_TO_DELETE_COMMENTS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to delete comments"),
+help_text = _("The minimum reputation an user must have to be allowed to delete comments.")))
+
+REP_TO_CONVERT_TO_COMMENT = Setting('REP_TO_CONVERT_TO_COMMENT', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert answers to comment"),
+help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a comment.")))
+
+REP_TO_CONVERT_COMMENTS_TO_ANSWERS = Setting('REP_TO_CONVERT_COMMENTS_TO_ANSWERS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert comments to answers"),
+help_text = _("The minimum reputation an user must have to be allowed to convert comments into an answer.")))
+
+REP_TO_CONVERT_TO_QUESTION = Setting('REP_TO_CONVERT_TO_QUESTION', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to convert answers to questions"),
+help_text = _("The minimum reputation an user must have to be allowed to convert an answer into a question.")))
+
+REP_TO_VIEW_FLAGS = Setting('REP_TO_VIEW_FLAGS', 2000, MIN_REP_SET, dict(
+label = _("Minimum reputation to view offensive flags"),
+help_text = _("The minimum reputation an user must have to view offensive flags.")))
+
+#REP_TO_DISABLE_NOFOLLOW = Setting('REP_TO_DISABLE_NOFOLLOW', 2000, MIN_REP_SET, dict(
+#label = _("Minimum reputation to disable nofollow"),
+#help_text = _("""
+#The minimum reputation an user must have to be allowed to disable the nofollow attribute of a post link.
+#""")))
index 6b283ec2604ae95bf52fbe09929ff938cd7fc0b8..8326757cf47bcdadc8ef2d59910fdb911a121d1b 100644 (file)
@@ -1,49 +1,49 @@
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-REP_GAIN_SET = SettingSet('repgain', _('Reputation gains and losses config'), _("Configure the reputation points a user may gain or lose upon certain actions."), 200)\r
-\r
-INITIAL_REP = Setting('INITIAL_REP', 1, REP_GAIN_SET, dict(\r
-label = _("Initial reputation"),\r
-help_text = _("The initial reputation an user gets when he first signs in.")))\r
-\r
-MAX_REP_BY_UPVOTE_DAY = Setting('MAX_REP_BY_UPVOTE_DAY', 200, REP_GAIN_SET, dict(\r
-label = "Max rep by up votes / day",\r
-help_text = _("Maximum reputation a user can gain in one day for being upvoted.")))\r
-\r
-REP_GAIN_BY_EMAIL_VALIDATION = Setting('REP_GAIN_BY_EMAIL_VALIDATION', 10, REP_GAIN_SET, dict(\r
-label = _("Rep gain by e-mail validation"),\r
-help_text = _("Reputation a user gains for validating his e-mail.")))\r
-\r
-REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict(\r
-label = _("Rep gain by upvoted"),\r
-help_text = _("Reputation a user gains for having one of his posts up voted.")))\r
-\r
-REP_LOST_BY_DOWNVOTED = Setting('REP_LOST_BY_DOWNVOTED', 2, REP_GAIN_SET, dict(\r
-label = _("Rep lost by downvoted"),\r
-help_text = _("Reputation a user loses for having one of his posts down voted.")))\r
-\r
-REP_LOST_BY_DOWNVOTING = Setting('REP_LOST_BY_DOWNVOTING', 1, REP_GAIN_SET, dict(\r
-label = _("Rep lost by downvoting"),\r
-help_text = _("Reputation a user loses for down voting a post.")))\r
-\r
-\r
-REP_GAIN_BY_ACCEPTED = Setting('REP_GAIN_BY_ACCEPTED', 15, REP_GAIN_SET, dict(\r
-label = _("Rep gain by accepted answer"),\r
-help_text = _("Reputation a user gains for having one of his answers accepted.")))\r
-\r
-REP_GAIN_BY_ACCEPTING = Setting('REP_GAIN_BY_ACCEPTING', 2, REP_GAIN_SET, dict(\r
-label = _("Rep gain by accepting answer"),\r
-help_text = _("Reputation a user gains for accepting an answer to one of his questions.")))\r
-\r
-REP_LOST_BY_FLAGGED = Setting('REP_LOST_BY_FLAGGED', 2, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged"),\r
-help_text = _("Reputation a user loses by having one of his posts flagged.")))\r
-\r
-REP_LOST_BY_FLAGGED_3_TIMES = Setting('REP_LOST_BY_FLAGGED_3_TIMES', 30, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged and hidden"),\r
-help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to hide the post.")))\r
-\r
-REP_LOST_BY_FLAGGED_5_TIMES = Setting('REP_LOST_BY_FLAGGED_5_TIMES', 100, REP_GAIN_SET, dict(\r
-label = _("Rep lost by post flagged and deleted"),\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+REP_GAIN_SET = SettingSet('repgain', _('Reputation gains and losses config'), _("Configure the reputation points a user may gain or lose upon certain actions."), 200)
+
+INITIAL_REP = Setting('INITIAL_REP', 1, REP_GAIN_SET, dict(
+label = _("Initial reputation"),
+help_text = _("The initial reputation an user gets when he first signs in.")))
+
+MAX_REP_BY_UPVOTE_DAY = Setting('MAX_REP_BY_UPVOTE_DAY', 200, REP_GAIN_SET, dict(
+label = "Max rep by up votes / day",
+help_text = _("Maximum reputation a user can gain in one day for being upvoted.")))
+
+REP_GAIN_BY_EMAIL_VALIDATION = Setting('REP_GAIN_BY_EMAIL_VALIDATION', 10, REP_GAIN_SET, dict(
+label = _("Rep gain by e-mail validation"),
+help_text = _("Reputation a user gains for validating his e-mail.")))
+
+REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict(
+label = _("Rep gain by upvoted"),
+help_text = _("Reputation a user gains for having one of his posts up voted.")))
+
+REP_LOST_BY_DOWNVOTED = Setting('REP_LOST_BY_DOWNVOTED', 2, REP_GAIN_SET, dict(
+label = _("Rep lost by downvoted"),
+help_text = _("Reputation a user loses for having one of his posts down voted.")))
+
+REP_LOST_BY_DOWNVOTING = Setting('REP_LOST_BY_DOWNVOTING', 1, REP_GAIN_SET, dict(
+label = _("Rep lost by downvoting"),
+help_text = _("Reputation a user loses for down voting a post.")))
+
+
+REP_GAIN_BY_ACCEPTED = Setting('REP_GAIN_BY_ACCEPTED', 15, REP_GAIN_SET, dict(
+label = _("Rep gain by accepted answer"),
+help_text = _("Reputation a user gains for having one of his answers accepted.")))
+
+REP_GAIN_BY_ACCEPTING = Setting('REP_GAIN_BY_ACCEPTING', 2, REP_GAIN_SET, dict(
+label = _("Rep gain by accepting answer"),
+help_text = _("Reputation a user gains for accepting an answer to one of his questions.")))
+
+REP_LOST_BY_FLAGGED = Setting('REP_LOST_BY_FLAGGED', 2, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged"),
+help_text = _("Reputation a user loses by having one of his posts flagged.")))
+
+REP_LOST_BY_FLAGGED_3_TIMES = Setting('REP_LOST_BY_FLAGGED_3_TIMES', 30, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged and hidden"),
+help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to hide the post.")))
+
+REP_LOST_BY_FLAGGED_5_TIMES = Setting('REP_LOST_BY_FLAGGED_5_TIMES', 100, REP_GAIN_SET, dict(
+label = _("Rep lost by post flagged and deleted"),
 help_text = _("Reputation a user loses by having the last revision of one of his posts flagged the enough number of times to delete the post.")))
\ No newline at end of file
index 6e66e0076df8304cfd3d0ce6d9827c7954d3b9c3..3c1fd24b02e9c4f63686a72240670fddb019ca36 100644 (file)
@@ -1,17 +1,17 @@
-import os.path\r
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-UPLOAD_SET = SettingSet('paths', _('File upload settings'), _("File uploads related settings."), 600)\r
-\r
-UPFILES_FOLDER = Setting('UPFILES_FOLDER', os.path.join(os.path.dirname(os.path.dirname(__file__)),'upfiles'), UPLOAD_SET, dict(\r
-label = _("Uploaded files folder"),\r
-help_text = _("The filesystem path where uploaded files will be stored. Please note that this folder must exist.")))\r
-\r
-UPFILES_ALIAS = Setting('UPFILES_ALIAS', '/upfiles/', UPLOAD_SET, dict(\r
-label = _("Uploaded files alias"),\r
-help_text = _("The url alias for uploaded files. Notice that if you change this setting, you'll need to restart your site.")))\r
-\r
-ALLOW_MAX_FILE_SIZE = Setting('ALLOW_MAX_FILE_SIZE', 2.5, UPLOAD_SET, dict(\r
-label = _("Max file size"),\r
+import os.path
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+UPLOAD_SET = SettingSet('paths', _('File upload settings'), _("File uploads related settings."), 600)
+
+UPFILES_FOLDER = Setting('UPFILES_FOLDER', os.path.join(os.path.dirname(os.path.dirname(__file__)),'upfiles'), UPLOAD_SET, dict(
+label = _("Uploaded files folder"),
+help_text = _("The filesystem path where uploaded files will be stored. Please note that this folder must exist.")))
+
+UPFILES_ALIAS = Setting('UPFILES_ALIAS', '/upfiles/', UPLOAD_SET, dict(
+label = _("Uploaded files alias"),
+help_text = _("The url alias for uploaded files. Notice that if you change this setting, you'll need to restart your site.")))
+
+ALLOW_MAX_FILE_SIZE = Setting('ALLOW_MAX_FILE_SIZE', 2.5, UPLOAD_SET, dict(
+label = _("Max file size"),
 help_text = _("The maximum allowed file size for uploads in mb.")))
\ No newline at end of file
index aea915380e98e079935b1410b18ba1965623ffda..e4e81b60e86c01496b28207bdedb79c2d046da3e 100644 (file)
@@ -1,32 +1,32 @@
-from base import Setting, SettingSet\r
-from django.utils.translation import ugettext_lazy as _\r
-\r
-VOTE_RULES_SET = SettingSet('voting', _('Voting rules'), _("Configure the voting rules on your site."), 400)\r
-\r
-USER_REPUTATION_TO_MAX_VOTES = Setting('USER_REPUTATION_TO_MAX_VOTES', True, VOTE_RULES_SET, dict(\r
-label = _("Add reputation to max votes per day"), required=False,\r
-help_text = _("The user reputation is added to the static MAX_VOTES_PER_DAY option. Users with higher reputation can vote more.")))\r
-\r
-MAX_VOTES_PER_DAY = Setting('MAX_VOTES_PER_DAY', 30, VOTE_RULES_SET, dict(\r
-label = _("Maximum votes per day"),\r
-help_text = _("The maximum number of votes an user can cast per day.")))\r
-\r
-START_WARN_VOTES_LEFT = Setting('START_WARN_VOTES_LEFT', 10, VOTE_RULES_SET, dict(\r
-label = _("Start warning about votes left"),\r
-help_text = _("From how many votes left should an user start to be warned about it.")))\r
-\r
-MAX_FLAGS_PER_DAY = Setting('MAX_FLAGS_PER_DAY', 5, VOTE_RULES_SET, dict(\r
-label = _("Maximum flags per day"),\r
-help_text = _("The maximum number of times an can flag a post per day.")))\r
-\r
-FLAG_COUNT_TO_HIDE_POST = Setting('FLAG_COUNT_TO_HIDE_POST', 3, VOTE_RULES_SET, dict(\r
-label = _("Flag count to hide post"),\r
-help_text = _("How many times a post needs to be flagged to be hidden from the main page.")))\r
-\r
-FLAG_COUNT_TO_DELETE_POST = Setting('FLAG_COUNT_TO_DELETE_POST', 5, VOTE_RULES_SET, dict(\r
-label = _("Flag count to delete post"),\r
-help_text = _("How many times a post needs to be flagged to be deleted.")))\r
-\r
-DENY_UNVOTE_DAYS = Setting('DENY_UNVOTE_DAYS', 1, VOTE_RULES_SET, dict(\r
-label = _("Days to cancel a vote"),\r
+from base import Setting, SettingSet
+from django.utils.translation import ugettext_lazy as _
+
+VOTE_RULES_SET = SettingSet('voting', _('Voting rules'), _("Configure the voting rules on your site."), 400)
+
+USER_REPUTATION_TO_MAX_VOTES = Setting('USER_REPUTATION_TO_MAX_VOTES', True, VOTE_RULES_SET, dict(
+label = _("Add reputation to max votes per day"), required=False,
+help_text = _("The user reputation is added to the static MAX_VOTES_PER_DAY option. Users with higher reputation can vote more.")))
+
+MAX_VOTES_PER_DAY = Setting('MAX_VOTES_PER_DAY', 30, VOTE_RULES_SET, dict(
+label = _("Maximum votes per day"),
+help_text = _("The maximum number of votes an user can cast per day.")))
+
+START_WARN_VOTES_LEFT = Setting('START_WARN_VOTES_LEFT', 10, VOTE_RULES_SET, dict(
+label = _("Start warning about votes left"),
+help_text = _("From how many votes left should an user start to be warned about it.")))
+
+MAX_FLAGS_PER_DAY = Setting('MAX_FLAGS_PER_DAY', 5, VOTE_RULES_SET, dict(
+label = _("Maximum flags per day"),
+help_text = _("The maximum number of times an can flag a post per day.")))
+
+FLAG_COUNT_TO_HIDE_POST = Setting('FLAG_COUNT_TO_HIDE_POST', 3, VOTE_RULES_SET, dict(
+label = _("Flag count to hide post"),
+help_text = _("How many times a post needs to be flagged to be hidden from the main page.")))
+
+FLAG_COUNT_TO_DELETE_POST = Setting('FLAG_COUNT_TO_DELETE_POST', 5, VOTE_RULES_SET, dict(
+label = _("Flag count to delete post"),
+help_text = _("How many times a post needs to be flagged to be deleted.")))
+
+DENY_UNVOTE_DAYS = Setting('DENY_UNVOTE_DAYS', 1, VOTE_RULES_SET, dict(
+label = _("Days to cancel a vote"),
 help_text = _("How many days an user can cancel a vote after he originaly casted it.")))
\ No newline at end of file
index 909f599946a91c1b202e5eff0ee2f31a2ae1c9d4..6423ad44aa209775df05419313451f3f4f5fbe33 100755 (executable)
-<public:component>\r
-<script type="text/javascript">\r
-\r
-// IE5.5+ PNG Alpha Fix v2.0 Alpha\r
-// (c) 2004-2009 Angus Turnbull http://www.twinhelix.com\r
-\r
-// This is licensed under the GNU LGPL, version 2.1 or later.\r
-// For details, see: http://creativecommons.org/licenses/LGPL/2.1/\r
-\r
-var IEPNGFix = window.IEPNGFix || {};\r
-IEPNGFix.data = IEPNGFix.data || {};\r
-\r
-\r
-// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.\r
-// Try either:\r
-// * An absolute path like:  '/images/blank.gif'\r
-// * A path relative to this HTC file like:  thisFolder + 'blank.gif'\r
-var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');\r
-IEPNGFix.blankImg = thisFolder + 'blank.gif';\r
-\r
-\r
-IEPNGFix.fix = function(elm, src, t) {\r
-       // Applies an image 'src' to an element 'elm' using the DirectX filter.\r
-       // If 'src' is null, filter is disabled.\r
-       // Disables the 'hook' to prevent infinite recursion on setting BG/src.\r
-       // 't' = type, where background tile = 0, background = 1, IMG SRC = 2.\r
-\r
-       var h = this.hook.enabled;\r
-       this.hook.enabled = 0;\r
-\r
-       var f = 'DXImageTransform.Microsoft.AlphaImageLoader';\r
-               src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');\r
-\r
-       if (\r
-               src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&\r
-               elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'\r
-       ) {\r
-               if (elm.offsetWidth) {\r
-                       elm.style.width = elm.offsetWidth + 'px';\r
-               }\r
-               if (elm.clientHeight) {\r
-                       elm.style.height = elm.clientHeight + 'px';\r
-               }\r
-               if (elm.currentStyle.display == 'inline') {\r
-                       elm.style.display = 'inline-block';\r
-               }\r
-       }\r
-\r
-       if (t == 1) {\r
-               elm.style.backgroundImage = 'url("' + this.blankImg + '")';\r
-       }\r
-       if (t == 2) {\r
-               elm.src = this.blankImg;\r
-       }\r
-\r
-       if (elm.filters[f]) {\r
-               elm.filters[f].enabled = src ? true : false;\r
-               if (src) {\r
-                       elm.filters[f].src = src;\r
-               }\r
-       } else if (src) {\r
-               elm.style.filter = 'progid:' + f + '(src="' + src +\r
-                       '",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';\r
-       }\r
-\r
-       this.hook.enabled = h;\r
-};\r
-\r
-\r
-IEPNGFix.process = function(elm, init) {\r
-       // Checks the onpropertychange event (on first 'init' run, a fake event)\r
-       // and calls the filter-applying-functions.\r
-\r
-       if (\r
-               !/MSIE (5\.5|6)/.test(navigator.userAgent) ||\r
-               typeof elm.filters == 'unknown'\r
-       ) {\r
-               return;\r
-       }\r
-       if (!this.data[elm.uniqueID]) {\r
-               this.data[elm.uniqueID] = {\r
-                       className: ''\r
-               };\r
-       }\r
-       var data = this.data[elm.uniqueID],\r
-               evt = init ? { propertyName: 'src,backgroundImage' } : event,\r
-               isSrc = /src/.test(evt.propertyName),\r
-               isBg = /backgroundImage/.test(evt.propertyName),\r
-               isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),\r
-               isClass = !init && ((elm.className != data.className) &&\r
-                       (elm.className || data.className));\r
-       if (!(isSrc || isBg || isPos || isClass)) {\r
-               return;\r
-       }\r
-       data.className = elm.className;\r
-       var blank = this.blankImg.match(/([^\/]+)$/)[1],\r
-               eS = elm.style,\r
-               eCS = elm.currentStyle;\r
-\r
-       // Required for Whatever:hover - erase set BG if className changes.\r
-       if (\r
-               isClass && (eS.backgroundImage.indexOf('url(') == -1 ||\r
-               eS.backgroundImage.indexOf(blank) > -1)\r
-       ) {\r
-               return setTimeout(function() {\r
-                       eS.backgroundImage = '';\r
-               }, 0);\r
-       }\r
-\r
-       // Foregrounds.\r
-       if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {\r
-               if ((/\.png/i).test(elm.src)) {\r
-                       if (!elm.oSrc) {\r
-                               // MM rollover compat\r
-                               elm.oSrc = elm.src;\r
-                       }\r
-                       this.fix(elm, elm.src, 2);\r
-               } else if (elm.src.indexOf(blank) == -1) {\r
-                       this.fix(elm, '');\r
-               }\r
-       }\r
-\r
-       // Backgrounds.\r
-       var bgSrc = eCS.backgroundImage || eS.backgroundImage;\r
-       if ((bgSrc + elm.src).indexOf(blank) == -1) {\r
-               var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);\r
-               if (bgPNG) {\r
-                       if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {\r
-                               this.tileBG(elm, bgPNG[1]);\r
-                               this.fix(elm, '', 1);\r
-                       } else {\r
-                               if (data.tiles && data.tiles.src) {\r
-                                       this.tileBG(elm, '');\r
-                               }\r
-                               this.fix(elm, bgPNG[1], 1);\r
-                               this.childFix(elm);\r
-                       }\r
-               } else {\r
-                       if (data.tiles && data.tiles.src) {\r
-                               this.tileBG(elm, '');\r
-                       }\r
-                       this.fix(elm, '');\r
-               }\r
-       } else if ((isPos || isClass) && data.tiles && data.tiles.src) {\r
-               this.tileBG(elm, data.tiles.src);\r
-       }\r
-\r
-       if (init) {\r
-               this.hook.enabled = 1;\r
-               elm.attachEvent('onpropertychange', this.hook);\r
-       }\r
-};\r
-\r
-\r
-IEPNGFix.childFix = function(elm) {\r
-       // "hasLayout" fix for unclickable children inside PNG backgrounds.\r
-       var tags = [\r
-                       'a',\r
-                       'input',\r
-                       'select',\r
-                       'textarea',\r
-                       'button',\r
-                       'iframe',\r
-                       'object'\r
-               ],\r
-               t = tags.length,\r
-               tFix = [];\r
-       while (t--) {\r
-               var pFix = elm.all.tags(tags[t]),\r
-                       e = pFix.length;\r
-               while (e--) {\r
-                       tFix.push(pFix[e]);\r
-               }\r
-       }\r
-       t = tFix.length;\r
-       if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {\r
-               alert('IEPNGFix: Unclickable children of element:' +\r
-                       '\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');\r
-       }\r
-       while (t--) {\r
-               if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {\r
-                       tFix[t].style.position = 'relative';\r
-               }\r
-       }\r
-};\r
-\r
-\r
-IEPNGFix.hook = function() {\r
-       if (IEPNGFix.hook.enabled) {\r
-               IEPNGFix.process(element, 0);\r
-       }\r
-};\r
-\r
-\r
-IEPNGFix.process(element, 1);\r
-\r
-</script>\r
-</public:component>\r
+<public:component>
+<script type="text/javascript">
+
+// IE5.5+ PNG Alpha Fix v2.0 Alpha
+// (c) 2004-2009 Angus Turnbull http://www.twinhelix.com
+
+// This is licensed under the GNU LGPL, version 2.1 or later.
+// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
+
+var IEPNGFix = window.IEPNGFix || {};
+IEPNGFix.data = IEPNGFix.data || {};
+
+
+// CONFIG: blankImg is the path to blank.gif, *relative to the HTML document*.
+// Try either:
+// * An absolute path like:  '/images/blank.gif'
+// * A path relative to this HTC file like:  thisFolder + 'blank.gif'
+var thisFolder = document.URL.replace(/(\\|\/)[^\\\/]*$/, '/');
+IEPNGFix.blankImg = thisFolder + 'blank.gif';
+
+
+IEPNGFix.fix = function(elm, src, t) {
+       // Applies an image 'src' to an element 'elm' using the DirectX filter.
+       // If 'src' is null, filter is disabled.
+       // Disables the 'hook' to prevent infinite recursion on setting BG/src.
+       // 't' = type, where background tile = 0, background = 1, IMG SRC = 2.
+
+       var h = this.hook.enabled;
+       this.hook.enabled = 0;
+
+       var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+               src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');
+
+       if (
+               src && !(/IMG|INPUT/.test(elm.nodeName) && (t != 2)) &&
+               elm.currentStyle.width == 'auto' && elm.currentStyle.height == 'auto'
+       ) {
+               if (elm.offsetWidth) {
+                       elm.style.width = elm.offsetWidth + 'px';
+               }
+               if (elm.clientHeight) {
+                       elm.style.height = elm.clientHeight + 'px';
+               }
+               if (elm.currentStyle.display == 'inline') {
+                       elm.style.display = 'inline-block';
+               }
+       }
+
+       if (t == 1) {
+               elm.style.backgroundImage = 'url("' + this.blankImg + '")';
+       }
+       if (t == 2) {
+               elm.src = this.blankImg;
+       }
+
+       if (elm.filters[f]) {
+               elm.filters[f].enabled = src ? true : false;
+               if (src) {
+                       elm.filters[f].src = src;
+               }
+       } else if (src) {
+               elm.style.filter = 'progid:' + f + '(src="' + src +
+                       '",sizingMethod="' + (t == 2 ? 'scale' : 'crop') + '")';
+       }
+
+       this.hook.enabled = h;
+};
+
+
+IEPNGFix.process = function(elm, init) {
+       // Checks the onpropertychange event (on first 'init' run, a fake event)
+       // and calls the filter-applying-functions.
+
+       if (
+               !/MSIE (5\.5|6)/.test(navigator.userAgent) ||
+               typeof elm.filters == 'unknown'
+       ) {
+               return;
+       }
+       if (!this.data[elm.uniqueID]) {
+               this.data[elm.uniqueID] = {
+                       className: ''
+               };
+       }
+       var data = this.data[elm.uniqueID],
+               evt = init ? { propertyName: 'src,backgroundImage' } : event,
+               isSrc = /src/.test(evt.propertyName),
+               isBg = /backgroundImage/.test(evt.propertyName),
+               isPos = /width|height|background(Pos|Rep)/.test(evt.propertyName),
+               isClass = !init && ((elm.className != data.className) &&
+                       (elm.className || data.className));
+       if (!(isSrc || isBg || isPos || isClass)) {
+               return;
+       }
+       data.className = elm.className;
+       var blank = this.blankImg.match(/([^\/]+)$/)[1],
+               eS = elm.style,
+               eCS = elm.currentStyle;
+
+       // Required for Whatever:hover - erase set BG if className changes.
+       if (
+               isClass && (eS.backgroundImage.indexOf('url(') == -1 ||
+               eS.backgroundImage.indexOf(blank) > -1)
+       ) {
+               return setTimeout(function() {
+                       eS.backgroundImage = '';
+               }, 0);
+       }
+
+       // Foregrounds.
+       if (isSrc && elm.src && { IMG: 1, INPUT: 1 }[elm.nodeName]) {
+               if ((/\.png/i).test(elm.src)) {
+                       if (!elm.oSrc) {
+                               // MM rollover compat
+                               elm.oSrc = elm.src;
+                       }
+                       this.fix(elm, elm.src, 2);
+               } else if (elm.src.indexOf(blank) == -1) {
+                       this.fix(elm, '');
+               }
+       }
+
+       // Backgrounds.
+       var bgSrc = eCS.backgroundImage || eS.backgroundImage;
+       if ((bgSrc + elm.src).indexOf(blank) == -1) {
+               var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
+               if (bgPNG) {
+                       if (this.tileBG && !{ IMG: 1, INPUT: 1 }[elm.nodeName]) {
+                               this.tileBG(elm, bgPNG[1]);
+                               this.fix(elm, '', 1);
+                       } else {
+                               if (data.tiles && data.tiles.src) {
+                                       this.tileBG(elm, '');
+                               }
+                               this.fix(elm, bgPNG[1], 1);
+                               this.childFix(elm);
+                       }
+               } else {
+                       if (data.tiles && data.tiles.src) {
+                               this.tileBG(elm, '');
+                       }
+                       this.fix(elm, '');
+               }
+       } else if ((isPos || isClass) && data.tiles && data.tiles.src) {
+               this.tileBG(elm, data.tiles.src);
+       }
+
+       if (init) {
+               this.hook.enabled = 1;
+               elm.attachEvent('onpropertychange', this.hook);
+       }
+};
+
+
+IEPNGFix.childFix = function(elm) {
+       // "hasLayout" fix for unclickable children inside PNG backgrounds.
+       var tags = [
+                       'a',
+                       'input',
+                       'select',
+                       'textarea',
+                       'button',
+                       'iframe',
+                       'object'
+               ],
+               t = tags.length,
+               tFix = [];
+       while (t--) {
+               var pFix = elm.all.tags(tags[t]),
+                       e = pFix.length;
+               while (e--) {
+                       tFix.push(pFix[e]);
+               }
+       }
+       t = tFix.length;
+       if (t && (/relative|absolute/i).test(elm.currentStyle.position)) {
+               alert('IEPNGFix: Unclickable children of element:' +
+                       '\n\n<' + elm.nodeName + (elm.id && ' id=' + elm.id) + '>');
+       }
+       while (t--) {
+               if (!(/relative|absolute/i).test(tFix[t].currentStyle.position)) {
+                       tFix[t].style.position = 'relative';
+               }
+       }
+};
+
+
+IEPNGFix.hook = function() {
+       if (IEPNGFix.hook.enabled) {
+               IEPNGFix.process(element, 0);
+       }
+};
+
+
+IEPNGFix.process(element, 1);
+
+</script>
+</public:component>
index 6a1ff4955bf3eec68eb312fccc97d4a8cc8d4e1e..42522537d0d1f3625f605f3a147848410d5b95a1 100755 (executable)
-// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support\r
-// (c) 2008-2009 Angus Turnbull http://www.twinhelix.com\r
-\r
-// This is licensed under the GNU LGPL, version 2.1 or later.\r
-// For details, see: http://creativecommons.org/licenses/LGPL/2.1/\r
-\r
-var IEPNGFix = window.IEPNGFix || {};\r
-\r
-IEPNGFix.tileBG = function(elm, pngSrc, ready) {\r
-       // Params: A reference to a DOM element, the PNG src file pathname, and a\r
-       // hidden "ready-to-run" passed when called back after image preloading.\r
-\r
-       var data = this.data[elm.uniqueID],\r
-               elmW = Math.max(elm.clientWidth, elm.scrollWidth),\r
-               elmH = Math.max(elm.clientHeight, elm.scrollHeight),\r
-               bgX = elm.currentStyle.backgroundPositionX,\r
-               bgY = elm.currentStyle.backgroundPositionY,\r
-               bgR = elm.currentStyle.backgroundRepeat;\r
-\r
-       // Cache of DIVs created per element, and image preloader/data.\r
-       if (!data.tiles) {\r
-               data.tiles = {\r
-                       elm: elm,\r
-                       src: '',\r
-                       cache: [],\r
-                       img: new Image(),\r
-                       old: {}\r
-               };\r
-       }\r
-       var tiles = data.tiles,\r
-               pngW = tiles.img.width,\r
-               pngH = tiles.img.height;\r
-\r
-       if (pngSrc) {\r
-               if (!ready && pngSrc != tiles.src) {\r
-                       // New image? Preload it with a callback to detect dimensions.\r
-                       tiles.img.onload = function() {\r
-                               this.onload = null;\r
-                               IEPNGFix.tileBG(elm, pngSrc, 1);\r
-                       };\r
-                       return tiles.img.src = pngSrc;\r
-               }\r
-       } else {\r
-               // No image?\r
-               if (tiles.src) ready = 1;\r
-               pngW = pngH = 0;\r
-       }\r
-       tiles.src = pngSrc;\r
-\r
-       if (!ready && elmW == tiles.old.w && elmH == tiles.old.h &&\r
-               bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {\r
-               return;\r
-       }\r
-\r
-       // Convert English and percentage positions to pixels.\r
-       var pos = {\r
-                       top: '0%',\r
-                       left: '0%',\r
-                       center: '50%',\r
-                       bottom: '100%',\r
-                       right: '100%'\r
-               },\r
-               x,\r
-               y,\r
-               pc;\r
-       x = pos[bgX] || bgX;\r
-       y = pos[bgY] || bgY;\r
-       if (pc = x.match(/(\d+)%/)) {\r
-               x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100));\r
-       }\r
-       if (pc = y.match(/(\d+)%/)) {\r
-               y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100));\r
-       }\r
-       x = parseInt(x);\r
-       y = parseInt(y);\r
-\r
-       // Handle backgroundRepeat.\r
-       var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR],\r
-               repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];\r
-       if (repeatX) {\r
-               x %= pngW;\r
-               if (x > 0) x -= pngW;\r
-       }\r
-       if (repeatY) {\r
-               y %= pngH;\r
-               if (y > 0) y -= pngH;\r
-       }\r
-\r
-       // Go!\r
-       this.hook.enabled = 0;\r
-       if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) {\r
-               elm.style.position = 'relative';\r
-       }\r
-       var count = 0,\r
-               xPos,\r
-               maxX = repeatX ? elmW : x + 0.1,\r
-               yPos,\r
-               maxY = repeatY ? elmH : y + 0.1,\r
-               d,\r
-               s,\r
-               isNew;\r
-       if (pngW && pngH) {\r
-               for (xPos = x; xPos < maxX; xPos += pngW) {\r
-                       for (yPos = y; yPos < maxY; yPos += pngH) {\r
-                               isNew = 0;\r
-                               if (!tiles.cache[count]) {\r
-                                       tiles.cache[count] = document.createElement('div');\r
-                                       isNew = 1;\r
-                               }\r
-                               var clipR = Math.max(0, xPos + pngW > elmW ? elmW - xPos : pngW),\r
-                                       clipB = Math.max(0, yPos + pngH > elmH ? elmH - yPos : pngH);\r
-                               d = tiles.cache[count];\r
-                               s = d.style;\r
-                               s.behavior = 'none';\r
-                               s.left = (xPos - parseInt(elm.currentStyle.paddingLeft)) + 'px';\r
-                               s.top = yPos + 'px';\r
-                               s.width = clipR + 'px';\r
-                               s.height = clipB + 'px';\r
-                               s.clip = 'rect(' +\r
-                                       (yPos < 0 ? 0 - yPos : 0) + 'px,' +\r
-                                       clipR + 'px,' +\r
-                                       clipB + 'px,' +\r
-                                       (xPos < 0 ? 0 - xPos : 0) + 'px)';\r
-                               s.display = 'block';\r
-                               if (isNew) {\r
-                                       s.position = 'absolute';\r
-                                       s.zIndex = -999;\r
-                                       if (elm.firstChild) {\r
-                                               elm.insertBefore(d, elm.firstChild);\r
-                                       } else {\r
-                                               elm.appendChild(d);\r
-                                       }\r
-                               }\r
-                               this.fix(d, pngSrc, 0);\r
-                               count++;\r
-                       }\r
-               }\r
-       }\r
-       while (count < tiles.cache.length) {\r
-               this.fix(tiles.cache[count], '', 0);\r
-               tiles.cache[count++].style.display = 'none';\r
-       }\r
-\r
-       this.hook.enabled = 1;\r
-\r
-       // Cache so updates are infrequent.\r
-       tiles.old = {\r
-               w: elmW,\r
-               h: elmH,\r
-               x: bgX,\r
-               y: bgY,\r
-               r: bgR\r
-       };\r
-};\r
-\r
-\r
-IEPNGFix.update = function() {\r
-       // Update all PNG backgrounds.\r
-       for (var i in IEPNGFix.data) {\r
-               var t = IEPNGFix.data[i].tiles;\r
-               if (t && t.elm && t.src) {\r
-                       IEPNGFix.tileBG(t.elm, t.src);\r
-               }\r
-       }\r
-};\r
-IEPNGFix.update.timer = 0;\r
-\r
-if (window.attachEvent && !window.opera) {\r
-       window.attachEvent('onresize', function() {\r
-               clearTimeout(IEPNGFix.update.timer);\r
-               IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100);\r
-       });\r
-}\r
+// IE5.5+ PNG Alpha Fix v2.0 Alpha: Background Tiling Support
+// (c) 2008-2009 Angus Turnbull http://www.twinhelix.com
+
+// This is licensed under the GNU LGPL, version 2.1 or later.
+// For details, see: http://creativecommons.org/licenses/LGPL/2.1/
+
+var IEPNGFix = window.IEPNGFix || {};
+
+IEPNGFix.tileBG = function(elm, pngSrc, ready) {
+       // Params: A reference to a DOM element, the PNG src file pathname, and a
+       // hidden "ready-to-run" passed when called back after image preloading.
+
+       var data = this.data[elm.uniqueID],
+               elmW = Math.max(elm.clientWidth, elm.scrollWidth),
+               elmH = Math.max(elm.clientHeight, elm.scrollHeight),
+               bgX = elm.currentStyle.backgroundPositionX,
+               bgY = elm.currentStyle.backgroundPositionY,
+               bgR = elm.currentStyle.backgroundRepeat;
+
+       // Cache of DIVs created per element, and image preloader/data.
+       if (!data.tiles) {
+               data.tiles = {
+                       elm: elm,
+                       src: '',
+                       cache: [],
+                       img: new Image(),
+                       old: {}
+               };
+       }
+       var tiles = data.tiles,
+               pngW = tiles.img.width,
+               pngH = tiles.img.height;
+
+       if (pngSrc) {
+               if (!ready && pngSrc != tiles.src) {
+                       // New image? Preload it with a callback to detect dimensions.
+                       tiles.img.onload = function() {
+                               this.onload = null;
+                               IEPNGFix.tileBG(elm, pngSrc, 1);
+                       };
+                       return tiles.img.src = pngSrc;
+               }
+       } else {
+               // No image?
+               if (tiles.src) ready = 1;
+               pngW = pngH = 0;
+       }
+       tiles.src = pngSrc;
+
+       if (!ready && elmW == tiles.old.w && elmH == tiles.old.h &&
+               bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r) {
+               return;
+       }
+
+       // Convert English and percentage positions to pixels.
+       var pos = {
+                       top: '0%',
+                       left: '0%',
+                       center: '50%',
+                       bottom: '100%',
+                       right: '100%'
+               },
+               x,
+               y,
+               pc;
+       x = pos[bgX] || bgX;
+       y = pos[bgY] || bgY;
+       if (pc = x.match(/(\d+)%/)) {
+               x = Math.round((elmW - pngW) * (parseInt(pc[1]) / 100));
+       }
+       if (pc = y.match(/(\d+)%/)) {
+               y = Math.round((elmH - pngH) * (parseInt(pc[1]) / 100));
+       }
+       x = parseInt(x);
+       y = parseInt(y);
+
+       // Handle backgroundRepeat.
+       var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR],
+               repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];
+       if (repeatX) {
+               x %= pngW;
+               if (x > 0) x -= pngW;
+       }
+       if (repeatY) {
+               y %= pngH;
+               if (y > 0) y -= pngH;
+       }
+
+       // Go!
+       this.hook.enabled = 0;
+       if (!({ relative: 1, absolute: 1 }[elm.currentStyle.position])) {
+               elm.style.position = 'relative';
+       }
+       var count = 0,
+               xPos,
+               maxX = repeatX ? elmW : x + 0.1,
+               yPos,
+               maxY = repeatY ? elmH : y + 0.1,
+               d,
+               s,
+               isNew;
+       if (pngW && pngH) {
+               for (xPos = x; xPos < maxX; xPos += pngW) {
+                       for (yPos = y; yPos < maxY; yPos += pngH) {
+                               isNew = 0;
+                               if (!tiles.cache[count]) {
+                                       tiles.cache[count] = document.createElement('div');
+                                       isNew = 1;
+                               }
+                               var clipR = Math.max(0, xPos + pngW > elmW ? elmW - xPos : pngW),
+                                       clipB = Math.max(0, yPos + pngH > elmH ? elmH - yPos : pngH);
+                               d = tiles.cache[count];
+                               s = d.style;
+                               s.behavior = 'none';
+                               s.left = (xPos - parseInt(elm.currentStyle.paddingLeft)) + 'px';
+                               s.top = yPos + 'px';
+                               s.width = clipR + 'px';
+                               s.height = clipB + 'px';
+                               s.clip = 'rect(' +
+                                       (yPos < 0 ? 0 - yPos : 0) + 'px,' +
+                                       clipR + 'px,' +
+                                       clipB + 'px,' +
+                                       (xPos < 0 ? 0 - xPos : 0) + 'px)';
+                               s.display = 'block';
+                               if (isNew) {
+                                       s.position = 'absolute';
+                                       s.zIndex = -999;
+                                       if (elm.firstChild) {
+                                               elm.insertBefore(d, elm.firstChild);
+                                       } else {
+                                               elm.appendChild(d);
+                                       }
+                               }
+                               this.fix(d, pngSrc, 0);
+                               count++;
+                       }
+               }
+       }
+       while (count < tiles.cache.length) {
+               this.fix(tiles.cache[count], '', 0);
+               tiles.cache[count++].style.display = 'none';
+       }
+
+       this.hook.enabled = 1;
+
+       // Cache so updates are infrequent.
+       tiles.old = {
+               w: elmW,
+               h: elmH,
+               x: bgX,
+               y: bgY,
+               r: bgR
+       };
+};
+
+
+IEPNGFix.update = function() {
+       // Update all PNG backgrounds.
+       for (var i in IEPNGFix.data) {
+               var t = IEPNGFix.data[i].tiles;
+               if (t && t.elm && t.src) {
+                       IEPNGFix.tileBG(t.elm, t.src);
+               }
+       }
+};
+IEPNGFix.update.timer = 0;
+
+if (window.attachEvent && !window.opera) {
+       window.attachEvent('onresize', function() {
+               clearTimeout(IEPNGFix.update.timer);
+               IEPNGFix.update.timer = setTimeout(IEPNGFix.update, 100);
+       });
+}
index d22d511ba6a3c1091c083b5ba98330e214af43f0..7a00ee556f5d48b645c479b15d641efcab864129 100644 (file)
@@ -1,10 +1,10 @@
-/*\r
- *\r
- * Copyright (c) 2010 C. F., Wong (<a href="http://cloudgen.w0ng.hk">Cloudgen Examplet Store</a>)\r
- * Licensed under the MIT License:\r
- * http://www.opensource.org/licenses/mit-license.php\r
- *\r
- */\r
-(function(k,e,i,j){k.fn.caret=function(b,l){var a,c,f=this[0],d=k.browser.msie;if(typeof b==="object"&&typeof b.start==="number"&&typeof b.end==="number"){a=b.start;c=b.end}else if(typeof b==="number"&&typeof l==="number"){a=b;c=l}else if(typeof b==="string")if((a=f.value.indexOf(b))>-1)c=a+b[e];else a=null;else if(Object.prototype.toString.call(b)==="[object RegExp]"){b=b.exec(f.value);if(b!=null){a=b.index;c=a+b[0][e]}}if(typeof a!="undefined"){if(d){d=this[0].createTextRange();d.collapse(true);\r
-d.moveStart("character",a);d.moveEnd("character",c-a);d.select()}else{this[0].selectionStart=a;this[0].selectionEnd=c}this[0].focus();return this}else{if(d){c=document.selection;if(this[0].tagName.toLowerCase()!="textarea"){d=this.val();a=c[i]()[j]();a.moveEnd("character",d[e]);var g=a.text==""?d[e]:d.lastIndexOf(a.text);a=c[i]()[j]();a.moveStart("character",-d[e]);var h=a.text[e]}else{a=c[i]();c=a[j]();c.moveToElementText(this[0]);c.setEndPoint("EndToEnd",a);g=c.text[e]-a.text[e];h=g+a.text[e]}}else{g=\r
+/*
+ *
+ * Copyright (c) 2010 C. F., Wong (<a href="http://cloudgen.w0ng.hk">Cloudgen Examplet Store</a>)
+ * Licensed under the MIT License:
+ * http://www.opensource.org/licenses/mit-license.php
+ *
+ */
+(function(k,e,i,j){k.fn.caret=function(b,l){var a,c,f=this[0],d=k.browser.msie;if(typeof b==="object"&&typeof b.start==="number"&&typeof b.end==="number"){a=b.start;c=b.end}else if(typeof b==="number"&&typeof l==="number"){a=b;c=l}else if(typeof b==="string")if((a=f.value.indexOf(b))>-1)c=a+b[e];else a=null;else if(Object.prototype.toString.call(b)==="[object RegExp]"){b=b.exec(f.value);if(b!=null){a=b.index;c=a+b[0][e]}}if(typeof a!="undefined"){if(d){d=this[0].createTextRange();d.collapse(true);
+d.moveStart("character",a);d.moveEnd("character",c-a);d.select()}else{this[0].selectionStart=a;this[0].selectionEnd=c}this[0].focus();return this}else{if(d){c=document.selection;if(this[0].tagName.toLowerCase()!="textarea"){d=this.val();a=c[i]()[j]();a.moveEnd("character",d[e]);var g=a.text==""?d[e]:d.lastIndexOf(a.text);a=c[i]()[j]();a.moveStart("character",-d[e]);var h=a.text[e]}else{a=c[i]();c=a[j]();c.moveToElementText(this[0]);c.setEndPoint("EndToEnd",a);g=c.text[e]-a.text[e];h=g+a.text[e]}}else{g=
 f.selectionStart;h=f.selectionEnd}a=f.value.substring(g,h);return{start:g,end:h,text:a,replace:function(m){return f.value.substring(0,g)+m+f.value.substring(h,f.value[e])}}}}})(jQuery,"length","createRange","duplicate");
\ No newline at end of file
index ccd71036d5ac2df8c3b8d9594e8e580e1e33ae64..cdeeddc45c5fceffb7c9be0c433ecbd91a883f5a 100644 (file)
@@ -1,83 +1,83 @@
-$(function() {\r
-    $('.string_list_widget_button').live('click', function() {\r
-        $but = $(this);\r
-\r
-        if ($but.is('.add')) {\r
-            $new = $("<div style=\"display: none;\">" +\r
-                    "<input style=\"width: 600px;\" type=\"text\" name=\"" + $but.attr('name') + "\" value=\"\" />" +\r
-                    "<button class=\"string_list_widget_button\">-</button>" +\r
-                    "</div>");\r
-\r
-            $but.before($new);\r
-            $new.slideDown('fast');\r
-        } else {\r
-            $but.parent().slideUp('fast', function() {\r
-                $but.parent().remove();\r
-            });\r
-        }\r
-\r
-        return false;\r
-    })\r
-\r
-    $('.fieldtool').each(function() {\r
-        var $link = $(this);\r
-        var $input = $link.parent().parent().find('input, textarea');\r
-        var name = $input.attr('name')\r
-\r
-        if ($link.is('.context')) {\r
-            $link.click(function() {\r
-                var $contextbox = $('<input type="text" value="' + name + '" />');\r
-                $link.replaceWith($contextbox);\r
-            });\r
-        } else if ($link.is('.default')) {\r
-            if ($input.length == 1 && ($input.is('[type=text]') || $input.is('textarea'))) {\r
-                $link.click(function() {\r
-                    $.post(name + '/', function(data) {\r
-                        $input.val(data);\r
-                    });\r
-                });\r
-            } else {\r
-                $link.attr('href', name + '/');\r
-            }\r
-        }\r
-    });\r
-\r
-    $('.url_field').each(function() {\r
-        var $input = $(this);\r
-        var $anchor = $input.parent().find('.url_field_anchor');\r
-        var app_url = $anchor.attr('href');\r
-\r
-        function rewrite_anchor() {\r
-            var val = app_url + '/' +  $input.val();\r
-\r
-            $anchor.attr('href', val);\r
-            $anchor.html(val);\r
-\r
-        }\r
-\r
-        $input.keyup(rewrite_anchor);\r
-        rewrite_anchor();        \r
-    });\r
-\r
-    $('#test_email_settings a.test_button').click(function() {\r
-        $('div.test_status').hide('slow')\r
-        $('div.ajax_indicator').show('fast')\r
-        $.post($(this).attr('href'), function(data) {\r
-            $('div.ajax_indicator').hide('fast')\r
-            $('div.test_status').html(data)\r
-            $('div.test_status').show('slow')\r
-        })\r
-    })\r
-});\r
-\r
-/*\r
- * Autocomplete - jQuery plugin 1.0.3\r
- *\r
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, J�rn Zaefferer\r
- *\r
- * Dual licensed under the MIT and GPL licenses:\r
- *   http://www.opensource.org/licenses/mit-license.php\r
- *   http://www.gnu.org/licenses/gpl.html\r
- *\r
- */\r
-(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);\r
+$(function() {
+    $('.string_list_widget_button').live('click', function() {
+        $but = $(this);
+
+        if ($but.is('.add')) {
+            $new = $("<div style=\"display: none;\">" +
+                    "<input style=\"width: 600px;\" type=\"text\" name=\"" + $but.attr('name') + "\" value=\"\" />" +
+                    "<button class=\"string_list_widget_button\">-</button>" +
+                    "</div>");
+
+            $but.before($new);
+            $new.slideDown('fast');
+        } else {
+            $but.parent().slideUp('fast', function() {
+                $but.parent().remove();
+            });
+        }
+
+        return false;
+    })
+
+    $('.fieldtool').each(function() {
+        var $link = $(this);
+        var $input = $link.parent().parent().find('input, textarea');
+        var name = $input.attr('name')
+
+        if ($link.is('.context')) {
+            $link.click(function() {
+                var $contextbox = $('<input type="text" value="' + name + '" />');
+                $link.replaceWith($contextbox);
+            });
+        } else if ($link.is('.default')) {
+            if ($input.length == 1 && ($input.is('[type=text]') || $input.is('textarea'))) {
+                $link.click(function() {
+                    $.post(name + '/', function(data) {
+                        $input.val(data);
+                    });
+                });
+            } else {
+                $link.attr('href', name + '/');
+            }
+        }
+    });
+
+    $('.url_field').each(function() {
+        var $input = $(this);
+        var $anchor = $input.parent().find('.url_field_anchor');
+        var app_url = $anchor.attr('href');
+
+        function rewrite_anchor() {
+            var val = app_url + '/' +  $input.val();
+
+            $anchor.attr('href', val);
+            $anchor.html(val);
+
+        }
+
+        $input.keyup(rewrite_anchor);
+        rewrite_anchor();        
+    });
+
+    $('#test_email_settings a.test_button').click(function() {
+        $('div.test_status').hide('slow')
+        $('div.ajax_indicator').show('fast')
+        $.post($(this).attr('href'), function(data) {
+            $('div.ajax_indicator').hide('fast')
+            $('div.test_status').html(data)
+            $('div.test_status').show('slow')
+        })
+    })
+});
+
+/*
+ * Autocomplete - jQuery plugin 1.0.3
+ *
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, J�rn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
index 55a3f1e02611ceba240851212cb4b008ed49167c..0f11ef732c291cfb8f541c44868af80e0171ba44 100644 (file)
-/**\r
- * We do not want the CSRF protection enabled for the AJAX post requests, it causes only trouble.\r
- * Get the csrftoken cookie and pass it to the X-CSRFToken HTTP request property.\r
- */\r
-\r
-$('html').ajaxSend(function(event, xhr, settings) {\r
-    function getCookie(name) {\r
-        var cookieValue = null;\r
-        if (document.cookie && document.cookie != '') {\r
-            var cookies = document.cookie.split(';');\r
-            for (var i = 0; i < cookies.length; i++) {\r
-                var cookie = jQuery.trim(cookies[i]);\r
-                // Does this cookie string begin with the name we want?\r
-                if (cookie.substring(0, name.length + 1) == (name + '=')) {\r
-                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\r
-                    break;\r
-                }\r
-            }\r
-        }\r
-        return cookieValue;\r
-    }\r
-    try {\r
-        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {\r
-            // Only send the token to relative URLs i.e. locally.\r
-            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));\r
-        }\r
-    } catch (e) {}\r
-});\r
-\r
-var response_commands = {\r
-    refresh_page: function() {\r
-        window.location.reload(true)\r
-    },\r
-    \r
-    update_post_score: function(id, inc) {\r
-        var $score_board = $('#post-' + id + '-score');\r
-        var current = parseInt($score_board.html())\r
-        if (isNaN(current)){\r
-            current = 0;\r
-        }\r
-        $score_board.html(current + inc)\r
-    },\r
-\r
-    update_user_post_vote: function(id, vote_type) {\r
-        var $upvote_button = $('#post-' + id + '-upvote');\r
-        var $downvote_button = $('#post-' + id + '-downvote');\r
-\r
-        $upvote_button.removeClass('on');\r
-        $downvote_button.removeClass('on');\r
-\r
-        if (vote_type == 'up') {\r
-            $upvote_button.addClass('on');\r
-        } else if (vote_type == 'down') {\r
-            $downvote_button.addClass('on');\r
-        }\r
-    },\r
-\r
-    update_favorite_count: function(inc) {\r
-        var $favorite_count = $('#favorite-count');\r
-        var count = parseInt($favorite_count.html());\r
-\r
-        if (isNaN(count))\r
-            count = 0;\r
-\r
-        count += inc;\r
-\r
-        if (count == 0)\r
-            count = '';\r
-\r
-        $favorite_count.html(count);\r
-    },\r
-\r
-    update_favorite_mark: function(type) {\r
-        if (type == 'on') {\r
-            $('#favorite-mark').addClass('on');\r
-        } else {\r
-            $('#favorite-mark').removeClass('on');\r
-        }\r
-    },\r
-\r
-    mark_accepted: function(id) {        \r
-        var $answer = $('#answer-container-' + id);\r
-        $answer.addClass('accepted-answer');\r
-        $answer.find('.accept-answer').addClass('on');\r
-        $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:on'));\r
-    },\r
-\r
-    unmark_accepted: function(id) {\r
-        var $answer = $('#answer-container-' + id);\r
-        $answer.removeClass('accepted-answer');\r
-        $answer.find('.accept-answer').removeClass('on');\r
-        $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:off'));\r
-    },\r
-\r
-    remove_comment: function(id) {\r
-        var $comment = $('#comment-' + id);\r
-        $comment.css('background', 'red')\r
-        $comment.fadeOut('slow', function() {\r
-            $comment.remove();    \r
-        });\r
-    },\r
-\r
-    award_points: function(id) {\r
-        alert('ok');\r
-    },\r
-\r
-    insert_comment: function(post_id, comment_id, comment, username, profile_url, delete_url, edit_url, convert_url, can_convert, show_latest_comments_first) {\r
-        var $container = $('#comments-container-' + post_id);\r
-        var skeleton = $('#new-comment-skeleton-' + post_id).html().toString();\r
-\r
-        skeleton = skeleton.replace(new RegExp('%ID%', 'g'), comment_id)\r
-                .replace(new RegExp('%COMMENT%', 'g'), comment)\r
-                .replace(new RegExp('%USERNAME%', 'g'), username)\r
-                .replace(new RegExp('%PROFILE_URL%', 'g'), profile_url)\r
-                .replace(new RegExp('%DELETE_URL%', 'g'), delete_url)\r
-                .replace(new RegExp('%EDIT_URL%', 'g'), edit_url)\r
-                .replace(new RegExp('%CONVERT_URL%', 'g'), convert_url);\r
-        if (show_latest_comments_first) {\r
-            $container.prepend(skeleton);\r
-        } else {\r
-            $container.append(skeleton);\r
-        }\r
-\r
-        // Show the convert comment to answer tool only if the current comment can be converted\r
-        if (can_convert == true) {\r
-            $('#comment-' + comment_id + '-convert').show();\r
-        }\r
-\r
-        $('#comment-' + comment_id).slideDown('slow');\r
-    },\r
-\r
-    update_comment: function(comment_id, comment_text) {\r
-        var $comment = $('#comment-' + comment_id);\r
-        $comment.find('.comment-text').html(comment_text);\r
-\r
-        $comment.slideDown('slow');\r
-    },\r
-\r
-    mark_deleted: function(post_type, post_id) {\r
-        if (post_type == 'question') {\r
-            var $container = $('#question-table');\r
-            $container.addClass('deleted');\r
-        } else {\r
-            var $el = $('#' + post_type + '-container-' + post_id);\r
-            $el.addClass('deleted');\r
-        }\r
-    },\r
-\r
-    unmark_deleted: function(post_type, post_id) {\r
-        if (post_type == 'answer') {\r
-            var $answer = $('#answer-container-' + post_id);\r
-            $answer.removeClass('deleted');\r
-        } else {\r
-            var $container = $('#question-table');\r
-            $container.removeClass('deleted');\r
-        }\r
-    },\r
-\r
-    set_subscription_button: function(text) {\r
-        $('.subscription_switch').html(text);\r
-    },\r
-\r
-    set_subscription_status: function(text) {\r
-        $('.subscription-status').html(text);\r
-    },\r
-\r
-    copy_url: function(url) {\r
-    }\r
-}\r
-\r
-function show_dialog (extern) {\r
-    var default_close_function = function($diag) {\r
-        $diag.fadeOut('fast', function() {\r
-            $diag.remove();\r
-        });\r
-    };\r
-\r
-    var options = {\r
-        extra_class: '',\r
-        pos: {\r
-            x: ($(window).width() / 2) + $(window).scrollLeft(),\r
-            y: ($(window).height() / 2) + $(window).scrollTop()\r
-        },\r
-        dim: false, \r
-        yes_text: messages.ok,\r
-        yes_callback: default_close_function,\r
-        no_text: messages.cancel,\r
-        show_no: false,\r
-        close_on_clickoutside: false,\r
-        copy: false\r
-    }\r
-\r
-    $.extend(options, extern);\r
-\r
-    var copy_id = '';\r
-    if (options.copy) {\r
-        copy_id = ' id="copy_clip_button"'\r
-    }\r
-\r
-    if (options.event != undefined && options.event.pageX != undefined && options.event.pageY != undefined) {\r
-        options.pos = {x: options.event.pageX, y: options.event.pageY};\r
-    } else if (options.event.currentTarget != undefined) {\r
-        var el = jQuery("#" + options.event.currentTarget.id);\r
-        var position = el.offset();\r
-        options.pos = {\r
-            x: position.left,\r
-            y: position.top\r
-        }\r
-    }\r
-\r
-    var html = '<div class="dialog ' + options.extra_class + '" style="display: none; z-index: 999;">'\r
-             + '<div class="dialog-content">' + options.html + '</div><div class="dialog-buttons">';\r
-\r
-    if (options.show_no) {\r
-        html += '<button class="dialog-no">' + options.no_text + '</button>';\r
-    }\r
-\r
-    html += '<button class="dialog-yes"' + copy_id + '>' + options.yes_text + '</button>' + '</div></div>';\r
-\r
-    var $dialog = $(html);\r
-\r
-    $('body').append($dialog);\r
-    var message = $('.dialog-content')[0];\r
-    message.style.visibility = "hidden";\r
-\r
-    if (options.dim === false) {\r
-        $dialog.css({\r
-            visibility: 'hidden',\r
-            display: 'block'\r
-        });\r
-\r
-        options.dim = {w: $dialog.width(), h: $dialog.height()};\r
-\r
-        $dialog.css({\r
-            width: 1,\r
-            height: 1,\r
-            visibility: 'visible'\r
-        });\r
-    }\r
-\r
-    $dialog.css({\r
-        top: options.pos.y,\r
-        left: options.pos.x\r
-    });\r
-    \r
-    top_position_change = (options.dim.h / 2)\r
-    left_position_change = (options.dim.w / 2)\r
-    \r
-    new_top_position = options.pos.y - top_position_change\r
-    new_left_position = options.pos.x - left_position_change\r
-    \r
-    if (new_left_position < 0) {\r
-        left_position_change = 0\r
-    }\r
-    if (($(window).scrollTop() - new_top_position) > 0) {\r
-        top_position_change = 0\r
-    }\r
-    if ((options.event.pageY + options.dim.h) > ($(window).height() + $(window).scrollTop())) {\r
-        top_position_change = options.dim.h\r
-    }\r
-    if ((options.event.pageX + options.dim.w) > ($(window).width() + $(window).scrollLeft())) {\r
-        left_position_change = options.dim.w\r
-    }\r
-    \r
-    $dialog.animate({\r
-        top: "-=" + top_position_change,\r
-        left: "-=" + left_position_change,\r
-        width: options.dim.w,\r
-        height: options.dim.h\r
-    }, 200, function() {\r
-        message.style.visibility = "visible";\r
-    });\r
-\r
-    $dialog.find('.dialog-yes').click(function() {\r
-        options.yes_callback($dialog);\r
-    });\r
-\r
-    if (options.hasOwnProperty("no_callback")) {\r
-        $dialog.find('.dialog-no:first-child').click(function() {\r
-            options.no_callback($dialog);\r
-        });\r
-    } else {\r
-        $dialog.find('.dialog-no:first-child').click(function() {\r
-            default_close_function($dialog);\r
-        });\r
-    }\r
-\r
-    if (options.close_on_clickoutside) {\r
-        $dialog.one('clickoutside', function() {\r
-            default_close_function($dialog);\r
-        });\r
-    }\r
-\r
-    return $dialog;\r
-}\r
-\r
-function show_message(evt, msg, callback) {\r
-    var $dialog = show_dialog({\r
-        html: msg,\r
-        extra_class: 'warning',\r
-        event: evt,\r
-        yes_callback: function() {\r
-            $dialog.fadeOut('fast', function() {\r
-                $dialog.remove();\r
-            });\r
-            if (callback) {\r
-                callback();\r
-            }\r
-        },\r
-        close_on_clickoutside: true\r
-    });\r
-}\r
-\r
-function load_prompt(evt, el, url) {\r
-    $.get(url, function(data) {\r
-        var doptions = {\r
-         html: data,\r
-            extra_class: 'prompt',\r
-            yes_callback: function() {\r
-                var postvars = {};\r
-                $dialog.find('input, textarea, select').each(function() {\r
-                    postvars[$(this).attr('name')] = $(this).val();\r
-                });\r
-                $.post(url, postvars, function(data) {\r
-                    $dialog.fadeOut('fast', function() {\r
-                        $dialog.remove();\r
-                    });\r
-                    process_ajax_response(data, evt);\r
-                }, 'json');\r
-            },\r
-            show_no: true,\r
-            copy: false\r
-        }\r
-\r
-        if (el.hasClass('copy')) {\r
-            $.extend(doptions, { yes_text : 'Copy', copy: true});\r
-        }\r
-\r
-        if (!el.is('.centered')) {\r
-            doptions.event = evt;\r
-        }\r
-\r
-        var $dialog = show_dialog(doptions);\r
-    });\r
-}\r
-\r
-function process_ajax_response(data, evt, callback) {\r
-    if (!data.success && data['error_message'] != undefined) {\r
-        show_message(evt, data.error_message, function() {if (callback) callback(true);});\r
-        end_command(false);\r
-    }\r
-    if (typeof data['commands'] != undefined){\r
-        for (var command in data.commands) {\r
-            response_commands[command].apply(null, data.commands[command])\r
-\r
-\r
-        }\r
-\r
-        if (data['message'] != undefined) {\r
-            show_message(evt, data.message, function() {if (callback) callback(false);})\r
-        } else {\r
-            if (callback) callback(false);\r
-        }\r
-        end_command(true);\r
-    }\r
-}\r
-\r
-var running = false;\r
-\r
-function start_command() {\r
-    $('body').append($('<div id="command-loader"></div>'));\r
-    running = true;\r
-}\r
-\r
-function end_command(success) {\r
-    if (success) {\r
-        $('#command-loader').addClass('success');\r
-        $('#command-loader').fadeOut("slow", function() {\r
-            $('#command-loader').remove();\r
-            running = false;\r
-        });\r
-    } else {\r
-        $('#command-loader').remove();\r
-        running = false;\r
-    }\r
-}\r
-\r
-var comment_box_cursor_position = 0;\r
-function canned_comment(post_id, comment) {\r
-    textarea = $('#comment-' + post_id + '-form textarea')\r
-\r
-    // Get the text from the beginning to the caret\r
-    textarea_start = textarea.val().substr(0, comment_box_cursor_position)\r
-\r
-    // Get the text from the caret to the end\r
-    textarea_end = textarea.val().substr(comment_box_cursor_position, textarea.val().length)\r
-\r
-    textarea.val(textarea_start + comment + textarea_end);\r
-}\r
-\r
-$(function() {\r
-    $('textarea.commentBox').bind('keydown keyup mousedown mouseup mousemove', function(evt) {\r
-        comment_box_cursor_position = $(this).caret().start;\r
-    });\r
-\r
-    $('textarea.commentBox').blur(function() {\r
-        //alert(comment_box_cursor_position);\r
-    });\r
-\r
-    $('a.ajax-command').live('click', function(evt) {\r
-        if (running) return false;\r
-\r
-        var el = $(this);\r
-\r
-        var ajax_url = el.attr('href')\r
-        ajax_url = ajax_url + "?nocache=" + new Date().getTime()\r
-\r
-        $('.context-menu-dropdown').slideUp('fast');\r
-\r
-        if (el.is('.withprompt')) {\r
-            load_prompt(evt, el, ajax_url);\r
-        } else if(el.is('.confirm')) {\r
-            var doptions = {\r
-                html: messages.confirm,\r
-                extra_class: 'confirm',\r
-                yes_callback: function() {\r
-                    start_command();\r
-                    $.getJSON(ajax_url, function(data) {\r
-                        process_ajax_response(data, evt);\r
-                        $dialog.fadeOut('fast', function() {\r
-                            $dialog.remove();\r
-                        });\r
-                    });\r
-                },\r
-                yes_text: messages.yes,\r
-                show_no: true,\r
-                no_text: messages.no\r
-            }\r
-\r
-            if (!el.is('.centered')) {\r
-                doptions.event = evt;\r
-            }\r
-            var $dialog = show_dialog(doptions);\r
-        } else {\r
-            start_command();\r
-            $.ajax({\r
-                url: ajax_url,\r
-                type: "POST",\r
-                dataType: "json",\r
-                contentType: "application/json; charset=utf-8",\r
-                success: function(data) {\r
-                    process_ajax_response(data, evt);\r
-                }\r
-            });\r
-        }\r
-\r
-        return false\r
-    });\r
-\r
-    $('.context-menu').each(function() {\r
-        var $menu = $(this);\r
-        var $trigger = $menu.find('.context-menu-trigger');\r
-        var $dropdown = $menu.find('.context-menu-dropdown');\r
-\r
-        $trigger.click(function() {\r
-            $dropdown.slideToggle('fast', function() {\r
-                if ($dropdown.is(':visible')) {\r
-                   $dropdown.one('clickoutside', function() {\r
-                       if ($dropdown.is(':visible'))\r
-                            $dropdown.slideUp('fast');\r
-                    });\r
-                }\r
-            });    \r
-        });\r
-    });\r
-\r
-    $('div.comment-form-container').each(function() {\r
-        var $container = $(this);\r
-        var $comment_tools = $container.parent().find('.comment-tools');\r
-        var $comments_container = $container.parent().find('.comments-container');\r
-        \r
-        var $form = $container.find('form');\r
-\r
-        if ($form.length) {\r
-            var $textarea = $container.find('textarea');\r
-            var textarea = $textarea.get(0);\r
-            var $button = $container.find('.comment-submit');\r
-            var $cancel = $container.find('.comment-cancel');\r
-            var $chars_left_message = $container.find('.comments-chars-left-msg');\r
-            var $chars_togo_message = $container.find('.comments-chars-togo-msg');\r
-            var $chars_counter = $container.find('.comments-char-left-count');\r
-\r
-            var $add_comment_link = $comment_tools.find('.add-comment-link');\r
-\r
-            var chars_limits = $chars_counter.html().split('|');\r
-\r
-            var min_length = parseInt(chars_limits[0]);\r
-            var max_length = parseInt(chars_limits[1]);\r
-\r
-            var warn_length = max_length - 30;\r
-            var current_length = 0;\r
-            var comment_in_form = false;\r
-            var interval = null;\r
-\r
-            var hcheck = !($.browser.msie || $.browser.opera);\r
-\r
-            $textarea.css("padding-top", 0).css("padding-bottom", 0).css("resize", "none");\r
-            textarea.style.overflow = 'hidden';\r
-\r
-\r
-            function cleanup_form() {\r
-                $textarea.val('');\r
-                $textarea.css('height', 80);\r
-                $chars_counter.html(max_length);\r
-                $chars_left_message.removeClass('warn');\r
-                comment_in_form = false;\r
-                current_length = 0;\r
-\r
-                $chars_left_message.hide();\r
-                $chars_togo_message.show();\r
-\r
-                $chars_counter.removeClass('warn');\r
-                $chars_counter.html(min_length);\r
-                $button.attr("disabled","disabled");\r
-\r
-                interval = null;\r
-            }\r
-\r
-            cleanup_form();\r
-\r
-            function process_form_changes() {\r
-                var length = $textarea.val().replace(/[ ]{2,}/g," ").length;\r
-\r
-                if (current_length == length)\r
-                    return;\r
-\r
-                if (length < warn_length && current_length >= warn_length) {\r
-                    $chars_counter.removeClass('warn');\r
-                } else if (current_length < warn_length && length >= warn_length){\r
-                    $chars_counter.addClass('warn');\r
-                }\r
-\r
-                if (length < min_length) {\r
-                    $chars_left_message.hide();\r
-                    $chars_togo_message.show();\r
-                    $chars_counter.html(min_length - length);\r
-                } else {\r
-                    length = $textarea.val().length;\r
-                    $chars_togo_message.hide();\r
-                    $chars_left_message.show();\r
-                    $chars_counter.html(max_length - length);\r
-                }\r
-\r
-                if (length > max_length || length < min_length) {\r
-                    $button.attr("disabled","disabled");\r
-                } else {\r
-                    $button.removeAttr("disabled");\r
-                }\r
-\r
-                var current_height = textarea.style.height;\r
-                if (hcheck)\r
-                    textarea.style.height = "0px";\r
-\r
-                var h = Math.max(80, textarea.scrollHeight);\r
-                textarea.style.height = current_height;\r
-                $textarea.animate({height: h + 'px'}, 50);\r
-\r
-                current_length = length;\r
-            }\r
-\r
-            function show_comment_form() {\r
-                $container.slideDown('slow');\r
-                $add_comment_link.fadeOut('slow');\r
-                $textarea.focus();\r
-                interval = window.setInterval(function() {\r
-                    process_form_changes();\r
-                }, 200);\r
-            }\r
-\r
-            function hide_comment_form() {\r
-                if (interval != null) {\r
-                    window.clearInterval(interval);\r
-                    interval = null;\r
-                }\r
-                $container.slideUp('slow');\r
-                $add_comment_link.fadeIn('slow');\r
-            }\r
-\r
-            $add_comment_link.click(function(){\r
-                cleanup_form();\r
-                show_comment_form();\r
-                return false;\r
-            });\r
-\r
-            $('#' + $comments_container.attr('id') + ' .comment-edit').live('click', function() {\r
-                var $link = $(this);\r
-                var comment_id = /comment-(\d+)-edit/.exec($link.attr('id'))[1];\r
-                var $comment = $('#comment-' + comment_id);\r
-\r
-                comment_in_form = comment_id;\r
-\r
-                $.get($link.attr('href'), function(data) {\r
-                    $textarea.val(data);\r
-                });\r
-\r
-                $comment.slideUp('slow');\r
-                show_comment_form();\r
-                return false;\r
-            });\r
-\r
-            $button.click(function(evt) {\r
-                if (running) return false;\r
-\r
-                var post_data = {\r
-                    comment: $textarea.val()\r
-                }\r
-\r
-                if (comment_in_form) {\r
-                    post_data['id'] = comment_in_form;\r
-                }\r
-\r
-                start_command();\r
-                $.post($form.attr('action'), post_data, function(data) {\r
-                    process_ajax_response(data, evt, function(error) {\r
-                        if (!error) {\r
-                            cleanup_form();\r
-                            hide_comment_form();\r
-                        }\r
-                    });\r
-\r
-                }, "json");\r
-\r
-                return false;\r
-            });\r
-\r
-            // Submit comment with CTRL + Enter\r
-            $textarea.keydown(function(e) {\r
-                if (e.ctrlKey && e.keyCode == 13 && !$button.attr('disabled')) {\r
-                    // console.log('submit');\r
-                    $(this).parent().find('input.comment-submit').click();\r
-                }\r
-            });\r
-\r
-            $cancel.click(function(event) {\r
-                if (confirm("You will lose all of your changes in this comment.  Do you still wish to proceed?")){\r
-                    if (comment_in_form) {\r
-                        $comment = $('#comment-' + comment_in_form).slideDown('slow');\r
-                    }\r
-                    hide_comment_form();\r
-                    cleanup_form();\r
-                }\r
-                return false;\r
-            });\r
-        }\r
-\r
-        $comment_tools.find('.show-all-comments-link').click(function() {\r
-            $comments_container.find('.not_top_scorer').slideDown('slow');\r
-            $(this).fadeOut('slow');\r
-            $comment_tools.find('.comments-showing').fadeOut('slow');\r
-            return false;\r
-        });\r
-    });\r
-\r
-    if ($('#editor').length) {\r
-        var $editor = $('#editor');\r
-        var $previewer = $('#previewer');\r
-        var $container = $('#editor-metrics');\r
-\r
-        var initial_whitespace_rExp = /^[^A-Za-zА-Яа-я0-9]+/gi;\r
-        var non_alphanumerics_rExp = rExp = /[^A-Za-zА-Яа-я0-9]+/gi;\r
-        var editor_interval = null;\r
-\r
-        $editor.focus(function() {\r
-            if (editor_interval == null) {\r
-                editor_interval = window.setInterval(function() {\r
-                    recalc_metrics();\r
-                }, 200);\r
-            }\r
-        });\r
-\r
-        function recalc_metrics() {\r
-            var text = $previewer.text();\r
-\r
-            var char_count = text.length;\r
-            var fullStr = text + " ";\r
-            var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");\r
-            var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");\r
-            var splitString = cleanedStr.split(" ");\r
-            var word_count = splitString.length - 1;\r
-\r
-            var metrics = char_count + " " + (char_count == 1 ? messages.character : messages.characters);\r
-            metrics += " / " + word_count + " " + (word_count == 1 ? messages.word : messages.words);\r
-            $container.html(metrics);\r
-        }\r
-    }\r
-});\r
-\r
-//var scriptUrl, interestingTags, ignoredTags, tags, $;\r
-function pickedTags(){\r
-\r
-    var sendAjax = function(tagname, reason, action, callback){\r
-        var url = scriptUrl;\r
-        if (action == 'add'){\r
-            url += $.i18n._('mark-tag/');\r
-            if (reason == 'good'){\r
-                url += $.i18n._('interesting/');\r
-            }\r
-            else {\r
-                url += $.i18n._('ignored/');\r
-            }\r
-        }\r
-        else {\r
-            url += $.i18n._('unmark-tag/');\r
-        }\r
-        url = url + tagname + '/';\r
-\r
-        var call_settings = {\r
-            type:'POST',\r
-            url:url,\r
-            data: ''\r
-        };\r
-        if (callback !== false){\r
-            call_settings.success = callback;\r
-        }\r
-        $.ajax(call_settings);\r
-    };\r
-\r
-\r
-    var unpickTag = function(from_target ,tagname, reason, send_ajax){\r
-        //send ajax request to delete tag\r
-        var deleteTagLocally = function(){\r
-            from_target[tagname].remove();\r
-            delete from_target[tagname];\r
-            $(".tags.interesting").trigger('contentchanged');\r
-        };\r
-\r
-        if (send_ajax){\r
-            sendAjax(tagname,reason,'remove',deleteTagLocally);\r
-        }\r
-        else {\r
-            deleteTagLocally();\r
-        }\r
-    };\r
-\r
-    var setupTagDeleteEvents = function(obj,tag_store,tagname,reason,send_ajax){\r
-        obj.unbind('mouseover').bind('mouseover', function(){\r
-            $(this).attr('src', mediaUrl('media/images/close-small-hover.png'));\r
-        });\r
-        obj.unbind('mouseout').bind('mouseout', function(){\r
-            $(this).attr('src', mediaUrl('media/images/close-small-dark.png'));\r
-        });\r
-        obj.click( function(){\r
-            unpickTag(tag_store,tagname,reason,send_ajax);\r
-        });\r
-    };\r
-\r
-    var handlePickedTag = function(obj,reason){\r
-        var tagname = $.trim($(obj).prev().attr('value'));\r
-        var to_target = interestingTags;\r
-        var from_target = ignoredTags;\r
-        var to_tag_container;\r
-        if (reason == 'bad'){\r
-            to_target = ignoredTags;\r
-            from_target = interestingTags;\r
-            to_tag_container = $('div .tags.ignored');\r
-        }\r
-        else if (reason != 'good'){\r
-            return;\r
-        }\r
-        else {\r
-            to_tag_container = $('div .tags.interesting');\r
-        }\r
-\r
-        if (tagname in from_target){\r
-            unpickTag(from_target,tagname,reason,false);\r
-        }\r
-\r
-        if (!(tagname in to_target)){\r
-            //send ajax request to pick this tag\r
-\r
-            sendAjax(tagname,reason,'add',function(){\r
-                var new_tag = $('<span></span>');\r
-                new_tag.addClass('deletable-tag');\r
-                var tag_link = $('<a></a>');\r
-                tag_link.attr('rel','tag');\r
-                tag_link.attr('href', scriptUrl + $.i18n._('tags/') + tagname + '/');\r
-                tag_link.html(tagname);\r
-                var del_link = $('<img />');\r
-                del_link.addClass('delete-icon');\r
-                del_link.attr('src', mediaUrl('media/images/close-small-dark.png'));\r
-\r
-                setupTagDeleteEvents(del_link, to_target, tagname, reason, true);\r
-\r
-                new_tag.append(tag_link);\r
-                new_tag.append(del_link);\r
-                to_tag_container.append(new_tag);\r
-\r
-                to_target[tagname] = new_tag;\r
-\r
-                to_tag_container.trigger('contentchanged');\r
-            });\r
-        }\r
-    };\r
-\r
-    var collectPickedTags = function(){\r
-        var good_prefix = 'interesting-tag-';\r
-        var bad_prefix = 'ignored-tag-';\r
-        var good_re = RegExp('^' + good_prefix);\r
-        var bad_re = RegExp('^' + bad_prefix);\r
-        interestingTags = {};\r
-        ignoredTags = {};\r
-        $('.deletable-tag').each(\r
-            function(i,item){\r
-                var item_id = $(item).attr('id');\r
-                var tag_name, tag_store;\r
-                if (good_re.test(item_id)){\r
-                    tag_name = item_id.replace(good_prefix,'');\r
-                    tag_store = interestingTags;\r
-                    reason = 'good';\r
-                }\r
-                else if (bad_re.test(item_id)){\r
-                    tag_name = item_id.replace(bad_prefix,'');\r
-                    tag_store = ignoredTags;\r
-                    reason = 'bad';\r
-                }\r
-                else {\r
-                    return;\r
-                }\r
-                tag_store[tag_name] = $(item);\r
-                setupTagDeleteEvents($(item).find('img'),tag_store,tag_name,reason,true);\r
-            }\r
-        );\r
-    };\r
-\r
-    var setupHideIgnoredQuestionsControl = function(){\r
-        $('#hideIgnoredTagsCb').unbind('click').click(function(){\r
-            $.ajax({\r
-                        type: 'POST',\r
-                        dataType: 'json',\r
-                        cache: false,\r
-                        url: scriptUrl + $.i18n._('command/'),\r
-                        data: {command:'toggle-ignored-questions'}\r
-                    });\r
-        });\r
-    };\r
-    return {\r
-        init: function(){\r
-            collectPickedTags();\r
-            setupHideIgnoredQuestionsControl();\r
-            $("#interestingTagInput, #ignoredTagInput").autocomplete(messages.matching_tags_url, {\r
-                minChars: 1,\r
-                matchContains: true,\r
-                max: 20,\r
-                /*multiple: false, - the favorite tags and ignore tags don't let you do multiple tags\r
-                multipleSeparator: " "*/\r
-\r
-                formatItem: function(row, i, max, value) {\r
-                    return row[1] + " (" + row[2] + ")";\r
-                },\r
-\r
-                formatResult: function(row, i, max, value){\r
-                    return row[1];\r
-                }\r
-\r
-            });\r
-            $("#interestingTagAdd").click(function(){handlePickedTag(this,'good');});\r
-            $("#ignoredTagAdd").click(function(){handlePickedTag(this,'bad');});\r
-        }\r
-    };\r
-}\r
-\r
-Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};\r
-\r
-var mediaUrl = function(resource){\r
-    return scriptUrl + 'm/' + osqaSkin + '/' + resource;\r
-};\r
-\r
-/*\r
- * jQuery i18n plugin\r
- * @requires jQuery v1.1 or later\r
- *\r
- * Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/\r
- * Dual licensed under the MIT and GPL licenses:\r
- *   http://www.opensource.org/licenses/mit-license.php\r
- *   http://www.gnu.org/licenses/gpl.html\r
- *\r
- * Based on 'javascript i18n that almost doesn't suck' by markos\r
- * http://markos.gaivo.net/blog/?p=100\r
- *\r
- * Revision: $Id$\r
- * Version: 1.0.0  Feb-10-2008\r
- */\r
- (function($) {\r
-/**\r
- * i18n provides a mechanism for translating strings using a jscript dictionary.\r
- *\r
- */\r
-\r
-\r
-/*\r
- * i18n property list\r
- */\r
-$.i18n = {\r
-\r
-/**\r
- * setDictionary()\r
- * Initialise the dictionary and translate nodes\r
- *\r
- * @param property_list i18n_dict : The dictionary to use for translation\r
- */\r
-       setDictionary: function(i18n_dict) {\r
-               i18n_dict = i18n_dict;\r
-       },\r
-\r
-/**\r
- * _()\r
- * The actual translation function. Looks the given string up in the\r
- * dictionary and returns the translation if one exists. If a translation\r
- * is not found, returns the original word\r
- *\r
- * @param string str : The string to translate\r
- * @param property_list params : params for using printf() on the string\r
- * @return string : Translated word\r
- *\r
- */\r
-       _: function (str, params) {\r
-               var transl = str;\r
-               if (i18n_dict&& i18n_dict[str]) {\r
-                       transl = i18n_dict[str];\r
-               }\r
-               return this.printf(transl, params);\r
-       },\r
-\r
-/**\r
- * toEntity()\r
- * Change non-ASCII characters to entity representation\r
- *\r
- * @param string str : The string to transform\r
- * @return string result : Original string with non-ASCII content converted to entities\r
- *\r
- */\r
-       toEntity: function (str) {\r
-               var result = '';\r
-               for (var i=0;i<str.length; i++) {\r
-                       if (str.charCodeAt(i) > 128)\r
-                               result += "&#"+str.charCodeAt(i)+";";\r
-                       else\r
-                               result += str.charAt(i);\r
-               }\r
-               return result;\r
-       },\r
-\r
-/**\r
- * stripStr()\r
- *\r
- * @param string str : The string to strip\r
- * @return string result : Stripped string\r
- *\r
- */\r
-       stripStr: function(str) {\r
-               return str.replace(/^\s*/, "").replace(/\s*$/, "");\r
-       },\r
-\r
-/**\r
- * stripStrML()\r
- *\r
- * @param string str : The multi-line string to strip\r
- * @return string result : Stripped string\r
- *\r
- */\r
-       stripStrML: function(str) {\r
-               // Split because m flag doesn't exist before JS1.5 and we need to\r
-               // strip newlines anyway\r
-               var parts = str.split('\n');\r
-               for (var i=0; i<parts.length; i++)\r
-                       parts[i] = stripStr(parts[i]);\r
-\r
-               // Don't join with empty strings, because it "concats" words\r
-               // And strip again\r
-               return stripStr(parts.join(" "));\r
-       },\r
-\r
-/*\r
- * printf()\r
- * C-printf like function, which substitutes %s with parameters\r
- * given in list. %%s is used to escape %s.\r
- *\r
- * Doesn't work in IE5.0 (splice)\r
- *\r
- * @param string S : string to perform printf on.\r
- * @param string L : Array of arguments for printf()\r
- */\r
-       printf: function(S, L) {\r
-               if (!L) return S;\r
-\r
-               var nS = "";\r
-               var tS = S.split("%s");\r
-\r
-               for(var i=0; i<L.length; i++) {\r
-                       if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)\r
-                               tS[i] += "s"+tS.splice(i+1,1)[0];\r
-                       nS += tS[i] + L[i];\r
-               }\r
-               return nS + tS[tS.length-1];\r
-       }\r
-\r
-};\r
-\r
-\r
-})(jQuery);\r
-\r
-\r
-//var i18nLang;\r
-var i18nZh = {\r
-       'insufficient privilege':'??????????',\r
-       'cannot pick own answer as best':'??????????????',\r
-       'anonymous users cannot select favorite questions':'?????????????',\r
-       'please login':'??????',\r
-       'anonymous users cannot vote':'????????',\r
-       '>15 points requried to upvote':'??+15?????????',\r
-       '>100 points required to downvote':'??+100?????????',\r
-       'please see': '??',\r
-       'cannot vote for own posts':'??????????',\r
-       'daily vote cap exhausted':'????????????????',\r
-       'cannot revoke old vote':'??????????????',\r
-       'please confirm offensive':"??????????????????????",\r
-       'anonymous users cannot flag offensive posts':'???????????',\r
-       'cannot flag message as offensive twice':'???????',\r
-       'flag offensive cap exhausted':'?????????????5?\91??\92???',\r
-       'need >15 points to report spam':"??+15??????\91???\92?",\r
-       'confirm delete':"?????/????????",\r
-       'anonymous users cannot delete/undelete':"???????????????",\r
-       'post recovered':"?????????????",\r
-       'post deleted':"????????????",\r
-       'add comment':'????',\r
-       'community karma points':'????',\r
-       'to comment, need':'????',\r
-       'delete this comment':'?????',\r
-       'hide comments':"????",\r
-       'add a comment':"????",\r
-       'comments':"??",\r
-       'confirm delete comment':"?????????",\r
-       'characters':'??',\r
-       'can write':'???',\r
-       'click to close':'???????',\r
-       'loading...':'???...',\r
-       'tags cannot be empty':'???????',\r
-       'tablimits info':"??5????????????20????",\r
-       'content cannot be empty':'???????',\r
-       'content minchars': '????? {0} ???',\r
-       'please enter title':'??????',\r
-       'title minchars':"????? {0} ???",\r
-       'delete':'??',\r
-       'undelete':     '??',\r
-       'bold':'??',\r
-       'italic':'??',\r
-       'link':'???',\r
-       'quote':'??',\r
-       'preformatted text':'??',\r
-       'image':'??',\r
-       'numbered list':'??????',\r
-       'bulleted list':'??????',\r
-       'heading':'??',\r
-       'horizontal bar':'???',\r
-       'undo':'??',\r
-       'redo':'??',\r
-       'enter image url':'<b>??????</b></p><p>???<br />http://www.example.com/image.jpg   \"????\"',\r
-       'enter url':'<b>??Web??</b></p><p>???<br />http://www.cnprog.com/   \"????\"</p>"',\r
-       'upload image':'?????????'\r
-};\r
-\r
-var i18nEn = {\r
-       'need >15 points to report spam':'need >15 points to report spam ',\r
-    '>15 points requried to upvote':'>15 points required to upvote ',\r
-       'tags cannot be empty':'please enter at least one tag',\r
-       'anonymous users cannot vote':'sorry, anonymous users cannot vote ',\r
-       'anonymous users cannot select favorite questions':'sorry, anonymous users cannot select favorite questions ',\r
-       'to comment, need': '(to comment other people\'s posts, karma ',\r
-       'please see':'please see ',\r
-       'community karma points':' or more is necessary) - ',\r
-       'upload image':'Upload image:',\r
-       'enter image url':'enter URL of the image, e.g. http://www.example.com/image.jpg \"image title\"',\r
-       'enter url':'enter Web address, e.g. http://www.example.com \"page title\"',\r
-       'daily vote cap exhausted':'sorry, you\'ve used up todays vote cap',\r
-       'cannot pick own answer as best':'sorry, you cannot accept your own answer',\r
-       'cannot revoke old vote':'sorry, older votes cannot be revoked',\r
-       'please confirm offensive':'are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?',\r
-       'flag offensive cap exhausted':'sorry, you\'ve used up todays cap of flagging offensive messages ',\r
-       'confirm delete':'are you sure you want to delete this?',\r
-       'anonymous users cannot delete/undelete':'sorry, anonymous users cannot delete or undelete posts',\r
-       'post recovered':'your post is now restored!',\r
-       'post deleted':'your post has been deleted',\r
-       'confirm delete comment':'do you really want to delete this comment?',\r
-       'can write':'have ',\r
-       'tablimits info':'up to 5 tags, no more than 20 characters each',\r
-       'content minchars': 'please enter more than {0} characters',\r
-       'title minchars':"please enter at least {0} characters",\r
-       'characters':'characters left',\r
-    'cannot vote for own posts':'sorry, you cannot vote for your own posts',\r
-    'cannot flag message as offensive twice':'cannot flag message as offensive twice ',\r
-       '>100 points required to downvote':'>100 points required to downvote '\r
-};\r
-\r
-var i18nEs = {\r
-       'insufficient privilege':'privilegio insuficiente',\r
-       'cannot pick own answer as best':'no puede escoger su propia respuesta como la mejor',\r
-       'anonymous users cannot select favorite questions':'usuarios anonimos no pueden seleccionar',\r
-       'please login':'por favor inicie sesión',\r
-       'anonymous users cannot vote':'usuarios anónimos no pueden votar',\r
-       '>15 points requried to upvote': '>15 puntos requeridos para votar positivamente',\r
-       '>100 points required to downvote':'>100 puntos requeridos para votar negativamente',\r
-       'please see': 'por favor vea',\r
-       'cannot vote for own posts':'no se puede votar por sus propias publicaciones',\r
-       'daily vote cap exhausted':'cuota de votos diarios excedida',\r
-       'cannot revoke old vote':'no puede revocar un voto viejo',\r
-       'please confirm offensive':"por favor confirme ofensiva",\r
-       'anonymous users cannot flag offensive posts':'usuarios anónimos no pueden marcar publicaciones como ofensivas',\r
-       'cannot flag message as offensive twice':'no puede marcar mensaje como ofensivo dos veces',\r
-       'flag offensive cap exhausted':'cuota para marcar ofensivas ha sido excedida',\r
-       'need >15 points to report spam':"necesita >15 puntos para reportar spam",\r
-       'confirm delete':"¿Está seguro que desea borrar esto?",\r
-       'anonymous users cannot delete/undelete':"usuarios anónimos no pueden borrar o recuperar publicaciones",\r
-       'post recovered':"publicación recuperada",\r
-       'post deleted':"publicación borrada?",\r
-       'add comment':'agregar comentario',\r
-       'community karma points':'reputación comunitaria',\r
-       'to comment, need':'para comentar, necesita reputación',\r
-       'delete this comment':'borrar este comentario',\r
-       'hide comments':"ocultar comentarios",\r
-       'add a comment':"agregar comentarios",\r
-       'comments':"comentarios",\r
-       'confirm delete comment':"¿Realmente desea borrar este comentario?",\r
-       'characters':'caracteres faltantes',\r
-       'can write':'tiene ',\r
-       'click to close':'haga click para cerrar',\r
-       'loading...':'cargando...',\r
-       'tags cannot be empty':'las etiquetas no pueden estar vacías',\r
-       'tablimits info':"hasta 5 etiquetas de no mas de 20 caracteres cada una",\r
-       'content cannot be empty':'el contenido no puede estar vacío',\r
-       'content minchars': 'por favor introduzca mas de {0} caracteres',\r
-       'please enter title':'por favor ingrese un título',\r
-       'title minchars':"por favor introduzca al menos {0} caracteres",\r
-       'delete':'borrar',\r
-       'undelete':     'recuperar',\r
-       'bold': 'negrita',\r
-       'italic':'cursiva',\r
-       'link':'enlace',\r
-       'quote':'citar',\r
-       'preformatted text':'texto preformateado',\r
-       'image':'imagen',\r
-       'numbered list':'lista numerada',\r
-       'bulleted list':'lista no numerada',\r
-       'heading':'??',\r
-       'horizontal bar':'barra horizontal',\r
-       'undo':'deshacer',\r
-       'redo':'rehacer',\r
-       'enter image url':'introduzca la URL de la imagen, por ejemplo?<br />http://www.example.com/image.jpg   \"titulo de imagen\"',\r
-       'enter url':'introduzca direcciones web, ejemplo?<br />http://www.cnprog.com/   \"titulo del enlace\"</p>"',\r
-       'upload image':'cargar imagen?',\r
-       'questions/' : 'preguntas/',\r
-       'vote/' : 'votar/'\r
-};\r
-\r
-var i18n = {\r
-       'en':i18nEn,\r
-       'zh_CN':i18nZh,\r
-       'es':i18nEs\r
-};\r
-\r
-var i18n_dict = i18n[i18nLang];\r
-\r
-/*\r
-       jQuery TextAreaResizer plugin\r
-       Created on 17th January 2008 by Ryan O'Dell\r
-       Version 1.0.4\r
-*/(function($){var textarea,staticOffset;var iLastMousePos=0;var iMin=32;var grip;$.fn.TextAreaResizer=function(){return this.each(function(){textarea=$(this).addClass('processed'),staticOffset=null;$(this).wrap('<div class="resizable-textarea"><span></span></div>').parent().append($('<div class="grippie"></div>').bind("mousedown",{el:this},startDrag));var grippie=$('div.grippie',$(this).parent())[0];grippie.style.marginRight=(grippie.offsetWidth-$(this)[0].offsetWidth)+'px'})};function startDrag(e){textarea=$(e.data.el);textarea.blur();iLastMousePos=mousePosition(e).y;staticOffset=textarea.height()-iLastMousePos;textarea.css('opacity',0.25);$(document).mousemove(performDrag).mouseup(endDrag);return false}function performDrag(e){var iThisMousePos=mousePosition(e).y;var iMousePos=staticOffset+iThisMousePos;if(iLastMousePos>=(iThisMousePos)){iMousePos-=5}iLastMousePos=iThisMousePos;iMousePos=Math.max(iMin,iMousePos);textarea.height(iMousePos+'px');if(iMousePos<iMin){endDrag(e)}return false}function endDrag(e){$(document).unbind('mousemove',performDrag).unbind('mouseup',endDrag);textarea.css('opacity',1);textarea.focus();textarea=null;staticOffset=null;iLastMousePos=0}function mousePosition(e){return{x:e.clientX+document.documentElement.scrollLeft,y:e.clientY+document.documentElement.scrollTop}}})(jQuery);\r
-/*\r
- * Autocomplete - jQuery plugin 1.0.3\r
- *\r
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer\r
- *\r
- * Dual licensed under the MIT and GPL licenses:\r
- *   http://www.opensource.org/licenses/mit-license.php\r
- *   http://www.gnu.org/licenses/gpl.html\r
- *\r
- */\r
-(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);\r
-\r
-var notify = function() {\r
-    var visible = false;\r
-    return {\r
-        show: function(html) {\r
-            if (html) {\r
-                $("body").css("margin-top", "2.2em");\r
-                $(".notify span").html(html);\r
-            }\r
-            $(".notify").fadeIn("slow");\r
-            visible = true;\r
-        },\r
-        close: function(doPostback) {\r
-            $(".notify").fadeOut("fast");\r
-            $("body").css("margin-top", "0");\r
-            visible = false;\r
-        },\r
-        isVisible: function() { return visible; }\r
-    };\r
-} ();\r
-\r
-/*\r
- * jQuery outside events - v1.1 - 3/16/2010\r
- * http://benalman.com/projects/jquery-outside-events-plugin/\r
- *\r
- * Copyright (c) 2010 "Cowboy" Ben Alman\r
- * Dual licensed under the MIT and GPL licenses.\r
- * http://benalman.com/about/license/\r
- */\r
-(function($,c,b){$.map("click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup".split(" "),function(d){a(d)});a("focusin","focus"+b);a("focusout","blur"+b);$.addOutsideEvent=a;function a(g,e){e=e||g+b;var d=$(),h=g+"."+e+"-special-event";$.event.special[e]={setup:function(){d=d.add(this);if(d.length===1){$(c).bind(h,f)}},teardown:function(){d=d.not(this);if(d.length===0){$(c).unbind(h)}},add:function(i){var j=i.handler;i.handler=function(l,k){l.target=k;j.apply(this,arguments)}}};function f(i){$(d).each(function(){var j=$(this);if(this!==i.target&&!j.has(i.target).length){j.triggerHandler(e,[i.target])}})}}})(jQuery,document,"outside");\r
-\r
-$(document).ready( function(){\r
-    pickedTags().init();\r
-\r
-    $('input#bnewaccount').click(function() {\r
-        $('#bnewaccount').disabled=true;\r
-    });\r
-});\r
-\r
-function yourWorkWillBeLost(e) {\r
-    if(browserTester('chrome')) {\r
-        return "Are you sure you want to leave?  Your work will be lost.";\r
-    } else if(browserTester('safari')) {\r
-        return "Are you sure you want to leave?  Your work will be lost.";\r
-    } else {\r
-        if(!e) e = window.event;\r
-        e.cancelBubble = true;\r
-        e.returnValue = 'If you leave, your work will be lost.';\r
-\r
-        if (e.stopPropagation) {\r
-            e.stopPropagation();\r
-            e.preventDefault();\r
-        }\r
-        return e;\r
-    }\r
-}\r
-\r
-function browserTester(browserString) {\r
-    return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;\r
-}\r
-\r
-// Add missing IE functionality\r
-if (!window.addEventListener) {\r
-    if (window.attachEvent) {\r
-        window.addEventListener = function (type, listener, useCapture) {\r
-            window.attachEvent('on' + type, listener);\r
-        };\r
-        window.removeEventListener = function (type, listener, useCapture) {\r
-            window.detachEvent('on' + type, listener);\r
-        };\r
-    } else {\r
-        window.addEventListener = function (type, listener, useCapture) {\r
-            window['on' + type] = listener;\r
-        };\r
-        window.removeEventListener = function (type, listener, useCapture) {\r
-            window['on' + type] = null;\r
-        };\r
-    }\r
-}\r
+/**
+ * We do not want the CSRF protection enabled for the AJAX post requests, it causes only trouble.
+ * Get the csrftoken cookie and pass it to the X-CSRFToken HTTP request property.
+ */
+
+$('html').ajaxSend(function(event, xhr, settings) {
+    function getCookie(name) {
+        var cookieValue = null;
+        if (document.cookie && document.cookie != '') {
+            var cookies = document.cookie.split(';');
+            for (var i = 0; i < cookies.length; i++) {
+                var cookie = jQuery.trim(cookies[i]);
+                // Does this cookie string begin with the name we want?
+                if (cookie.substring(0, name.length + 1) == (name + '=')) {
+                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+                    break;
+                }
+            }
+        }
+        return cookieValue;
+    }
+    try {
+        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
+            // Only send the token to relative URLs i.e. locally.
+            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
+        }
+    } catch (e) {}
+});
+
+var response_commands = {
+    refresh_page: function() {
+        window.location.reload(true)
+    },
+    
+    update_post_score: function(id, inc) {
+        var $score_board = $('#post-' + id + '-score');
+        var current = parseInt($score_board.html())
+        if (isNaN(current)){
+            current = 0;
+        }
+        $score_board.html(current + inc)
+    },
+
+    update_user_post_vote: function(id, vote_type) {
+        var $upvote_button = $('#post-' + id + '-upvote');
+        var $downvote_button = $('#post-' + id + '-downvote');
+
+        $upvote_button.removeClass('on');
+        $downvote_button.removeClass('on');
+
+        if (vote_type == 'up') {
+            $upvote_button.addClass('on');
+        } else if (vote_type == 'down') {
+            $downvote_button.addClass('on');
+        }
+    },
+
+    update_favorite_count: function(inc) {
+        var $favorite_count = $('#favorite-count');
+        var count = parseInt($favorite_count.html());
+
+        if (isNaN(count))
+            count = 0;
+
+        count += inc;
+
+        if (count == 0)
+            count = '';
+
+        $favorite_count.html(count);
+    },
+
+    update_favorite_mark: function(type) {
+        if (type == 'on') {
+            $('#favorite-mark').addClass('on');
+        } else {
+            $('#favorite-mark').removeClass('on');
+        }
+    },
+
+    mark_accepted: function(id) {        
+        var $answer = $('#answer-container-' + id);
+        $answer.addClass('accepted-answer');
+        $answer.find('.accept-answer').addClass('on');
+        $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:on'));
+    },
+
+    unmark_accepted: function(id) {
+        var $answer = $('#answer-container-' + id);
+        $answer.removeClass('accepted-answer');
+        $answer.find('.accept-answer').removeClass('on');
+        $answer.find('.accept-answer').attr('title', $answer.find('.accept-answer').attr('bn:off'));
+    },
+
+    remove_comment: function(id) {
+        var $comment = $('#comment-' + id);
+        $comment.css('background', 'red')
+        $comment.fadeOut('slow', function() {
+            $comment.remove();    
+        });
+    },
+
+    award_points: function(id) {
+        alert('ok');
+    },
+
+    insert_comment: function(post_id, comment_id, comment, username, profile_url, delete_url, edit_url, convert_url, can_convert, show_latest_comments_first) {
+        var $container = $('#comments-container-' + post_id);
+        var skeleton = $('#new-comment-skeleton-' + post_id).html().toString();
+
+        skeleton = skeleton.replace(new RegExp('%ID%', 'g'), comment_id)
+                .replace(new RegExp('%COMMENT%', 'g'), comment)
+                .replace(new RegExp('%USERNAME%', 'g'), username)
+                .replace(new RegExp('%PROFILE_URL%', 'g'), profile_url)
+                .replace(new RegExp('%DELETE_URL%', 'g'), delete_url)
+                .replace(new RegExp('%EDIT_URL%', 'g'), edit_url)
+                .replace(new RegExp('%CONVERT_URL%', 'g'), convert_url);
+        if (show_latest_comments_first) {
+            $container.prepend(skeleton);
+        } else {
+            $container.append(skeleton);
+        }
+
+        // Show the convert comment to answer tool only if the current comment can be converted
+        if (can_convert == true) {
+            $('#comment-' + comment_id + '-convert').show();
+        }
+
+        $('#comment-' + comment_id).slideDown('slow');
+    },
+
+    update_comment: function(comment_id, comment_text) {
+        var $comment = $('#comment-' + comment_id);
+        $comment.find('.comment-text').html(comment_text);
+
+        $comment.slideDown('slow');
+    },
+
+    mark_deleted: function(post_type, post_id) {
+        if (post_type == 'question') {
+            var $container = $('#question-table');
+            $container.addClass('deleted');
+        } else {
+            var $el = $('#' + post_type + '-container-' + post_id);
+            $el.addClass('deleted');
+        }
+    },
+
+    unmark_deleted: function(post_type, post_id) {
+        if (post_type == 'answer') {
+            var $answer = $('#answer-container-' + post_id);
+            $answer.removeClass('deleted');
+        } else {
+            var $container = $('#question-table');
+            $container.removeClass('deleted');
+        }
+    },
+
+    set_subscription_button: function(text) {
+        $('.subscription_switch').html(text);
+    },
+
+    set_subscription_status: function(text) {
+        $('.subscription-status').html(text);
+    },
+
+    copy_url: function(url) {
+    }
+}
+
+function show_dialog (extern) {
+    var default_close_function = function($diag) {
+        $diag.fadeOut('fast', function() {
+            $diag.remove();
+        });
+    };
+
+    var options = {
+        extra_class: '',
+        pos: {
+            x: ($(window).width() / 2) + $(window).scrollLeft(),
+            y: ($(window).height() / 2) + $(window).scrollTop()
+        },
+        dim: false, 
+        yes_text: messages.ok,
+        yes_callback: default_close_function,
+        no_text: messages.cancel,
+        show_no: false,
+        close_on_clickoutside: false,
+        copy: false
+    }
+
+    $.extend(options, extern);
+
+    var copy_id = '';
+    if (options.copy) {
+        copy_id = ' id="copy_clip_button"'
+    }
+
+    if (options.event != undefined && options.event.pageX != undefined && options.event.pageY != undefined) {
+        options.pos = {x: options.event.pageX, y: options.event.pageY};
+    } else if (options.event.currentTarget != undefined) {
+        var el = jQuery("#" + options.event.currentTarget.id);
+        var position = el.offset();
+        options.pos = {
+            x: position.left,
+            y: position.top
+        }
+    }
+
+    var html = '<div class="dialog ' + options.extra_class + '" style="display: none; z-index: 999;">'
+             + '<div class="dialog-content">' + options.html + '</div><div class="dialog-buttons">';
+
+    if (options.show_no) {
+        html += '<button class="dialog-no">' + options.no_text + '</button>';
+    }
+
+    html += '<button class="dialog-yes"' + copy_id + '>' + options.yes_text + '</button>' + '</div></div>';
+
+    var $dialog = $(html);
+
+    $('body').append($dialog);
+    var message = $('.dialog-content')[0];
+    message.style.visibility = "hidden";
+
+    if (options.dim === false) {
+        $dialog.css({
+            visibility: 'hidden',
+            display: 'block'
+        });
+
+        options.dim = {w: $dialog.width(), h: $dialog.height()};
+
+        $dialog.css({
+            width: 1,
+            height: 1,
+            visibility: 'visible'
+        });
+    }
+
+    $dialog.css({
+        top: options.pos.y,
+        left: options.pos.x
+    });
+    
+    top_position_change = (options.dim.h / 2)
+    left_position_change = (options.dim.w / 2)
+    
+    new_top_position = options.pos.y - top_position_change
+    new_left_position = options.pos.x - left_position_change
+    
+    if (new_left_position < 0) {
+        left_position_change = 0
+    }
+    if (($(window).scrollTop() - new_top_position) > 0) {
+        top_position_change = 0
+    }
+    if ((options.event.pageY + options.dim.h) > ($(window).height() + $(window).scrollTop())) {
+        top_position_change = options.dim.h
+    }
+    if ((options.event.pageX + options.dim.w) > ($(window).width() + $(window).scrollLeft())) {
+        left_position_change = options.dim.w
+    }
+    
+    $dialog.animate({
+        top: "-=" + top_position_change,
+        left: "-=" + left_position_change,
+        width: options.dim.w,
+        height: options.dim.h
+    }, 200, function() {
+        message.style.visibility = "visible";
+    });
+
+    $dialog.find('.dialog-yes').click(function() {
+        options.yes_callback($dialog);
+    });
+
+    if (options.hasOwnProperty("no_callback")) {
+        $dialog.find('.dialog-no:first-child').click(function() {
+            options.no_callback($dialog);
+        });
+    } else {
+        $dialog.find('.dialog-no:first-child').click(function() {
+            default_close_function($dialog);
+        });
+    }
+
+    if (options.close_on_clickoutside) {
+        $dialog.one('clickoutside', function() {
+            default_close_function($dialog);
+        });
+    }
+
+    return $dialog;
+}
+
+function show_message(evt, msg, callback) {
+    var $dialog = show_dialog({
+        html: msg,
+        extra_class: 'warning',
+        event: evt,
+        yes_callback: function() {
+            $dialog.fadeOut('fast', function() {
+                $dialog.remove();
+            });
+            if (callback) {
+                callback();
+            }
+        },
+        close_on_clickoutside: true
+    });
+}
+
+function load_prompt(evt, el, url) {
+    $.get(url, function(data) {
+        var doptions = {
+         html: data,
+            extra_class: 'prompt',
+            yes_callback: function() {
+                var postvars = {};
+                $dialog.find('input, textarea, select').each(function() {
+                    postvars[$(this).attr('name')] = $(this).val();
+                });
+                $.post(url, postvars, function(data) {
+                    $dialog.fadeOut('fast', function() {
+                        $dialog.remove();
+                    });
+                    process_ajax_response(data, evt);
+                }, 'json');
+            },
+            show_no: true,
+            copy: false
+        }
+
+        if (el.hasClass('copy')) {
+            $.extend(doptions, { yes_text : 'Copy', copy: true});
+        }
+
+        if (!el.is('.centered')) {
+            doptions.event = evt;
+        }
+
+        var $dialog = show_dialog(doptions);
+    });
+}
+
+function process_ajax_response(data, evt, callback) {
+    if (!data.success && data['error_message'] != undefined) {
+        show_message(evt, data.error_message, function() {if (callback) callback(true);});
+        end_command(false);
+    }
+    if (typeof data['commands'] != undefined){
+        for (var command in data.commands) {
+            response_commands[command].apply(null, data.commands[command])
+
+
+        }
+
+        if (data['message'] != undefined) {
+            show_message(evt, data.message, function() {if (callback) callback(false);})
+        } else {
+            if (callback) callback(false);
+        }
+        end_command(true);
+    }
+}
+
+var running = false;
+
+function start_command() {
+    $('body').append($('<div id="command-loader"></div>'));
+    running = true;
+}
+
+function end_command(success) {
+    if (success) {
+        $('#command-loader').addClass('success');
+        $('#command-loader').fadeOut("slow", function() {
+            $('#command-loader').remove();
+            running = false;
+        });
+    } else {
+        $('#command-loader').remove();
+        running = false;
+    }
+}
+
+var comment_box_cursor_position = 0;
+function canned_comment(post_id, comment) {
+    textarea = $('#comment-' + post_id + '-form textarea')
+
+    // Get the text from the beginning to the caret
+    textarea_start = textarea.val().substr(0, comment_box_cursor_position)
+
+    // Get the text from the caret to the end
+    textarea_end = textarea.val().substr(comment_box_cursor_position, textarea.val().length)
+
+    textarea.val(textarea_start + comment + textarea_end);
+}
+
+$(function() {
+    $('textarea.commentBox').bind('keydown keyup mousedown mouseup mousemove', function(evt) {
+        comment_box_cursor_position = $(this).caret().start;
+    });
+
+    $('textarea.commentBox').blur(function() {
+        //alert(comment_box_cursor_position);
+    });
+
+    $('a.ajax-command').live('click', function(evt) {
+        if (running) return false;
+
+        var el = $(this);
+
+        var ajax_url = el.attr('href')
+        ajax_url = ajax_url + "?nocache=" + new Date().getTime()
+
+        $('.context-menu-dropdown').slideUp('fast');
+
+        if (el.is('.withprompt')) {
+            load_prompt(evt, el, ajax_url);
+        } else if(el.is('.confirm')) {
+            var doptions = {
+                html: messages.confirm,
+                extra_class: 'confirm',
+                yes_callback: function() {
+                    start_command();
+                    $.getJSON(ajax_url, function(data) {
+                        process_ajax_response(data, evt);
+                        $dialog.fadeOut('fast', function() {
+                            $dialog.remove();
+                        });
+                    });
+                },
+                yes_text: messages.yes,
+                show_no: true,
+                no_text: messages.no
+            }
+
+            if (!el.is('.centered')) {
+                doptions.event = evt;
+            }
+            var $dialog = show_dialog(doptions);
+        } else {
+            start_command();
+            $.ajax({
+                url: ajax_url,
+                type: "POST",
+                dataType: "json",
+                contentType: "application/json; charset=utf-8",
+                success: function(data) {
+                    process_ajax_response(data, evt);
+                }
+            });
+        }
+
+        return false
+    });
+
+    $('.context-menu').each(function() {
+        var $menu = $(this);
+        var $trigger = $menu.find('.context-menu-trigger');
+        var $dropdown = $menu.find('.context-menu-dropdown');
+
+        $trigger.click(function() {
+            $dropdown.slideToggle('fast', function() {
+                if ($dropdown.is(':visible')) {
+                   $dropdown.one('clickoutside', function() {
+                       if ($dropdown.is(':visible'))
+                            $dropdown.slideUp('fast');
+                    });
+                }
+            });    
+        });
+    });
+
+    $('div.comment-form-container').each(function() {
+        var $container = $(this);
+        var $comment_tools = $container.parent().find('.comment-tools');
+        var $comments_container = $container.parent().find('.comments-container');
+        
+        var $form = $container.find('form');
+
+        if ($form.length) {
+            var $textarea = $container.find('textarea');
+            var textarea = $textarea.get(0);
+            var $button = $container.find('.comment-submit');
+            var $cancel = $container.find('.comment-cancel');
+            var $chars_left_message = $container.find('.comments-chars-left-msg');
+            var $chars_togo_message = $container.find('.comments-chars-togo-msg');
+            var $chars_counter = $container.find('.comments-char-left-count');
+
+            var $add_comment_link = $comment_tools.find('.add-comment-link');
+
+            var chars_limits = $chars_counter.html().split('|');
+
+            var min_length = parseInt(chars_limits[0]);
+            var max_length = parseInt(chars_limits[1]);
+
+            var warn_length = max_length - 30;
+            var current_length = 0;
+            var comment_in_form = false;
+            var interval = null;
+
+            var hcheck = !($.browser.msie || $.browser.opera);
+
+            $textarea.css("padding-top", 0).css("padding-bottom", 0).css("resize", "none");
+            textarea.style.overflow = 'hidden';
+
+
+            function cleanup_form() {
+                $textarea.val('');
+                $textarea.css('height', 80);
+                $chars_counter.html(max_length);
+                $chars_left_message.removeClass('warn');
+                comment_in_form = false;
+                current_length = 0;
+
+                $chars_left_message.hide();
+                $chars_togo_message.show();
+
+                $chars_counter.removeClass('warn');
+                $chars_counter.html(min_length);
+                $button.attr("disabled","disabled");
+
+                interval = null;
+            }
+
+            cleanup_form();
+
+            function process_form_changes() {
+                var length = $textarea.val().replace(/[ ]{2,}/g," ").length;
+
+                if (current_length == length)
+                    return;
+
+                if (length < warn_length && current_length >= warn_length) {
+                    $chars_counter.removeClass('warn');
+                } else if (current_length < warn_length && length >= warn_length){
+                    $chars_counter.addClass('warn');
+                }
+
+                if (length < min_length) {
+                    $chars_left_message.hide();
+                    $chars_togo_message.show();
+                    $chars_counter.html(min_length - length);
+                } else {
+                    length = $textarea.val().length;
+                    $chars_togo_message.hide();
+                    $chars_left_message.show();
+                    $chars_counter.html(max_length - length);
+                }
+
+                if (length > max_length || length < min_length) {
+                    $button.attr("disabled","disabled");
+                } else {
+                    $button.removeAttr("disabled");
+                }
+
+                var current_height = textarea.style.height;
+                if (hcheck)
+                    textarea.style.height = "0px";
+
+                var h = Math.max(80, textarea.scrollHeight);
+                textarea.style.height = current_height;
+                $textarea.animate({height: h + 'px'}, 50);
+
+                current_length = length;
+            }
+
+            function show_comment_form() {
+                $container.slideDown('slow');
+                $add_comment_link.fadeOut('slow');
+                $textarea.focus();
+                interval = window.setInterval(function() {
+                    process_form_changes();
+                }, 200);
+            }
+
+            function hide_comment_form() {
+                if (interval != null) {
+                    window.clearInterval(interval);
+                    interval = null;
+                }
+                $container.slideUp('slow');
+                $add_comment_link.fadeIn('slow');
+            }
+
+            $add_comment_link.click(function(){
+                cleanup_form();
+                show_comment_form();
+                return false;
+            });
+
+            $('#' + $comments_container.attr('id') + ' .comment-edit').live('click', function() {
+                var $link = $(this);
+                var comment_id = /comment-(\d+)-edit/.exec($link.attr('id'))[1];
+                var $comment = $('#comment-' + comment_id);
+
+                comment_in_form = comment_id;
+
+                $.get($link.attr('href'), function(data) {
+                    $textarea.val(data);
+                });
+
+                $comment.slideUp('slow');
+                show_comment_form();
+                return false;
+            });
+
+            $button.click(function(evt) {
+                if (running) return false;
+
+                var post_data = {
+                    comment: $textarea.val()
+                }
+
+                if (comment_in_form) {
+                    post_data['id'] = comment_in_form;
+                }
+
+                start_command();
+                $.post($form.attr('action'), post_data, function(data) {
+                    process_ajax_response(data, evt, function(error) {
+                        if (!error) {
+                            cleanup_form();
+                            hide_comment_form();
+                        }
+                    });
+
+                }, "json");
+
+                return false;
+            });
+
+            // Submit comment with CTRL + Enter
+            $textarea.keydown(function(e) {
+                if (e.ctrlKey && e.keyCode == 13 && !$button.attr('disabled')) {
+                    // console.log('submit');
+                    $(this).parent().find('input.comment-submit').click();
+                }
+            });
+
+            $cancel.click(function(event) {
+                if (confirm("You will lose all of your changes in this comment.  Do you still wish to proceed?")){
+                    if (comment_in_form) {
+                        $comment = $('#comment-' + comment_in_form).slideDown('slow');
+                    }
+                    hide_comment_form();
+                    cleanup_form();
+                }
+                return false;
+            });
+        }
+
+        $comment_tools.find('.show-all-comments-link').click(function() {
+            $comments_container.find('.not_top_scorer').slideDown('slow');
+            $(this).fadeOut('slow');
+            $comment_tools.find('.comments-showing').fadeOut('slow');
+            return false;
+        });
+    });
+
+    if ($('#editor').length) {
+        var $editor = $('#editor');
+        var $previewer = $('#previewer');
+        var $container = $('#editor-metrics');
+
+        var initial_whitespace_rExp = /^[^A-Za-zА-Яа-я0-9]+/gi;
+        var non_alphanumerics_rExp = rExp = /[^A-Za-zА-Яа-я0-9]+/gi;
+        var editor_interval = null;
+
+        $editor.focus(function() {
+            if (editor_interval == null) {
+                editor_interval = window.setInterval(function() {
+                    recalc_metrics();
+                }, 200);
+            }
+        });
+
+        function recalc_metrics() {
+            var text = $previewer.text();
+
+            var char_count = text.length;
+            var fullStr = text + " ";
+            var left_trimmedStr = fullStr.replace(initial_whitespace_rExp, "");
+            var cleanedStr = left_trimmedStr.replace(non_alphanumerics_rExp, " ");
+            var splitString = cleanedStr.split(" ");
+            var word_count = splitString.length - 1;
+
+            var metrics = char_count + " " + (char_count == 1 ? messages.character : messages.characters);
+            metrics += " / " + word_count + " " + (word_count == 1 ? messages.word : messages.words);
+            $container.html(metrics);
+        }
+    }
+});
+
+//var scriptUrl, interestingTags, ignoredTags, tags, $;
+function pickedTags(){
+
+    var sendAjax = function(tagname, reason, action, callback){
+        var url = scriptUrl;
+        if (action == 'add'){
+            url += $.i18n._('mark-tag/');
+            if (reason == 'good'){
+                url += $.i18n._('interesting/');
+            }
+            else {
+                url += $.i18n._('ignored/');
+            }
+        }
+        else {
+            url += $.i18n._('unmark-tag/');
+        }
+        url = url + tagname + '/';
+
+        var call_settings = {
+            type:'POST',
+            url:url,
+            data: ''
+        };
+        if (callback !== false){
+            call_settings.success = callback;
+        }
+        $.ajax(call_settings);
+    };
+
+
+    var unpickTag = function(from_target ,tagname, reason, send_ajax){
+        //send ajax request to delete tag
+        var deleteTagLocally = function(){
+            from_target[tagname].remove();
+            delete from_target[tagname];
+            $(".tags.interesting").trigger('contentchanged');
+        };
+
+        if (send_ajax){
+            sendAjax(tagname,reason,'remove',deleteTagLocally);
+        }
+        else {
+            deleteTagLocally();
+        }
+    };
+
+    var setupTagDeleteEvents = function(obj,tag_store,tagname,reason,send_ajax){
+        obj.unbind('mouseover').bind('mouseover', function(){
+            $(this).attr('src', mediaUrl('media/images/close-small-hover.png'));
+        });
+        obj.unbind('mouseout').bind('mouseout', function(){
+            $(this).attr('src', mediaUrl('media/images/close-small-dark.png'));
+        });
+        obj.click( function(){
+            unpickTag(tag_store,tagname,reason,send_ajax);
+        });
+    };
+
+    var handlePickedTag = function(obj,reason){
+        var tagname = $.trim($(obj).prev().attr('value'));
+        var to_target = interestingTags;
+        var from_target = ignoredTags;
+        var to_tag_container;
+        if (reason == 'bad'){
+            to_target = ignoredTags;
+            from_target = interestingTags;
+            to_tag_container = $('div .tags.ignored');
+        }
+        else if (reason != 'good'){
+            return;
+        }
+        else {
+            to_tag_container = $('div .tags.interesting');
+        }
+
+        if (tagname in from_target){
+            unpickTag(from_target,tagname,reason,false);
+        }
+
+        if (!(tagname in to_target)){
+            //send ajax request to pick this tag
+
+            sendAjax(tagname,reason,'add',function(){
+                var new_tag = $('<span></span>');
+                new_tag.addClass('deletable-tag');
+                var tag_link = $('<a></a>');
+                tag_link.attr('rel','tag');
+                tag_link.attr('href', scriptUrl + $.i18n._('tags/') + tagname + '/');
+                tag_link.html(tagname);
+                var del_link = $('<img />');
+                del_link.addClass('delete-icon');
+                del_link.attr('src', mediaUrl('media/images/close-small-dark.png'));
+
+                setupTagDeleteEvents(del_link, to_target, tagname, reason, true);
+
+                new_tag.append(tag_link);
+                new_tag.append(del_link);
+                to_tag_container.append(new_tag);
+
+                to_target[tagname] = new_tag;
+
+                to_tag_container.trigger('contentchanged');
+            });
+        }
+    };
+
+    var collectPickedTags = function(){
+        var good_prefix = 'interesting-tag-';
+        var bad_prefix = 'ignored-tag-';
+        var good_re = RegExp('^' + good_prefix);
+        var bad_re = RegExp('^' + bad_prefix);
+        interestingTags = {};
+        ignoredTags = {};
+        $('.deletable-tag').each(
+            function(i,item){
+                var item_id = $(item).attr('id');
+                var tag_name, tag_store;
+                if (good_re.test(item_id)){
+                    tag_name = item_id.replace(good_prefix,'');
+                    tag_store = interestingTags;
+                    reason = 'good';
+                }
+                else if (bad_re.test(item_id)){
+                    tag_name = item_id.replace(bad_prefix,'');
+                    tag_store = ignoredTags;
+                    reason = 'bad';
+                }
+                else {
+                    return;
+                }
+                tag_store[tag_name] = $(item);
+                setupTagDeleteEvents($(item).find('img'),tag_store,tag_name,reason,true);
+            }
+        );
+    };
+
+    var setupHideIgnoredQuestionsControl = function(){
+        $('#hideIgnoredTagsCb').unbind('click').click(function(){
+            $.ajax({
+                        type: 'POST',
+                        dataType: 'json',
+                        cache: false,
+                        url: scriptUrl + $.i18n._('command/'),
+                        data: {command:'toggle-ignored-questions'}
+                    });
+        });
+    };
+    return {
+        init: function(){
+            collectPickedTags();
+            setupHideIgnoredQuestionsControl();
+            $("#interestingTagInput, #ignoredTagInput").autocomplete(messages.matching_tags_url, {
+                minChars: 1,
+                matchContains: true,
+                max: 20,
+                /*multiple: false, - the favorite tags and ignore tags don't let you do multiple tags
+                multipleSeparator: " "*/
+
+                formatItem: function(row, i, max, value) {
+                    return row[1] + " (" + row[2] + ")";
+                },
+
+                formatResult: function(row, i, max, value){
+                    return row[1];
+                }
+
+            });
+            $("#interestingTagAdd").click(function(){handlePickedTag(this,'good');});
+            $("#ignoredTagAdd").click(function(){handlePickedTag(this,'bad');});
+        }
+    };
+}
+
+Hilite={elementid:"content",exact:true,max_nodes:1000,onload:true,style_name:"hilite",style_name_suffix:true,debug_referrer:""};Hilite.search_engines=[["local","q"],["cnprog\\.","q"],["google\\.","q"],["search\\.yahoo\\.","p"],["search\\.msn\\.","q"],["search\\.live\\.","query"],["search\\.aol\\.","userQuery"],["ask\\.com","q"],["altavista\\.","q"],["feedster\\.","q"],["search\\.lycos\\.","q"],["alltheweb\\.","q"],["technorati\\.com/search/([^\\?/]+)",1],["dogpile\\.com/info\\.dogpl/search/web/([^\\?/]+)",1,true]];Hilite.decodeReferrer=function(d){var g=null;var e=new RegExp("");for(var c=0;c<Hilite.search_engines.length;c++){var f=Hilite.search_engines[c];e.compile("^http://(www\\.)?"+f[0],"i");var b=d.match(e);if(b){var a;if(isNaN(f[1])){a=Hilite.decodeReferrerQS(d,f[1])}else{a=b[f[1]+1]}if(a){a=decodeURIComponent(a);if(f.length>2&&f[2]){a=decodeURIComponent(a)}a=a.replace(/\'|"/g,"");a=a.split(/[\s,\+\.]+/);return a}break}}return null};Hilite.decodeReferrerQS=function(f,d){var b=f.indexOf("?");var c;if(b>=0){var a=new String(f.substring(b+1));b=0;c=0;while((b>=0)&&((c=a.indexOf("=",b))>=0)){var e,g;e=a.substring(b,c);b=a.indexOf("&",c)+1;if(e==d){if(b<=0){return a.substring(c+1)}else{return a.substring(c+1,b-1)}}else{if(b<=0){return null}}}}return null};Hilite.hiliteElement=function(f,e){if(!e||f.childNodes.length==0){return}var c=new Array();for(var b=0;b<e.length;b++){e[b]=e[b].toLowerCase();if(Hilite.exact){c.push("\\b"+e[b]+"\\b")}else{c.push(e[b])}}c=new RegExp(c.join("|"),"i");var a={};for(var b=0;b<e.length;b++){if(Hilite.style_name_suffix){a[e[b]]=Hilite.style_name+(b+1)}else{a[e[b]]=Hilite.style_name}}var d=function(m){var j=c.exec(m.data);if(j){var n=j[0];var i="";var h=m.splitText(j.index);var g=h.splitText(n.length);var l=m.ownerDocument.createElement("SPAN");m.parentNode.replaceChild(l,h);l.className=a[n.toLowerCase()];l.appendChild(h);return l}else{return m}};Hilite.walkElements(f.childNodes[0],1,d)};Hilite.hilite=function(){var a=Hilite.debug_referrer?Hilite.debug_referrer:document.referrer;var b=null;a=Hilite.decodeReferrer(a);if(a&&((Hilite.elementid&&(b=document.getElementById(Hilite.elementid)))||(b=document.body))){Hilite.hiliteElement(b,a)}};Hilite.walkElements=function(d,f,e){var a=/^(script|style|textarea)/i;var c=0;while(d&&f>0){c++;if(c>=Hilite.max_nodes){var b=function(){Hilite.walkElements(d,f,e)};setTimeout(b,50);return}if(d.nodeType==1){if(!a.test(d.tagName)&&d.childNodes.length>0){d=d.childNodes[0];f++;continue}}else{if(d.nodeType==3){d=e(d)}}if(d.nextSibling){d=d.nextSibling}else{while(f>0){d=d.parentNode;f--;if(d.nextSibling){d=d.nextSibling;break}}}}};if(Hilite.onload){if(window.attachEvent){window.attachEvent("onload",Hilite.hilite)}else{if(window.addEventListener){window.addEventListener("load",Hilite.hilite,false)}else{var __onload=window.onload;window.onload=function(){Hilite.hilite();__onload()}}}};
+
+var mediaUrl = function(resource){
+    return scriptUrl + 'm/' + osqaSkin + '/' + resource;
+};
+
+/*
+ * jQuery i18n plugin
+ * @requires jQuery v1.1 or later
+ *
+ * Examples at: http://recurser.com/articles/2008/02/21/jquery-i18n-translation-plugin/
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ * Based on 'javascript i18n that almost doesn't suck' by markos
+ * http://markos.gaivo.net/blog/?p=100
+ *
+ * Revision: $Id$
+ * Version: 1.0.0  Feb-10-2008
+ */
+ (function($) {
+/**
+ * i18n provides a mechanism for translating strings using a jscript dictionary.
+ *
+ */
+
+
+/*
+ * i18n property list
+ */
+$.i18n = {
+
+/**
+ * setDictionary()
+ * Initialise the dictionary and translate nodes
+ *
+ * @param property_list i18n_dict : The dictionary to use for translation
+ */
+       setDictionary: function(i18n_dict) {
+               i18n_dict = i18n_dict;
+       },
+
+/**
+ * _()
+ * The actual translation function. Looks the given string up in the
+ * dictionary and returns the translation if one exists. If a translation
+ * is not found, returns the original word
+ *
+ * @param string str : The string to translate
+ * @param property_list params : params for using printf() on the string
+ * @return string : Translated word
+ *
+ */
+       _: function (str, params) {
+               var transl = str;
+               if (i18n_dict&& i18n_dict[str]) {
+                       transl = i18n_dict[str];
+               }
+               return this.printf(transl, params);
+       },
+
+/**
+ * toEntity()
+ * Change non-ASCII characters to entity representation
+ *
+ * @param string str : The string to transform
+ * @return string result : Original string with non-ASCII content converted to entities
+ *
+ */
+       toEntity: function (str) {
+               var result = '';
+               for (var i=0;i<str.length; i++) {
+                       if (str.charCodeAt(i) > 128)
+                               result += "&#"+str.charCodeAt(i)+";";
+                       else
+                               result += str.charAt(i);
+               }
+               return result;
+       },
+
+/**
+ * stripStr()
+ *
+ * @param string str : The string to strip
+ * @return string result : Stripped string
+ *
+ */
+       stripStr: function(str) {
+               return str.replace(/^\s*/, "").replace(/\s*$/, "");
+       },
+
+/**
+ * stripStrML()
+ *
+ * @param string str : The multi-line string to strip
+ * @return string result : Stripped string
+ *
+ */
+       stripStrML: function(str) {
+               // Split because m flag doesn't exist before JS1.5 and we need to
+               // strip newlines anyway
+               var parts = str.split('\n');
+               for (var i=0; i<parts.length; i++)
+                       parts[i] = stripStr(parts[i]);
+
+               // Don't join with empty strings, because it "concats" words
+               // And strip again
+               return stripStr(parts.join(" "));
+       },
+
+/*
+ * printf()
+ * C-printf like function, which substitutes %s with parameters
+ * given in list. %%s is used to escape %s.
+ *
+ * Doesn't work in IE5.0 (splice)
+ *
+ * @param string S : string to perform printf on.
+ * @param string L : Array of arguments for printf()
+ */
+       printf: function(S, L) {
+               if (!L) return S;
+
+               var nS = "";
+               var tS = S.split("%s");
+
+               for(var i=0; i<L.length; i++) {
+                       if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != L.length-1)
+                               tS[i] += "s"+tS.splice(i+1,1)[0];
+                       nS += tS[i] + L[i];
+               }
+               return nS + tS[tS.length-1];
+       }
+
+};
+
+
+})(jQuery);
+
+
+//var i18nLang;
+var i18nZh = {
+       'insufficient privilege':'??????????',
+       'cannot pick own answer as best':'??????????????',
+       'anonymous users cannot select favorite questions':'?????????????',
+       'please login':'??????',
+       'anonymous users cannot vote':'????????',
+       '>15 points requried to upvote':'??+15?????????',
+       '>100 points required to downvote':'??+100?????????',
+       'please see': '??',
+       'cannot vote for own posts':'??????????',
+       'daily vote cap exhausted':'????????????????',
+       'cannot revoke old vote':'??????????????',
+       'please confirm offensive':"??????????????????????",
+       'anonymous users cannot flag offensive posts':'???????????',
+       'cannot flag message as offensive twice':'???????',
+       'flag offensive cap exhausted':'?????????????5?\91??\92???',
+       'need >15 points to report spam':"??+15??????\91???\92?",
+       'confirm delete':"?????/????????",
+       'anonymous users cannot delete/undelete':"???????????????",
+       'post recovered':"?????????????",
+       'post deleted':"????????????",
+       'add comment':'????',
+       'community karma points':'????',
+       'to comment, need':'????',
+       'delete this comment':'?????',
+       'hide comments':"????",
+       'add a comment':"????",
+       'comments':"??",
+       'confirm delete comment':"?????????",
+       'characters':'??',
+       'can write':'???',
+       'click to close':'???????',
+       'loading...':'???...',
+       'tags cannot be empty':'???????',
+       'tablimits info':"??5????????????20????",
+       'content cannot be empty':'???????',
+       'content minchars': '????? {0} ???',
+       'please enter title':'??????',
+       'title minchars':"????? {0} ???",
+       'delete':'??',
+       'undelete':     '??',
+       'bold':'??',
+       'italic':'??',
+       'link':'???',
+       'quote':'??',
+       'preformatted text':'??',
+       'image':'??',
+       'numbered list':'??????',
+       'bulleted list':'??????',
+       'heading':'??',
+       'horizontal bar':'???',
+       'undo':'??',
+       'redo':'??',
+       'enter image url':'<b>??????</b></p><p>???<br />http://www.example.com/image.jpg   \"????\"',
+       'enter url':'<b>??Web??</b></p><p>???<br />http://www.cnprog.com/   \"????\"</p>"',
+       'upload image':'?????????'
+};
+
+var i18nEn = {
+       'need >15 points to report spam':'need >15 points to report spam ',
+    '>15 points requried to upvote':'>15 points required to upvote ',
+       'tags cannot be empty':'please enter at least one tag',
+       'anonymous users cannot vote':'sorry, anonymous users cannot vote ',
+       'anonymous users cannot select favorite questions':'sorry, anonymous users cannot select favorite questions ',
+       'to comment, need': '(to comment other people\'s posts, karma ',
+       'please see':'please see ',
+       'community karma points':' or more is necessary) - ',
+       'upload image':'Upload image:',
+       'enter image url':'enter URL of the image, e.g. http://www.example.com/image.jpg \"image title\"',
+       'enter url':'enter Web address, e.g. http://www.example.com \"page title\"',
+       'daily vote cap exhausted':'sorry, you\'ve used up todays vote cap',
+       'cannot pick own answer as best':'sorry, you cannot accept your own answer',
+       'cannot revoke old vote':'sorry, older votes cannot be revoked',
+       'please confirm offensive':'are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?',
+       'flag offensive cap exhausted':'sorry, you\'ve used up todays cap of flagging offensive messages ',
+       'confirm delete':'are you sure you want to delete this?',
+       'anonymous users cannot delete/undelete':'sorry, anonymous users cannot delete or undelete posts',
+       'post recovered':'your post is now restored!',
+       'post deleted':'your post has been deleted',
+       'confirm delete comment':'do you really want to delete this comment?',
+       'can write':'have ',
+       'tablimits info':'up to 5 tags, no more than 20 characters each',
+       'content minchars': 'please enter more than {0} characters',
+       'title minchars':"please enter at least {0} characters",
+       'characters':'characters left',
+    'cannot vote for own posts':'sorry, you cannot vote for your own posts',
+    'cannot flag message as offensive twice':'cannot flag message as offensive twice ',
+       '>100 points required to downvote':'>100 points required to downvote '
+};
+
+var i18nEs = {
+       'insufficient privilege':'privilegio insuficiente',
+       'cannot pick own answer as best':'no puede escoger su propia respuesta como la mejor',
+       'anonymous users cannot select favorite questions':'usuarios anonimos no pueden seleccionar',
+       'please login':'por favor inicie sesión',
+       'anonymous users cannot vote':'usuarios anónimos no pueden votar',
+       '>15 points requried to upvote': '>15 puntos requeridos para votar positivamente',
+       '>100 points required to downvote':'>100 puntos requeridos para votar negativamente',
+       'please see': 'por favor vea',
+       'cannot vote for own posts':'no se puede votar por sus propias publicaciones',
+       'daily vote cap exhausted':'cuota de votos diarios excedida',
+       'cannot revoke old vote':'no puede revocar un voto viejo',
+       'please confirm offensive':"por favor confirme ofensiva",
+       'anonymous users cannot flag offensive posts':'usuarios anónimos no pueden marcar publicaciones como ofensivas',
+       'cannot flag message as offensive twice':'no puede marcar mensaje como ofensivo dos veces',
+       'flag offensive cap exhausted':'cuota para marcar ofensivas ha sido excedida',
+       'need >15 points to report spam':"necesita >15 puntos para reportar spam",
+       'confirm delete':"¿Está seguro que desea borrar esto?",
+       'anonymous users cannot delete/undelete':"usuarios anónimos no pueden borrar o recuperar publicaciones",
+       'post recovered':"publicación recuperada",
+       'post deleted':"publicación borrada?",
+       'add comment':'agregar comentario',
+       'community karma points':'reputación comunitaria',
+       'to comment, need':'para comentar, necesita reputación',
+       'delete this comment':'borrar este comentario',
+       'hide comments':"ocultar comentarios",
+       'add a comment':"agregar comentarios",
+       'comments':"comentarios",
+       'confirm delete comment':"¿Realmente desea borrar este comentario?",
+       'characters':'caracteres faltantes',
+       'can write':'tiene ',
+       'click to close':'haga click para cerrar',
+       'loading...':'cargando...',
+       'tags cannot be empty':'las etiquetas no pueden estar vacías',
+       'tablimits info':"hasta 5 etiquetas de no mas de 20 caracteres cada una",
+       'content cannot be empty':'el contenido no puede estar vacío',
+       'content minchars': 'por favor introduzca mas de {0} caracteres',
+       'please enter title':'por favor ingrese un título',
+       'title minchars':"por favor introduzca al menos {0} caracteres",
+       'delete':'borrar',
+       'undelete':     'recuperar',
+       'bold': 'negrita',
+       'italic':'cursiva',
+       'link':'enlace',
+       'quote':'citar',
+       'preformatted text':'texto preformateado',
+       'image':'imagen',
+       'numbered list':'lista numerada',
+       'bulleted list':'lista no numerada',
+       'heading':'??',
+       'horizontal bar':'barra horizontal',
+       'undo':'deshacer',
+       'redo':'rehacer',
+       'enter image url':'introduzca la URL de la imagen, por ejemplo?<br />http://www.example.com/image.jpg   \"titulo de imagen\"',
+       'enter url':'introduzca direcciones web, ejemplo?<br />http://www.cnprog.com/   \"titulo del enlace\"</p>"',
+       'upload image':'cargar imagen?',
+       'questions/' : 'preguntas/',
+       'vote/' : 'votar/'
+};
+
+var i18n = {
+       'en':i18nEn,
+       'zh_CN':i18nZh,
+       'es':i18nEs
+};
+
+var i18n_dict = i18n[i18nLang];
+
+/*
+       jQuery TextAreaResizer plugin
+       Created on 17th January 2008 by Ryan O'Dell
+       Version 1.0.4
+*/(function($){var textarea,staticOffset;var iLastMousePos=0;var iMin=32;var grip;$.fn.TextAreaResizer=function(){return this.each(function(){textarea=$(this).addClass('processed'),staticOffset=null;$(this).wrap('<div class="resizable-textarea"><span></span></div>').parent().append($('<div class="grippie"></div>').bind("mousedown",{el:this},startDrag));var grippie=$('div.grippie',$(this).parent())[0];grippie.style.marginRight=(grippie.offsetWidth-$(this)[0].offsetWidth)+'px'})};function startDrag(e){textarea=$(e.data.el);textarea.blur();iLastMousePos=mousePosition(e).y;staticOffset=textarea.height()-iLastMousePos;textarea.css('opacity',0.25);$(document).mousemove(performDrag).mouseup(endDrag);return false}function performDrag(e){var iThisMousePos=mousePosition(e).y;var iMousePos=staticOffset+iThisMousePos;if(iLastMousePos>=(iThisMousePos)){iMousePos-=5}iLastMousePos=iThisMousePos;iMousePos=Math.max(iMin,iMousePos);textarea.height(iMousePos+'px');if(iMousePos<iMin){endDrag(e)}return false}function endDrag(e){$(document).unbind('mousemove',performDrag).unbind('mouseup',endDrag);textarea.css('opacity',1);textarea.focus();textarea=null;staticOffset=null;iLastMousePos=0}function mousePosition(e){return{x:e.clientX+document.documentElement.scrollLeft,y:e.clientY+document.documentElement.scrollTop}}})(jQuery);
+/*
+ * Autocomplete - jQuery plugin 1.0.3
+ *
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *   http://www.gnu.org/licenses/gpl.html
+ *
+ */
+(function(a){a.fn.extend({autocomplete:function(b,c){var d=typeof b=="string";c=a.extend({},a.Autocompleter.defaults,{url:d?b:null,data:d?null:b,delay:d?a.Autocompleter.defaults.delay:10,max:c&&!c.scroll?10:150},c);c.highlight=c.highlight||function(e){return e};c.formatMatch=c.formatMatch||c.formatItem;return this.each(function(){new a.Autocompleter(this,c)})},result:function(b){return this.bind("result",b)},search:function(b){return this.trigger("search",[b])},flushCache:function(){return this.trigger("flushCache")},setOptions:function(b){return this.trigger("setOptions",[b])},unautocomplete:function(){return this.trigger("unautocomplete")}});a.Autocompleter=function(l,g){var c={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var b=a(l).attr("autocomplete","off").addClass(g.inputClass);var j;var p="";var m=a.Autocompleter.Cache(g);var e=0;var u;var x={mouseDownOnSelect:false};var r=a.Autocompleter.Select(g,l,d,x);var w;a.browser.opera&&a(l.form).bind("submit.autocomplete",function(){if(w){w=false;return false}});b.bind((a.browser.opera?"keypress":"keydown")+".autocomplete",function(y){u=y.keyCode;switch(y.keyCode){case c.UP:y.preventDefault();if(r.visible()){r.prev()}else{t(0,true)}break;case c.DOWN:y.preventDefault();if(r.visible()){r.next()}else{t(0,true)}break;case c.PAGEUP:y.preventDefault();if(r.visible()){r.pageUp()}else{t(0,true)}break;case c.PAGEDOWN:y.preventDefault();if(r.visible()){r.pageDown()}else{t(0,true)}break;case g.multiple&&a.trim(g.multipleSeparator)==","&&c.COMMA:case c.TAB:case c.RETURN:if(d()){y.preventDefault();w=true;return false}break;case c.ESC:r.hide();break;default:clearTimeout(j);j=setTimeout(t,g.delay);break}}).focus(function(){e++}).blur(function(){e=0;if(!x.mouseDownOnSelect){s()}}).click(function(){if(e++>1&&!r.visible()){t(0,true)}}).bind("search",function(){var y=(arguments.length>1)?arguments[1]:null;function z(D,C){var A;if(C&&C.length){for(var B=0;B<C.length;B++){if(C[B].result.toLowerCase()==D.toLowerCase()){A=C[B];break}}}if(typeof y=="function"){y(A)}else{b.trigger("result",A&&[A.data,A.value])}}a.each(h(b.val()),function(A,B){f(B,z,z)})}).bind("flushCache",function(){m.flush()}).bind("setOptions",function(){a.extend(g,arguments[1]);if("data" in arguments[1]){m.populate()}}).bind("unautocomplete",function(){r.unbind();b.unbind();a(l.form).unbind(".autocomplete")});function d(){var z=r.selected();if(!z){return false}var y=z.result;p=y;if(g.multiple){var A=h(b.val());if(A.length>1){y=A.slice(0,A.length-1).join(g.multipleSeparator)+g.multipleSeparator+y}y+=g.multipleSeparator}b.val(y);v();b.trigger("result",[z.data,z.value]);return true}function t(A,z){if(u==c.DEL){r.hide();return}var y=b.val();if(!z&&y==p){return}p=y;y=i(y);if(y.length>=g.minChars){b.addClass(g.loadingClass);if(!g.matchCase){y=y.toLowerCase()}f(y,k,v)}else{n();r.hide()}}function h(z){if(!z){return[""]}var A=z.split(g.multipleSeparator);var y=[];a.each(A,function(B,C){if(a.trim(C)){y[B]=a.trim(C)}});return y}function i(y){if(!g.multiple){return y}var z=h(y);return z[z.length-1]}function q(y,z){if(g.autoFill&&(i(b.val()).toLowerCase()==y.toLowerCase())&&u!=c.BACKSPACE){b.val(b.val()+z.substring(i(p).length));a.Autocompleter.Selection(l,p.length,p.length+z.length)}}function s(){clearTimeout(j);j=setTimeout(v,200)}function v(){var y=r.visible();r.hide();clearTimeout(j);n();if(g.mustMatch){b.search(function(z){if(!z){if(g.multiple){var A=h(b.val()).slice(0,-1);b.val(A.join(g.multipleSeparator)+(A.length?g.multipleSeparator:""))}else{b.val("")}}})}if(y){a.Autocompleter.Selection(l,l.value.length,l.value.length)}}function k(z,y){if(y&&y.length&&e){n();r.display(y,z);q(z,y[0].value);r.show()}else{v()}}function f(z,B,y){if(!g.matchCase){z=z.toLowerCase()}var A=m.load(z);if(A&&A.length){B(z,A)}else{if((typeof g.url=="string")&&(g.url.length>0)){var C={timestamp:+new Date()};a.each(g.extraParams,function(D,E){C[D]=typeof E=="function"?E():E});a.ajax({mode:"abort",port:"autocomplete"+l.name,dataType:g.dataType,url:g.url,data:a.extend({q:i(z),limit:g.max},C),success:function(E){var D=g.parse&&g.parse(E)||o(E);m.add(z,D);B(z,D)}})}else{r.emptyList();y(z)}}}function o(B){var y=[];var A=B.split("\n");for(var z=0;z<A.length;z++){var C=a.trim(A[z]);if(C){C=C.split("|");y[y.length]={data:C,value:C[0],result:g.formatResult&&g.formatResult(C,C[0])||C[0]}}}return y}function n(){b.removeClass(g.loadingClass)}};a.Autocompleter.defaults={inputClass:"ac_input",resultsClass:"ac_results",loadingClass:"ac_loading",minChars:1,delay:400,matchCase:false,matchSubset:true,matchContains:false,cacheLength:10,max:100,mustMatch:false,extraParams:{},selectFirst:true,formatItem:function(b){return b[0]},formatMatch:null,autoFill:false,width:0,multiple:false,multipleSeparator:", ",highlight:function(c,b){return c.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)("+b.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"<strong>$1</strong>")},scroll:true,scrollHeight:180};a.Autocompleter.Cache=function(c){var f={};var d=0;function h(l,k){if(!c.matchCase){l=l.toLowerCase()}var j=l.indexOf(k);if(j==-1){return false}return j==0||c.matchContains}function g(j,i){if(d>c.cacheLength){b()}if(!f[j]){d++}f[j]=i}function e(){if(!c.data){return false}var k={},j=0;if(!c.url){c.cacheLength=1}k[""]=[];for(var m=0,l=c.data.length;m<l;m++){var p=c.data[m];p=(typeof p=="string")?[p]:p;var o=c.formatMatch(p,m+1,c.data.length);if(o===false){continue}var n=o.charAt(0).toLowerCase();if(!k[n]){k[n]=[]}var q={value:o,data:p,result:c.formatResult&&c.formatResult(p)||o};k[n].push(q);if(j++<c.max){k[""].push(q)}}a.each(k,function(r,s){c.cacheLength++;g(r,s)})}setTimeout(e,25);function b(){f={};d=0}return{flush:b,add:g,populate:e,load:function(n){if(!c.cacheLength||!d){return null}if(!c.url&&c.matchContains){var m=[];for(var j in f){if(j.length>0){var o=f[j];a.each(o,function(p,k){if(h(k.value,n)){m.push(k)}})}}return m}else{if(f[n]){return f[n]}else{if(c.matchSubset){for(var l=n.length-1;l>=c.minChars;l--){var o=f[n.substr(0,l)];if(o){var m=[];a.each(o,function(p,k){if(h(k.value,n)){m[m.length]=k}});return m}}}}}return null}}};a.Autocompleter.Select=function(e,j,l,p){var i={ACTIVE:"ac_over"};var k,f=-1,r,m="",s=true,c,o;function n(){if(!s){return}c=a("<div/>").hide().addClass(e.resultsClass).css("position","absolute").appendTo(document.body);o=a("<ul/>").appendTo(c).mouseover(function(t){if(q(t).nodeName&&q(t).nodeName.toUpperCase()=="LI"){f=a("li",o).removeClass(i.ACTIVE).index(q(t));a(q(t)).addClass(i.ACTIVE)}}).click(function(t){a(q(t)).addClass(i.ACTIVE);l();j.focus();return false}).mousedown(function(){p.mouseDownOnSelect=true}).mouseup(function(){p.mouseDownOnSelect=false});if(e.width>0){c.css("width",e.width)}s=false}function q(u){var t=u.target;while(t&&t.tagName!="LI"){t=t.parentNode}if(!t){return[]}return t}function h(t){k.slice(f,f+1).removeClass(i.ACTIVE);g(t);var v=k.slice(f,f+1).addClass(i.ACTIVE);if(e.scroll){var u=0;k.slice(0,f).each(function(){u+=this.offsetHeight});if((u+v[0].offsetHeight-o.scrollTop())>o[0].clientHeight){o.scrollTop(u+v[0].offsetHeight-o.innerHeight())}else{if(u<o.scrollTop()){o.scrollTop(u)}}}}function g(t){f+=t;if(f<0){f=k.size()-1}else{if(f>=k.size()){f=0}}}function b(t){return e.max&&e.max<t?e.max:t}function d(){o.empty();var u=b(r.length);for(var v=0;v<u;v++){if(!r[v]){continue}var w=e.formatItem(r[v].data,v+1,u,r[v].value,m);if(w===false){continue}var t=a("<li/>").html(e.highlight(w,m)).addClass(v%2==0?"ac_even":"ac_odd").appendTo(o)[0];a.data(t,"ac_data",r[v])}k=o.find("li");if(e.selectFirst){k.slice(0,1).addClass(i.ACTIVE);f=0}if(a.fn.bgiframe){o.bgiframe()}}return{display:function(u,t){n();r=u;m=t;d()},next:function(){h(1)},prev:function(){h(-1)},pageUp:function(){if(f!=0&&f-8<0){h(-f)}else{h(-8)}},pageDown:function(){if(f!=k.size()-1&&f+8>k.size()){h(k.size()-1-f)}else{h(8)}},hide:function(){c&&c.hide();k&&k.removeClass(i.ACTIVE);f=-1},visible:function(){return c&&c.is(":visible")},current:function(){return this.visible()&&(k.filter("."+i.ACTIVE)[0]||e.selectFirst&&k[0])},show:function(){var v=a(j).offset();c.css({width:typeof e.width=="string"||e.width>0?e.width:a(j).width(),top:v.top+j.offsetHeight,left:v.left}).show();if(e.scroll){o.scrollTop(0);o.css({maxHeight:e.scrollHeight,overflow:"auto"});if(a.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var t=0;k.each(function(){t+=this.offsetHeight});var u=t>e.scrollHeight;o.css("height",u?e.scrollHeight:t);if(!u){k.width(o.width()-parseInt(k.css("padding-left"))-parseInt(k.css("padding-right")))}}}},selected:function(){var t=k&&k.filter("."+i.ACTIVE).removeClass(i.ACTIVE);return t&&t.length&&a.data(t[0],"ac_data")},emptyList:function(){o&&o.empty()},unbind:function(){c&&c.remove()}}};a.Autocompleter.Selection=function(d,e,c){if(d.setSelectionRange){d.setSelectionRange(e,c)}else{if(d.createTextRange){var b=d.createTextRange();b.collapse(true);b.moveStart("character",e);b.moveEnd("character",c);b.select()}else{if(d.selectionStart){d.selectionStart=e;d.selectionEnd=c}}}d.focus()}})(jQuery);
+
+var notify = function() {
+    var visible = false;
+    return {
+        show: function(html) {
+            if (html) {
+                $("body").css("margin-top", "2.2em");
+                $(".notify span").html(html);
+            }
+            $(".notify").fadeIn("slow");
+            visible = true;
+        },
+        close: function(doPostback) {
+            $(".notify").fadeOut("fast");
+            $("body").css("margin-top", "0");
+            visible = false;
+        },
+        isVisible: function() { return visible; }
+    };
+} ();
+
+/*
+ * jQuery outside events - v1.1 - 3/16/2010
+ * http://benalman.com/projects/jquery-outside-events-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,c,b){$.map("click dblclick mousemove mousedown mouseup mouseover mouseout change select submit keydown keypress keyup".split(" "),function(d){a(d)});a("focusin","focus"+b);a("focusout","blur"+b);$.addOutsideEvent=a;function a(g,e){e=e||g+b;var d=$(),h=g+"."+e+"-special-event";$.event.special[e]={setup:function(){d=d.add(this);if(d.length===1){$(c).bind(h,f)}},teardown:function(){d=d.not(this);if(d.length===0){$(c).unbind(h)}},add:function(i){var j=i.handler;i.handler=function(l,k){l.target=k;j.apply(this,arguments)}}};function f(i){$(d).each(function(){var j=$(this);if(this!==i.target&&!j.has(i.target).length){j.triggerHandler(e,[i.target])}})}}})(jQuery,document,"outside");
+
+$(document).ready( function(){
+    pickedTags().init();
+
+    $('input#bnewaccount').click(function() {
+        $('#bnewaccount').disabled=true;
+    });
+});
+
+function yourWorkWillBeLost(e) {
+    if(browserTester('chrome')) {
+        return "Are you sure you want to leave?  Your work will be lost.";
+    } else if(browserTester('safari')) {
+        return "Are you sure you want to leave?  Your work will be lost.";
+    } else {
+        if(!e) e = window.event;
+        e.cancelBubble = true;
+        e.returnValue = 'If you leave, your work will be lost.';
+
+        if (e.stopPropagation) {
+            e.stopPropagation();
+            e.preventDefault();
+        }
+        return e;
+    }
+}
+
+function browserTester(browserString) {
+    return navigator.userAgent.toLowerCase().indexOf(browserString) > -1;
+}
+
+// Add missing IE functionality
+if (!window.addEventListener) {
+    if (window.attachEvent) {
+        window.addEventListener = function (type, listener, useCapture) {
+            window.attachEvent('on' + type, listener);
+        };
+        window.removeEventListener = function (type, listener, useCapture) {
+            window.detachEvent('on' + type, listener);
+        };
+    } else {
+        window.addEventListener = function (type, listener, useCapture) {
+            window['on' + type] = listener;
+        };
+        window.removeEventListener = function (type, listener, useCapture) {
+            window['on' + type] = null;
+        };
+    }
+}
index b563176740c3e2301c80196f7403d3794283a7a9..ad722b2d1bc03d61e06ca5fd0846e5f209a60144 100644 (file)
-/* Miniatury */\r
-.thumbdiv {\r
-       float:left; \r
-       position:relative;\r
-}\r
-.thumbdiv .title {\r
-       position:absolute;\r
-       padding:2px;\r
-       font-size:1.0em;\r
-       color:#fff;\r
-       background:#000;\r
-       border-top:solid 1px #000;\r
-       opacity:0.8;\r
-       bottom:14px;\r
-       left:8px;\r
-       right:9px;\r
-}\r
-/* VIEWBOX */\r
-#viewbox {\r
-       position:fixed;\r
-       height:100%;\r
-       width:100%;   \r
-       top:0;\r
-       left:0;\r
-       background:#383739;\r
-       z-index:2190; \r
-       overflow:auto;\r
-} \r
-.vb_wrap {\r
-       position:absolute; \r
-       padding:10px;\r
-       height:20px;\r
-       width:20px; \r
-       background-image:url(../images/viewbox/ViewBox_bg.png);\r
-       background-color:#0f0e0e;\r
-       overflow:visible; \r
-       z-index:2200;\r
-       margin:0 auto;\r
-       top:0; \r
-       left:0;\r
-       border-radius:10px;\r
-       box-shadow: 4px 4px 7px #000;\r
-} \r
-.vb_wrap .content {\r
-       position:relative;\r
-       overflow:visible;\r
-}\r
-.vb_wrap .number {\r
-       position:absolute;\r
-       top:-32px;\r
-       left:1px;\r
-       font-size:0.9em;\r
-       color:#0c0c0c;\r
-} \r
-.vb_wrap .close {\r
-       position:absolute; \r
-       top:-40px;\r
-       right:-7px;\r
-       background:url(../images/viewbox/viewbox_close.png) top left no-repeat;\r
-       height:30px;\r
-       width:30px;\r
-}\r
-* html .vb_wrap .close {\r
-       top:-26px;\r
-       right:7px;\r
-}\r
-.vb_wrap .next {\r
-       position:absolute;   \r
-       right:-60px;\r
-       background:url(../images/viewbox/ViewBox_next.png) top left no-repeat;\r
-       height:50px;\r
-       width:50px;\r
-       z-index:2190;\r
-}\r
-.vb_wrap .prev {\r
-       position:absolute;   \r
-       left:-59px;\r
-       background:url(../images/viewbox/ViewBox_prev.png) top right no-repeat;\r
-       height:50px;\r
-       width:50px;\r
-       z-index:2190;\r
-}\r
-.vb_wrap .close a, .vb_wrap .next a, .vb_wrap .prev a {\r
-       display:block;\r
-       height:100%;\r
-       width:100%;\r
-       text-indent:-777em;\r
-       outline:none;\r
-}\r
-.vb_wrap h1 {\r
-       margin:5px 0px 8px;\r
-       padding-bottom:3px;\r
-       letter-spacing:1.3px; \r
-       font-family:Arial, Helvetica, sans-serif;\r
-       font-size:0.9em;\r
-       color:#cdcdcd;\r
-       border-bottom:solid 1px #7e7e7e;\r
-       \r
-}\r
-.vb_wrap p { \r
-       font-family:Arial, Helvetica, sans-serif;\r
-       font-size:0.8em;\r
-       text-align:justify;\r
-       color:#e5e5e5;\r
-}\r
-.vb_wrap .text {\r
-       position:absolute;\r
-       background: url(../images/viewbox/ViewBox_bg.png) top left repeat;\r
-       border-top:solid 1px #121212;\r
-       bottom:0; left:0;\r
-       padding:5px;\r
-       width:99%; \r
-       z-index:2110;\r
-}\r
-* html .vb_wrap .text {\r
-       background-image:none;\r
-       background-color:#0f0e0e;\r
-}\r
-.vb_wrap .image {\r
-       z-index:2220;\r
-}\r
-.vb_wrap .text h1 {\r
-       margin:2px; \r
-       padding:1px;\r
-       color:#919191;\r
-       z-index:2230;\r
-}\r
-.vb_wrap .text .description {\r
-       position:relative;\r
-       bottom:0px; \r
-       left:0px;\r
-       padding:2px 2px;\r
-       font-family:Arial, Helvetica, sans-serif;\r
-       font-size:0.8em;\r
-       z-index:2260;\r
-       color:#949494; \r
-}\r
+/* Miniatury */
+.thumbdiv {
+       float:left; 
+       position:relative;
+}
+.thumbdiv .title {
+       position:absolute;
+       padding:2px;
+       font-size:1.0em;
+       color:#fff;
+       background:#000;
+       border-top:solid 1px #000;
+       opacity:0.8;
+       bottom:14px;
+       left:8px;
+       right:9px;
+}
+/* VIEWBOX */
+#viewbox {
+       position:fixed;
+       height:100%;
+       width:100%;   
+       top:0;
+       left:0;
+       background:#383739;
+       z-index:2190; 
+       overflow:auto;
+} 
+.vb_wrap {
+       position:absolute; 
+       padding:10px;
+       height:20px;
+       width:20px; 
+       background-image:url(../images/viewbox/ViewBox_bg.png);
+       background-color:#0f0e0e;
+       overflow:visible; 
+       z-index:2200;
+       margin:0 auto;
+       top:0; 
+       left:0;
+       border-radius:10px;
+       box-shadow: 4px 4px 7px #000;
+} 
+.vb_wrap .content {
+       position:relative;
+       overflow:visible;
+}
+.vb_wrap .number {
+       position:absolute;
+       top:-32px;
+       left:1px;
+       font-size:0.9em;
+       color:#0c0c0c;
+} 
+.vb_wrap .close {
+       position:absolute; 
+       top:-40px;
+       right:-7px;
+       background:url(../images/viewbox/viewbox_close.png) top left no-repeat;
+       height:30px;
+       width:30px;
+}
+* html .vb_wrap .close {
+       top:-26px;
+       right:7px;
+}
+.vb_wrap .next {
+       position:absolute;   
+       right:-60px;
+       background:url(../images/viewbox/ViewBox_next.png) top left no-repeat;
+       height:50px;
+       width:50px;
+       z-index:2190;
+}
+.vb_wrap .prev {
+       position:absolute;   
+       left:-59px;
+       background:url(../images/viewbox/ViewBox_prev.png) top right no-repeat;
+       height:50px;
+       width:50px;
+       z-index:2190;
+}
+.vb_wrap .close a, .vb_wrap .next a, .vb_wrap .prev a {
+       display:block;
+       height:100%;
+       width:100%;
+       text-indent:-777em;
+       outline:none;
+}
+.vb_wrap h1 {
+       margin:5px 0px 8px;
+       padding-bottom:3px;
+       letter-spacing:1.3px; 
+       font-family:Arial, Helvetica, sans-serif;
+       font-size:0.9em;
+       color:#cdcdcd;
+       border-bottom:solid 1px #7e7e7e;
+       
+}
+.vb_wrap p { 
+       font-family:Arial, Helvetica, sans-serif;
+       font-size:0.8em;
+       text-align:justify;
+       color:#e5e5e5;
+}
+.vb_wrap .text {
+       position:absolute;
+       background: url(../images/viewbox/ViewBox_bg.png) top left repeat;
+       border-top:solid 1px #121212;
+       bottom:0; left:0;
+       padding:5px;
+       width:99%; 
+       z-index:2110;
+}
+* html .vb_wrap .text {
+       background-image:none;
+       background-color:#0f0e0e;
+}
+.vb_wrap .image {
+       z-index:2220;
+}
+.vb_wrap .text h1 {
+       margin:2px; 
+       padding:1px;
+       color:#919191;
+       z-index:2230;
+}
+.vb_wrap .text .description {
+       position:relative;
+       bottom:0px; 
+       left:0px;
+       padding:2px 2px;
+       font-family:Arial, Helvetica, sans-serif;
+       font-size:0.8em;
+       z-index:2260;
+       color:#949494; 
+}
index 7c1023fd6fb39157ada46de8f144edad4ac05bcf..0740e1fd4db91e74d9bd2b8250df926b1cc80d53 100644 (file)
@@ -2,7 +2,7 @@
 {% load i18n %}
 {% block title %}{% trans "Not logged in" %}{% endblock %}
 {% block meta %}
-    <!-- <meta http-equiv="refresh" content="5;url={% url auth_signin %}"> -->
+    <!-- <meta http-equiv="refresh" content="5;url={% url "auth_signin" %}"> -->
 {% endblock %}
 {% block forestyle%}
     <style type="text/css">
@@ -17,7 +17,7 @@
             }, 800);
 
             window.setTimeout(function() {
-                window.location = "{% url auth_signin %}";
+                window.location = "{% url "auth_signin" %}";
             }, 5000);
         });
 
@@ -37,7 +37,7 @@
             </p>
             <p>
                 {% trans "If you're not automatically redirected in 5 seconds, please click" %}
-                <a href="{% url auth_signin %}">{% trans "here" %}</a>.
+                <a href="{% url "auth_signin" %}">{% trans "here" %}</a>.
             </p>
         </div>
     </div>
index 26b563f63fd812f72e244d71db6cb97177820c70..a8549bceff7d136ac6cfbacdfc7b8c947c009940 100644 (file)
             <li>{% trans "you followed a link on an email, but you're currently logged in as another user;" %}</li>
             <li>{% trans "there are errors in the url, please confirm it;" %}</li>
             <li>{% trans "if you believe you shouldn't bee seeing this error, please" %}
-                               <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url feedback %}{% endif %}" target="_blank">
+                               <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url "feedback" %}{% endif %}" target="_blank">
                                    {% trans "report this problem" %}
                                </a>
                        </li>
             </ul>
         </div>
         <ul>
-            <li><a href="{% url index %}">{% trans "to home page" %} &raquo;</a></li>
-            <li><a href="{% url questions %}">{% trans "see all questions" %} &raquo;</a></li>
-            <li><a href="{% url tags %}">{% trans "see all tags" %} &raquo;</a></li>
+            <li><a href="{% url "index" %}">{% trans "to home page" %} &raquo;</a></li>
+            <li><a href="{% url "questions" %}">{% trans "see all questions" %} &raquo;</a></li>
+            <li><a href="{% url "tags" %}">{% trans "see all tags" %} &raquo;</a></li>
         </ul>
     </div>
 
index ad2ac68cdbf563856385e5acba9e2d0432fd16ee..da70f934c48482b6562a28cc6001cfe116156354 100644 (file)
@@ -28,7 +28,7 @@
             <li>{% trans "this question or answer has been deleted;" %}</li>
             <li>{% trans "url has error - please check it;" %}</li>
             <li>{% trans "if you believe this error 404 should not have occurred, please" %} 
-                               <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url feedback %}{% endif %}">{% trans "report this problem" %}</a></li>
+                               <a href="{% if settings.CONTACT_URL %}{{ settings.CONTACT_URL }}{% else %}{% url "feedback" %}{% endif %}">{% trans "report this problem" %}</a></li>
             </ul>
         </div>
         <script type="text/javascript">
@@ -38,8 +38,8 @@
         <script type="text/javascript" src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
         <ul>
             <li><a href="#" id="linkPrevious">{% trans "back to previous page" %} &raquo;</a></li>
-            <li><a href="{% url questions %}">{% trans "see all questions" %} &raquo;</a></li>
-            <li><a href="{% url tags %}">{% trans "see all tags" %} &raquo;</a></li>
+            <li><a href="{% url "questions" %}">{% trans "see all questions" %} &raquo;</a></li>
+            <li><a href="{% url "tags" %}">{% trans "see all tags" %} &raquo;</a></li>
         </ul>
     </div>
 
index 3300b8e91a8ed4796972e8955c2f97b549043352..4088bb4081fcbb1f97c93b71f94f9d8f592babbf 100644 (file)
@@ -25,8 +25,8 @@
                {% trans "please report the error to the site administrators if you wish" %}
         <ul>
             <li><a href="#" id="linkPrevious">{% trans "back to previous page" %}</a></li>
-            <li><a href="{% url questions %}">{% trans "see latest questions" %}</a></li>
-            <li><a href="{% url tags %}">{% trans "see tags" %}</a></li>
+            <li><a href="{% url "questions" %}">{% trans "see latest questions" %}</a></li>
+            <li><a href="{% url "tags" %}">{% trans "see tags" %}</a></li>
         </ul>
     </div>
 
index d1349ec77c42e2399fb28ff11454ee470100349d..4f9fea1055795d21c3a2811e69f4ee5c361089d8 100644 (file)
        {% endif %}
 
        <dl class="list-item">
-        <dt>&raquo; <a href="{% url user_changepw %}">{% trans "Change password" %}</a></dt>
+        <dt>&raquo; <a href="{% url "user_changepw" %}">{% trans "Change password" %}</a></dt>
         <dd>{% trans "Give your  account a new password." %}</dd>
         {% comment %}
-        <dt>&raquo; <a href="{% url user_changeemail %}">{% trans "Change email " %}</a></dt>
+        <dt>&raquo; <a href="{% url "user_changeemail" %}">{% trans "Change email " %}</a></dt>
         <dd>{% trans "Add or update the email address associated with your account." %}</dd>
 
-        <dt>&raquo; <a href="{% url user_changeopenid %}">{% trans "Change OpenID" %}</a></dt>
+        <dt>&raquo; <a href="{% url "user_changeopenid" %}">{% trans "Change OpenID" %}</a></dt>
         <dd>{% trans "Change openid associated to your account" %}</dd>
 
         
-        <dt>&raquo; <a href="{% url user_delete %}">{% trans "Delete account" %}</a></dt>
+        <dt>&raquo; <a href="{% url "user_delete" %}">{% trans "Delete account" %}</a></dt>
         <dd>{% trans "Erase your username and all your data from website" %}</dd>
         {% endcomment %}
        </dl>
index 3201dd26de651966b3c59b537a3f3a33f5ab650f..a3be73fb8c1309b156db60f3a933b17f275d0d5f 100644 (file)
@@ -64,7 +64,7 @@
 </div>
 <div id="main-body" class="ask-body">
     <div id="askform">
-        <form id="fmedit" action="{% url edit_answer answer.id %}" method="post">
+        <form id="fmedit" action="{% url "edit_answer" answer.id %}" method="post">
             {% csrf_token %}
             <label for="id_revision" ><strong>{% trans "revision" %}:</strong></label> <br/> 
             {% if revision_form.revision.errors %}{{ revision_form.revision.errors.as_ul }}{% endif %}
index 39e1f3c2a34aac7088b6764175c9ba57ec52d6f1..163cddc067b653e502dd994b9d5cf7f14dc57b97 100644 (file)
@@ -17,7 +17,7 @@
             </li>
         </ul>
         <p class='info-box-follow-up-links'>
-            <a href="{% url faq %}" target="_blank" title="{% trans "see frequently asked questions" %}">faq &raquo;</a>
+            <a href="{% url "faq" %}" target="_blank" title="{% trans "see frequently asked questions" %}">faq &raquo;</a>
         </p>
     </div>
 </div>
index ec5b1a8e80d6ac2fd5fb38cd541f9bdc9a1beff9..0c7b25544a3d6e05fc09a354a712a973ad621ec7 100644 (file)
@@ -22,7 +22,7 @@
             $('#editor').TextAreaResizer();
 
             //toggle preview of editor
-                       //todo remove copy-paste
+            //todo remove copy-paste
             var display = true;
             var txt = "[{% trans "hide preview" %}]";
             $('#pre-collapse').text(txt);
@@ -34,9 +34,9 @@
             });
 
             //Tags autocomplete action
-               $("#id_tags").autocomplete("{% url matching_tags %}", {
+            $("#id_tags").autocomplete('{% url "matching_tags" %}', {
                 minChars: 1,
-                       matchContains: true,
+                matchContains: true,
                 max: 10,
                 multiple: true,
                 multipleSeparator: " ",
                 scroll: true,
                 scrollHeight: 300,
 
-
-                       /*
-                       formatItem: function(row, i, max) {
-                               return row.n + " ("+ row.c +")";
-                       },
-                formatResult: function(row, i, max){
-                    return row.n;
-                }
-                */
-
                 formatItem: function(row, i, max, value) {
                     return row[1] + " (" + row[2] + ")";
                 },
         }
         window.addEventListener('beforeunload', beforeUnload, true);
 
-        var related_questions_url = "{% url related_questions %}";
+        var related_questions_url = '{% url "related_questions" %}';
         </script>
         <script src="{% media "/media/js/osqa.ask.js" %}" type="text/javascript"></script>
 {% endblock %}
 
 {% block content %}
 <div id="main-bar" class="headNormal">
-       {% trans "Ask a question" %}
+    {% trans "Ask a question" %}
 </div>
 <div id="main-body" class="ask-body">
     <div id="askform">
         <form id="fmask" action="" method="post" accept-charset="utf-8">
             {% csrf_token %}
-                       {% if not request.user.is_authenticated %}
+            {% if not request.user.is_authenticated %}
             <div class="message">
                 <span class="strong big">{% trans "You are welcome to start submitting your question anonymously." %}</span>
                 <p>{% blocktrans %}
                 {% if not request.user.email_valid_and_can_ask %}
                     <div class="message">
                         {% blocktrans %}Remember, your question will not be published until you validate your email.{% endblocktrans %}
-                        <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+                        <a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
                     </div>
                 {% endif %}
-                       {% endif %}
+            {% endif %}
             <div class="form-item">
                 <label for="id_title" ><strong>{{ form.title.label_tag }}:</strong></label> <span class="form-error"></span><br/>
                 {{ form.title }} {{ form.title.errors }}
index 969036d6c499650c900381ca809df8c95d6c6533..4d9064c58bfda6dcd2e9e65644e57dbb9ea9a209 100644 (file)
@@ -9,7 +9,7 @@
     <p class="message">{% blocktrans %}These are the external authentication providers currently associated with your account.{% endblocktrans %}</p>
     <div>
         {% for key in auth_keys %}
-            <p>{{ key.name }} (<a href="{% url user_remove_external_provider id=key.id %}">{% trans "remove" %}</a>)</p>
+            <p>{{ key.name }} (<a href="{% url "user_remove_external_provider" id=key.id %}">{% trans "remove" %}</a>)</p>
         {% endfor %}
     </div>
 {% endif %}
@@ -17,7 +17,7 @@
     <p class="message">{% blocktrans %}You currently have no external authentication provider associated with your account.{% endblocktrans %}</p>
 {% endif %}
 {% ifequal view_user request.user %}
-    <input type="button" class="submit" value="{% trans "Add new provider" %}" onclick="window.location='{% url user_add_external_provider %}'" />
+    <input type="button" class="submit" value="{% trans "Add new provider" %}" onclick="window.location='{% url "user_add_external_provider" %}'" />
 {% endifequal %}
 {% if allow_local_auth %}
 {% if has_password %}
index 1c327bfeb4b0d59ef9443224ce54af3083a19ccc..efaf531fed840f0c340020d7f7079f32ff09784e 100644 (file)
@@ -88,7 +88,7 @@
     {% comment %}<!-- this form associates openID with an existing password-protected account, not yet functional -->
     {% if form2 %}
        <div class="login" style="display:none">
-        <form name="fverify" action="{% url user_register %}" method="POST">
+        <form name="fverify" action="{% url "user_register" %}" method="POST">
             {% csrf_token %}
             {{ form2.next }}
                        <fieldset style="padding:10px">
@@ -99,7 +99,7 @@
                                <!--todo double check translation from chinese 确认 = "Register" -->
                                <div class="submit-row">
                                        <input type="submit" class="submit" name="bverify" value="{% trans "Register" %}"/> 
-                                       <a href="{% url user_sendpw %}">{% trans "Forgot your password?" %}</a>
+                                       <a href="{% url "user_sendpw" %}">{% trans "Forgot your password?" %}</a>
                                </div>
                        </fieldset>
                </form>
index 82029d620862c0f7dd6952ddd1a9ebbb4887cfc7..7e6a2f3022d7b4c1d2c3f5ccb13dfc0308c1582c 100644 (file)
     {% htmlcontent notifications/base.html %}
         <p style="{{ p_style }}">{% trans "Please use the following link to help us verify your email address:" %}</p>
 
-        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl auth_validate_email user=recipient.id,code=validation_code %}">{% trans "Validate my email address" %}</a></p>
+        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}">{% trans "Validate my email address" %}</a></p>
 
         <p style="{{ p_style }}">{% trans "If the above link is not clickable, copy and paste this url into your web browser's address bar:" %}</p>
 
-        <p style="{{ p_style }}">{% fullurl auth_validate_email user=recipient.id,code=validation_code %}</p>
+        <p style="{{ p_style }}">{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}</p>
     {% endhtmlcontent %}
 
 {% textcontent notifications/base_text.html %}
 {% trans "Copy and paste this url into your web browser's address bar to help us verify your email address:" %}
 
-{% fullurl auth_validate_email user=recipient.id,code=validation_code %}
+{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}
 {% endtextcontent %}
 
 {% endemail %}
index 5514cc52823ecdaed5a8922a1d8574f62d39381f..617abe63b6b9a176e93e497d3c2cc406e0948ab5 100644 (file)
-{% extends "base.html" %}\r
-\r
-{% load i18n %}\r
-{% load extra_tags %}\r
-\r
-{% block title %}{% spaceless %}{% trans "Login" %}{% endspaceless %}{% endblock %}\r
-        \r
-{% block forejs %}\r
-    <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/auth.css" %}"/>\r
-    {% for provider in all_providers %}\r
-        {% for location in provider.extra_css %}\r
-            <link rel="stylesheet" type="text/css" media="screen" href="{{ location }}"/>\r
-        {% endfor %}\r
-    {% endfor %}\r
-{% endblock %}\r
-\r
-{% block content %}\r
-    {% for provider in all_providers %}\r
-        {% if provider.pre_code %}\r
-            {{ provider.pre_code|safe }}\r
-        {% endif %}\r
-    {% endfor %}\r
-    <div class="headNormal">\r
-           {% trans "User login" %}\r
-    </div>\r
-    {% if msg %}\r
-        <p class="error">{{ msg }}</p>\r
-    {% endif %}\r
-    {% for provider in top_stackitem_providers %}\r
-        <form class="signin_form" method="POST" action="{% url auth_provider_signin provider=provider.id %}" accept-charset="utf-8">\r
-            {% csrf_token %}\r
-            {% include provider.stack_item_template %}\r
-            <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
-        </form>\r
-    {% endfor %}\r
-    {% if top_stackitem_providers %}\r
-        <h3 class="or_label">{% trans 'Or...' %}</h3>\r
-    {% endif %}\r
-    <div style="width:600px;float:left;margin-bottom:5px;">\r
-    {% blocktrans %}\r
-        External login services use <b><a href="http://openid.net/">OpenID</a></b> technology, where your password always stays confidential between\r
-        you and your login provider and you don't have to remember another one.\r
-    {% endblocktrans %}\r
-    </div>\r
-    {% if request.user.is_anonymous %}\r
-        <div style="width:600px;float:left;margin-bottom:5px;">\r
-            <input type="checkbox" checked="checked" id="validate_email" />\r
-            {% trans "Validate my email after I login." %}\r
-        </div>\r
-    {% endif %}\r
-    <div id="bigicon_providers">\r
-        {% for provider in bigicon_providers %}\r
-            <div class="provider_logo big" name="{{ provider.id }}">\r
-                <div class="inner">\r
-                    {% ifequal provider.type "DIRECT" %}\r
-                        <a class="provider_direct" href="{% url auth_provider_signin provider=provider.id %}">\r
-                            <img src="{% media provider.icon %}" />\r
-                        </a>\r
-                    {% endifequal %}\r
-                    {% ifequal provider.type "CUSTOM" %}\r
-                        {% include provider.code_template %}\r
-                    {% endifequal %}\r
-                    {% ifequal provider.type "SIMPLE_FORM" %}\r
-                        <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />\r
-                    {% endifequal %}\r
-                </div>\r
-            </div>\r
-        {% endfor %}\r
-    </div>\r
-    <div id="smallicon_providers">\r
-        {% for provider in smallicon_providers %}\r
-            <div class="provider_logo small" name="{{ provider.id }}">\r
-                <div class="inner">\r
-                    {% ifequal provider.type "DIRECT" %}\r
-                        <a class="provider_direct" href="{% url auth_provider_signin provider=provider.id %}">\r
-                            <img src="{% media provider.icon %}" />\r
-                        </a>\r
-                    {% endifequal %}\r
-                    {% ifequal provider.type "CUSTOM" %}\r
-                        {% include provider.code_template %}\r
-                    {% endifequal %}\r
-                    {% ifequal provider.type "SIMPLE_FORM" %}\r
-                        <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />\r
-                    {% endifequal %}\r
-                </div>\r
-            </div>\r
-        {% endfor %}\r
-    </div>\r
-    <form name="signin_form" id="signin_form" class="signin_form" method="POST" action="">\r
-        {% csrf_token %}\r
-        <div id="signin_form_slot"></div>\r
-        <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
-    </form>\r
-    {% for provider in stackitem_providers %}\r
-        <h3 class="or_label">{% trans 'Or...' %}</h3>\r
-        <form class="signin_form" method="POST" action="{% url auth_provider_signin provider=provider.id %}" accept-charset="utf-8">\r
-            {% csrf_token %}\r
-            {% include provider.stack_item_template %}\r
-            <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
-        </form>\r
-    {% endfor %}\r
-    <h3 class="or_label">{% trans 'Or...' %}</h3>\r
-    <form name="signin_form" id="dummy_form_unused" class="signin_form" method="POST" action="">\r
-        {% csrf_token %}\r
-        <fieldset>\r
-            {% trans 'Click' %} <a href="{% url auth_request_tempsignin %}">{% trans 'here' %}</a> {% trans "if you're having trouble signing in." %}\r
-        </fieldset>\r
-    </form>\r
-    <script type="text/html" id="simple_form_template">\r
-        <fieldset id="slot_form">\r
-              <p id="provider_name_slot">{% trans 'Enter your ' %}%%YOUR_WHAT%%</p>\r
-              <div><p><span></span>\r
-                    <input id="input_field" type="text" name="input_field" /><span></span>\r
-                    <input id="ssignin" name="ssignin" type="submit" value="Login" />\r
-              </p></div>\r
-              <input type="hidden" class="validate_email" name="validate_email" value="yes" />\r
-          </fieldset>\r
-    </script>\r
-    <script type="text/javascript">\r
-        $(function() {\r
-            var signin_url = "{% url auth_provider_signin provider='PROVIDER' %}";\r
-\r
-            function set_validate_email() {\r
-                var validate = $('#validate_email').attr('checked') ? 'yes' : 'no';\r
-                $('.validate_email').attr('value', validate);\r
-\r
-                $('.provider_direct').each(function() {\r
-                    var current_url = $(this).attr('href');\r
-                    if (!/\?validate_email\=(yes|no)$/.test(current_url)) {\r
-                        current_url += ('?validate_email=' + validate);\r
-                    } else {\r
-                        current_url = current_url.replace(/(yes|no)$/, validate);\r
-                    }\r
-\r
-                    $(this).attr('href', current_url);\r
-                })\r
-            }\r
-\r
-            $('#validate_email').change(set_validate_email);\r
-\r
-            function set_form_action(el) {\r
-                var provider = el.parents('.provider_logo').attr('name');\r
-                $('#signin_form').attr('action', signin_url.replace('PROVIDER', provider));\r
-            }\r
-\r
-            $('.provider_logo').click(function() {\r
-                $('.provider_logo').removeClass('selected');\r
-                $(this).addClass('selected');\r
-            });\r
-\r
-            $('.simple_form_provider').click(function() {\r
-                $('#signin_form_slot').html('');\r
-                var new_html = $('#simple_form_template').html()\r
-                    .replace('%%YOUR_WHAT%%', $(this).attr('alt'));\r
-                $('#signin_form_slot').html(new_html);\r
-                set_form_action($(this));\r
-                set_validate_email();\r
-            })\r
-\r
-            set_validate_email();\r
-        });\r
-    </script>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-<div class="boxC">\r
-    <h3 class="subtitle">{% trans "Why use OpenID?" %}</h3>\r
-    <ul class="list-item">\r
-        <li>\r
-               {% trans "with openid it is easier" %}\r
-        </li>\r
-        <li>\r
-               {% trans "reuse openid" %}\r
-        </li>\r
-        <li>\r
-               {% trans "openid is widely adopted" %}\r
-        </li>\r
-        <li>\r
-               {% trans "openid is supported open standard" %}\r
-        </li>\r
-\r
-    </ul>\r
-    <p class="info-box-follow-up-links">\r
-        <a href="http://openid.net/what/" target="_blank">{% trans "Find out more" %} </a><br/>\r
-        <a href="http://openid.net/get/" target="_blank">{% trans "Get OpenID" %} </a>\r
-    </p>\r
-</div>\r
-{% endblock%}\r
+{% extends "base.html" %}
+
+{% load i18n %}
+{% load extra_tags %}
+
+{% block title %}{% spaceless %}{% trans "Login" %}{% endspaceless %}{% endblock %}
+
+{% block forejs %}
+    <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/auth.css" %}"/>
+    {% for provider in all_providers %}
+        {% for location in provider.extra_css %}
+            <link rel="stylesheet" type="text/css" media="screen" href="{{ location }}"/>
+        {% endfor %}
+    {% endfor %}
+{% endblock %}
+
+{% block content %}
+    {% for provider in all_providers %}
+        {% if provider.pre_code %}
+            {{ provider.pre_code|safe }}
+        {% endif %}
+    {% endfor %}
+    <div class="headNormal">
+        {% trans "User login" %}
+    </div>
+    {% if msg %}
+        <p class="error">{{ msg }}</p>
+    {% endif %}
+    {% for provider in top_stackitem_providers %}
+        <form class="signin_form" method="POST" action="{% url "auth_provider_signin" provider=provider.id %}" accept-charset="utf-8">
+            {% csrf_token %}
+            {% include provider.stack_item_template %}
+            <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+        </form>
+    {% endfor %}
+    {% if top_stackitem_providers %}
+        <h3 class="or_label">{% trans 'Or...' %}</h3>
+    {% endif %}
+    <div style="width:600px;float:left;margin-bottom:5px;">
+    {% blocktrans %}
+        External login services use <b><a href="http://openid.net/">OpenID</a></b> technology, where your password always stays confidential between
+        you and your login provider and you don't have to remember another one.
+    {% endblocktrans %}
+    </div>
+    {% if request.user.is_anonymous %}
+        <div style="width:600px;float:left;margin-bottom:5px;">
+            <input type="checkbox" checked="checked" id="validate_email" />
+            {% trans "Validate my email after I login." %}
+        </div>
+    {% endif %}
+    <div id="bigicon_providers">
+        {% for provider in bigicon_providers %}
+            <div class="provider_logo big" name="{{ provider.id }}">
+                <div class="inner">
+                    {% ifequal provider.type "DIRECT" %}
+                        <a class="provider_direct" href="{% url "auth_provider_signin" provider=provider.id %}">
+                            <img src="{% media provider.icon %}" />
+                        </a>
+                    {% endifequal %}
+                    {% ifequal provider.type "CUSTOM" %}
+                        {% include provider.code_template %}
+                    {% endifequal %}
+                    {% ifequal provider.type "SIMPLE_FORM" %}
+                        <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />
+                    {% endifequal %}
+                </div>
+            </div>
+        {% endfor %}
+    </div>
+    <div id="smallicon_providers">
+        {% for provider in smallicon_providers %}
+            <div class="provider_logo small" name="{{ provider.id }}">
+                <div class="inner">
+                    {% ifequal provider.type "DIRECT" %}
+                        <a class="provider_direct" href="{% url "auth_provider_signin" provider=provider.id %}">
+                            <img src="{% media provider.icon %}" />
+                        </a>
+                    {% endifequal %}
+                    {% ifequal provider.type "CUSTOM" %}
+                        {% include provider.code_template %}
+                    {% endifequal %}
+                    {% ifequal provider.type "SIMPLE_FORM" %}
+                        <img alt="{{ provider.simple_form_context.your_what }}" class="simple_form_provider" src="{% media provider.icon %}" />
+                    {% endifequal %}
+                </div>
+            </div>
+        {% endfor %}
+    </div>
+    <form name="signin_form" id="signin_form" class="signin_form" method="POST" action="">
+        {% csrf_token %}
+        <div id="signin_form_slot"></div>
+        <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+    </form>
+    {% for provider in stackitem_providers %}
+        <h3 class="or_label">{% trans 'Or...' %}</h3>
+        <form class="signin_form" method="POST" action="{% url "auth_provider_signin" provider=provider.id %}" accept-charset="utf-8">
+            {% csrf_token %}
+            {% include provider.stack_item_template %}
+            <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+        </form>
+    {% endfor %}
+    <h3 class="or_label">{% trans 'Or...' %}</h3>
+    <form name="signin_form" id="dummy_form_unused" class="signin_form" method="POST" action="">
+        {% csrf_token %}
+        <fieldset>
+            {% trans 'Click' %} <a href="{% url "auth_request_tempsignin" %}">{% trans 'here' %}</a> {% trans "if you're having trouble signing in." %}
+        </fieldset>
+    </form>
+    <script type="text/html" id="simple_form_template">
+        <fieldset id="slot_form">
+              <p id="provider_name_slot">{% trans 'Enter your ' %}%%YOUR_WHAT%%</p>
+              <div><p><span></span>
+                    <input id="input_field" type="text" name="input_field" /><span></span>
+                    <input id="ssignin" name="ssignin" type="submit" value="Login" />
+              </p></div>
+              <input type="hidden" class="validate_email" name="validate_email" value="yes" />
+          </fieldset>
+    </script>
+    <script type="text/javascript">
+        $(function() {
+            var signin_url = "{% url "auth_provider_signin" provider='PROVIDER' %}";
+
+            function set_validate_email() {
+                var validate = $('#validate_email').attr('checked') ? 'yes' : 'no';
+                $('.validate_email').attr('value', validate);
+
+                $('.provider_direct').each(function() {
+                    var current_url = $(this).attr('href');
+                    if (!/\?validate_email\=(yes|no)$/.test(current_url)) {
+                        current_url += ('?validate_email=' + validate);
+                    } else {
+                        current_url = current_url.replace(/(yes|no)$/, validate);
+                    }
+
+                    $(this).attr('href', current_url);
+                })
+            }
+
+            $('#validate_email').change(set_validate_email);
+
+            function set_form_action(el) {
+                var provider = el.parents('.provider_logo').attr('name');
+                $('#signin_form').attr('action', signin_url.replace('PROVIDER', provider));
+            }
+
+            $('.provider_logo').click(function() {
+                $('.provider_logo').removeClass('selected');
+                $(this).addClass('selected');
+            });
+
+            $('.simple_form_provider').click(function() {
+                $('#signin_form_slot').html('');
+                var new_html = $('#simple_form_template').html()
+                    .replace('%%YOUR_WHAT%%', $(this).attr('alt'));
+                $('#signin_form_slot').html(new_html);
+                set_form_action($(this));
+                set_validate_email();
+            })
+
+            set_validate_email();
+        });
+    </script>
+{% endblock %}
+
+{% block sidebar %}
+<div class="boxC">
+    <h3 class="subtitle">{% trans "Why use OpenID?" %}</h3>
+    <ul class="list-item">
+        <li>
+            {% trans "with openid it is easier" %}
+        </li>
+        <li>
+            {% trans "reuse openid" %}
+        </li>
+        <li>
+            {% trans "openid is widely adopted" %}
+        </li>
+        <li>
+            {% trans "openid is supported open standard" %}
+        </li>
+
+    </ul>
+    <p class="info-box-follow-up-links">
+        <a href="http://openid.net/what/" target="_blank">{% trans "Find out more" %} </a><br/>
+        <a href="http://openid.net/get/" target="_blank">{% trans "Get OpenID" %} </a>
+    </p>
+</div>
+{% endblock%}
index 32ade899f9fab341036be8d16807bf3b5d0d02d0..3c5707f0f0956a87a223d22099ce8f089df36ce3 100644 (file)
         <p style="{{ p_style }}">
             {% blocktrans %}The following link grants you a one time access to your account at {{ app_name }}.{% endblocktrans %}
         </p>
-        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl auth_tempsignin user=recipient.id,code=temp_login_code %}">{% trans "Go to your account" %}</a></p>
+        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl "auth_tempsignin" user=recipient.id code=temp_login_code %}">{% trans "Go to your account" %}</a></p>
 
         <p style="{{ p_style }}">{% trans "If the above link is not clickable, copy and paste this url into your web browser's address bar:" %}</p>
 
-        <p style="{{ p_style }}">{% fullurl auth_tempsignin user=recipient.id,code=temp_login_code %}</p>
+        <p style="{{ p_style }}">{% fullurl "auth_tempsignin" user=recipient.id code=temp_login_code %}</p>
     {% endhtmlcontent %}
 
 {% textcontent notifications/base_text.html %}
 {% blocktrans %}The following url grants you a one time access to your account at {{ app_name }}.{% endblocktrans %}
 
-{% fullurl auth_tempsignin user=recipient.id,code=temp_login_code %}
+{% fullurl "auth_tempsignin" user=recipient.id code=temp_login_code %}
 {% endtextcontent %}
 
 {% endemail %}
index 70f740e2d8e917318b6d380a893b6725571f8bcf..3dd5951e51fe429c7bc3d80c91ed2efdd8fc5fd5 100644 (file)
@@ -1,29 +1,29 @@
-{% extends "base.html" %}\r
-\r
-{% load i18n %}\r
-{% block head %}{% endblock %}\r
-{% block title %}{% spaceless %}{% trans "Request temporary login key" %}{% endspaceless %}{% endblock %}\r
-{% block content %}\r
-<div class="headNormal">{% trans "Account: request temporary login key" %}</div>\r
-<p class="message">{% blocktrans %}\r
-    If you're experiencing problems accessing your account, or if you forgot your password,\r
-    here you can request a temporary login key. Fill out your account email and we'll send you a temporary access link that\r
-    will enable you to access your account. This token is valid only once and for a limited period of time.\r
- {% endblocktrans %}</p>\r
-<div class="aligned">\r
-    {% if form.errors %}\r
-        <ul class="errorlist">\r
-            {% for error in form.errors %}\r
-                <li>{{ error }}</li>\r
-            {% endfor %}\r
-        </ul>\r
-       {% endif %}\r
-       <form action="" method="post" accept-charset="utf-8">\r
-        {% csrf_token %}\r
-        <ul id="changepw-form" class="form-horizontal-rows">\r
-        {{form.as_ul}}\r
-        </ul>\r
-        <div class="submit-row"><input type="submit" class="submit" value="{% trans "Send link" %}" /></div>\r
-       </form>\r
-       </div>\r
+{% extends "base.html" %}
+
+{% load i18n %}
+{% block head %}{% endblock %}
+{% block title %}{% spaceless %}{% trans "Request temporary login key" %}{% endspaceless %}{% endblock %}
+{% block content %}
+<div class="headNormal">{% trans "Account: request temporary login key" %}</div>
+<p class="message">{% blocktrans %}
+    If you're experiencing problems accessing your account, or if you forgot your password,
+    here you can request a temporary login key. Fill out your account email and we'll send you a temporary access link that
+    will enable you to access your account. This token is valid only once and for a limited period of time.
+ {% endblocktrans %}</p>
+<div class="aligned">
+    {% if form.errors %}
+        <ul class="errorlist">
+            {% for error in form.errors %}
+                <li>{{ error }}</li>
+            {% endfor %}
+        </ul>
+       {% endif %}
+       <form action="" method="post" accept-charset="utf-8">
+        {% csrf_token %}
+        <ul id="changepw-form" class="form-horizontal-rows">
+        {{form.as_ul}}
+        </ul>
+        <div class="submit-row"><input type="submit" class="submit" value="{% trans "Send link" %}" /></div>
+       </form>
+       </div>
 {% endblock %}
\ No newline at end of file
index 1adcba2f87e4302603e7d2641a99113d213f3cab..9ebe7ba345184f8115f108b765c17214f9b7bde1 100644 (file)
 
         <p style="{{ p_style }}">{% trans "The following link will help us verify your email address:" %}</p>
 
-        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl auth_validate_email user=recipient.id,code=validation_code %}">{% trans "Validate my email address" %}</a></p>
+        <p style="{{ p_style }}"><a  style="{{ a_style }}" href="{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}">{% trans "Validate my email address" %}</a></p>
 
         <p style="{{ p_style }}">{% trans "If the above link is not clickable, copy and paste this url into your web browser's address bar:" %}</p>
 
-        <p style="{{ p_style }}">{% fullurl auth_validate_email user=recipient.id,code=validation_code %}</p>
+        <p style="{{ p_style }}">{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}</p>
     {% endhtmlcontent %}
 
 {% textcontent notifications/base_text.html %}
@@ -39,7 +39,7 @@
 
 {% trans "Copy and paste this url into your web browser's address bar to help us verify your email address:" %}
 
-{% fullurl auth_validate_email user=recipient.id,code=validation_code %}
+{% fullurl "auth_validate_email" user=recipient.id code=validation_code %}
 {% endtextcontent %}
 
 {% endemail %}
index 789710d2177d359b05464d750375450c1427c2cc..cb19abab1b999451b92c80bd474a85eb3de9f415 100644 (file)
@@ -1,6 +1,6 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <!-- base_content.html -->
-{% load i18n extra_tags extra_filters markup ui_registry %}
+{% load i18n extra_tags extra_filters ui_registry %}
 <html xmlns="http://www.w3.org/1999/xhtml">
     <head>{% block after_head_js %}{% endblock %}
         <title>{% block fulltitle %}{% block title %}{% endblock %} - {{ settings.APP_SHORT_NAME }}{% endblock %}</title>
@@ -14,7 +14,7 @@
         <link rel="shortcut icon" href="{{ settings.APP_FAVICON }}" />
         <link href="{% media  "/media/style/style.css" %}" rel="stylesheet" type="text/css" />
         {% if settings.USE_CUSTOM_CSS|or_preview:request %}
-        <link href="{% url custom_css %}" rel="stylesheet" type="text/css" />
+        <link href="{% url "custom_css" %}" rel="stylesheet" type="text/css" />
         {% endif %}
         <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/base/jquery-ui.css" />
         <!--[if IE 6]>
@@ -44,7 +44,7 @@
                 cancel: "{% trans "Cancel" %}",
                 close: "{% trans "Close" %}",
                 ok: "{% trans "Ok" %}",
-                matching_tags_url: "{% url matching_tags %}",
+                matching_tags_url: "{% url "matching_tags" %}",
                 word: "{% trans "word" %}",
                 words: "{% trans "words" %}",
                 character: "{% trans "character" %}",
@@ -69,7 +69,7 @@
             {{ settings.CUSTOM_HEAD|or_preview:request|safe }}
         {% endif %}
         {% block forejs %}{% endblock %}
-        <link rel="search" type="application/opensearchdescription+xml" href="{% url opensearch %}" title="{{ settings.APP_SHORT_NAME }} Search" />
+        <link rel="search" type="application/opensearchdescription+xml" href="{% url "opensearch" %}" title="{{ settings.APP_SHORT_NAME }} Search" />
         {% loadregistry head_content %}{% endloadregistry %}
     </head>
     <body>
index 2e8af8d335da9b09b9b1aebd229dc690527de30c..7d1c36ee82c082e3c81502f199a4b5da0f0e0b71 100644 (file)
@@ -20,7 +20,7 @@
     <strong>{{ question.get_question_title }}</strong></a>
     </p>   
     
-    <form id="fmclose" action="{% url close question.id %}" method="post" >
+    <form id="fmclose" action="{% url "close" question.id %}" method="post" >
         {% csrf_token %}
         <p>
             <strong>{% trans "Reasons" %}:</strong> {{ form.reason }}
index 690e9439a73307315470d24b7250202149937922..ce51d02131c4b745119438421c14e702bf1b4a06 100644 (file)
@@ -11,7 +11,7 @@
 {% trans "Give us your feedback!" %}
 </div>
 <div class="content">
-    <form method="post" action="{% url feedback %}" accept-charset="utf-8">
+    <form method="post" action="{% url "feedback" %}" accept-charset="utf-8">
         {% csrf_token %}
         {% if user.is_authenticated %}
             <p class="message">
index f5090aa6322acea722c145db93539cdf165e76dc..dc00a2f3d50116139b0230462737cf2e319d46de 100644 (file)
@@ -6,7 +6,7 @@
         {% loadregistry footer_links %}<span class="link-separator"> |</span>{% endloadregistry %}
     </div>
   <p>
-     <a href="http://osqa.net" target="_blank" title="OSQA {{ settings.OSQA_VERSION }} ({{ settings.SVN_REVISION }})">
+     <a href="http://osqa.net" target="_blank" title="OSQA {{ settings.OSQA_VERSION }} ({{ settings.VCS_REVISION }})">
         powered by OSQA
      </a>
   </p>
index 0e3a73f7d0805b9ef9fc76770bf9fa60e9670149..6d2c849622ad5aa0f6df4d680501c3e611e4bc18 100644 (file)
@@ -1,10 +1,10 @@
 <!-- template header.html -->
-{% load extra_tags ui_registry i18n extra_filters markup %}
+{% load extra_tags ui_registry i18n extra_filters %}
 
        <div id="roof">
          
                <div id="logo">
-                       <a href="{% url index %}">
+                       <a href="{% url "index" %}">
                                <img src="{{ settings.APP_LOGO }}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
                        </a>
                </div>
         {% loopregistry page_top_tabs %}{% spaceless %}
             <a id="nav_{{ tab_name }}"{% ifequal tab tab_name %} class="on"{% endifequal %} href="{{ tab_url }}" >{{ tab_title }}</a>
         {% endspaceless %}{% endloopregistry %}
-        <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
+        <a id="nav_ask" href="{% url "ask" %}" class="special">{% trans "ask a question" %}</a>
     </div>
   </div>
 
   <div class="clear"></div>
   
        <div id="searchBar">
-    <form action="{% url search %}" method="get">
+    <form action="{% url "search" %}" method="get">
         {% csrf_token %}
         <div>
             <input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" />
index 94552e60490184e8a83b847fc40643cdb6a5ac1d..dce3ca189fc98b8d4ff47e4f0de74e94159ae7bc 100644 (file)
@@ -1,30 +1,30 @@
-{% extends "questions.html" %}\r
-<!-- index.html -->\r
-{% load general_sidebar_tags %}\r
-{% load question_list_tags %}\r
-{% load i18n %}\r
-{% block fulltitle %}{{ settings.APP_TITLE }}{% endblock %}\r
-{% block sidebar %}\r
-    {% if not request.user.is_authenticated %}\r
-        {% if settings.SHOW_WELCOME_BOX %}\r
-            <div class="boxA">\r
-                <h3>{% trans "welcome to " %}{{ settings.APP_SHORT_NAME }}</h3>\r
-                <div class="body">\r
-                  {{ settings.APP_INTRO|safe }}\r
-                  <div class="more"><a href="{% url about %}">{% trans "about" %} </a></div>\r
-                  <div class="more"><a href="{% url faq %}">{% trans "faq" %} </a></div>\r
-                </div>\r
-            </div>\r
-        {% endif %}\r
-    {% endif %}\r
-    {% include "question_list/count.html" %}\r
-    {% sidebar_upper %}\r
-    {% if request.user.is_authenticated %}\r
-        {% tag_selector %}\r
-    {% endif %}\r
-    {% sidebar_lower %}\r
-    {% recent_tags %}\r
-    {% recent_awards %}\r
-{% endblock %}\r
-<!-- index.html -->\r
-\r
+{% extends "questions.html" %}
+<!-- index.html -->
+{% load general_sidebar_tags %}
+{% load question_list_tags %}
+{% load i18n %}
+{% block fulltitle %}{{ settings.APP_TITLE }}{% endblock %}
+{% block sidebar %}
+    {% if not request.user.is_authenticated %}
+        {% if settings.SHOW_WELCOME_BOX %}
+            <div class="boxA">
+                <h3>{% trans "welcome to " %}{{ settings.APP_SHORT_NAME }}</h3>
+                <div class="body">
+                  {{ settings.APP_INTRO|safe }}
+                  <div class="more"><a href="{% url "about" %}">{% trans "about" %} </a></div>
+                  <div class="more"><a href="{% url "faq" %}">{% trans "faq" %} </a></div>
+                </div>
+            </div>
+        {% endif %}
+    {% endif %}
+    {% include "question_list/count.html" %}
+    {% sidebar_upper %}
+    {% if request.user.is_authenticated %}
+        {% tag_selector %}
+    {% endif %}
+    {% sidebar_lower %}
+    {% recent_tags %}
+    {% recent_awards %}
+{% endblock %}
+<!-- index.html -->
+
index 650ba044fc2dcd2cfa5c5f711481fabccd3d25c1..9a9994c98a532bdc30dc5eaab4bba29f7785e47a 100644 (file)
@@ -7,7 +7,7 @@
 {% block forejs %}
     <script type="text/javascript">
     $().ready(function(){
-        $('#btLogout').bind('click', function(){ window.location.href='{% url user_signout %}?next={{ next }}'; });
+        $('#btLogout').bind('click', function(){ window.location.href='{% url "user_signout" %}?next={{ next }}'; });
     });
     </script>
 {% endblock %}
index 653f8b181e2ea7d581111b946372be97e3e7aae9..94f0f541ae52ff2c73ea25b14c883ea40e87649e 100644 (file)
@@ -1,22 +1,22 @@
-{% load i18n %}\r
-\r
-{% if can_accept %}\r
-    <a id="accept-answer-{{ answer.id }}" class="ajax-command accept-answer{% if answer.nis.accepted %} on{% endif %}"\r
-      title=" {% if answer.nis.accepted %}\r
-              {% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}\r
-              {% else %}\r
-                {% trans "mark this answer as the accepted answer" %}\r
-              {% endif %}"\r
-              bn:on="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"\r
-              bn:off="{% trans "mark this answer as the accepted answer" %}"\r
-       href="{% url accept_answer id=answer.id %}" rel="nofollow"> \r
-    </a>\r
-{% else %}\r
-    {% if answer.nis.accepted %}\r
-      <a class="accept-answer on"\r
-        title="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"\r
-        href="{% url accept_answer id=answer.id %}" rel="nofollow"> \r
-      </a>\r
-    {% endif %}\r
-{% endif %}\r
-\r
+{% load i18n %}
+
+{% if can_accept %}
+    <a id="accept-answer-{{ answer.id }}" class="ajax-command accept-answer{% if answer.nis.accepted %} on{% endif %}"
+      title=" {% if answer.nis.accepted %}
+              {% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}
+              {% else %}
+                {% trans "mark this answer as the accepted answer" %}
+              {% endif %}"
+              bn:on="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"
+              bn:off="{% trans "mark this answer as the accepted answer" %}"
+       href="{% url "accept_answer" id=answer.id %}" rel="nofollow">
+    </a>
+{% else %}
+    {% if answer.nis.accepted %}
+      <a class="accept-answer on"
+        title="{% blocktrans with answer.nstate.accepted.by.username as who %}{{ who }} has selected this answer as the correct answer{% endblocktrans %}"
+        href="{% url "accept_answer" id=answer.id %}" rel="nofollow">
+      </a>
+    {% endif %}
+{% endif %}
+
index c9f95e1b77b8685c0e890e69f2d01d04a3880f22..a1306072250f4024d1b486f1ddf92e72d2e3cb4d 100644 (file)
@@ -4,7 +4,7 @@
 <div class="clear"></div>
 <div id="comment-{{ post.id }}-form-container" class="comment-form-container">
     {% if can_comment %}
-    <form id="comment-{{ post.id }}-form" method="post" action="{% url comment id=post.id %}" accept-charset="utf-8">
+    <form id="comment-{{ post.id }}-form" method="post" action="{% url "comment" id=post.id %}" accept-charset="utf-8">
         {% csrf_token %}
         <div class="comment-form-widgets-container">
             <textarea name="comment" class="commentBox" id="comment"></textarea>
index a84ef89d5583d46b518aa6a61ee647e75434f683..4959db54ba94a6577dc5a1c4974a5c98f8144ac5 100644 (file)
@@ -1,56 +1,56 @@
-{% load extra_tags %}\r
-{% load i18n %}\r
-\r
-{% if show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}\r
-\r
-<div class="comments-container" id="comments-container-{{ post.id }}">\r
-    {% for comment in comments %}\r
-        <a name="{{ comment.id }}"></a>\r
-        <div class="comment{% if not comment.top_scorer %} not_top_scorer{% endif %}" id="comment-{{comment.id}}">\r
-            <div id="post-{{ comment.id }}-score" class="comment-score">{% if comment.score %}{{ comment.score }}{% endif %}</div>\r
-            <div class="comment-text">{{ comment.comment }}</div>\r
-            <div class="comment-info" id="comment-{{comment.id}}-info">\r
-                {% if comment.can_like %}\r
-                    <a id="post-{{ comment.id }}-upvote" href="{% url like_comment id=comment.id %}"\r
-                     title="{% trans "I like this comment (click again to cancel)" %}" class="ajax-command comment-like{% if comment.likes %} on{% endif %}"\r
-                    rel="nofollow"> </a>\r
-                {% endif %}\r
-                {% if comment.can_edit %}\r
-                    <a id="comment-{{ comment.id }}-edit" href="{% url node_markdown id=comment.id %}" title="{% trans "Edit comment" %}"\r
-                        class="comment-edit" rel="nofollow"> </a>\r
-                {% endif %}\r
-                {% if comment.can_delete %}\r
-                    <a id="comment-{{ comment.id }}-delete" href="{% url delete_comment id=comment.id %}" title="{% trans "Delete comment" %}"\r
-                        class="ajax-command comment-delete confirm" rel="nofollow"> </a>\r
-                {% endif %}\r
-                {% if comment.can_convert %}\r
-                    <a rel="nofollow" id="comment-{{ comment.id }}-convert" href="{% url convert_comment id=comment.id %}" title="{% trans "Convert comment to answer" %}"\r
-                        class="ajax-command comment-convert confirm" rel="nofollow"> </a>\r
-                    <a rel="nofollow" id="comment-{{ comment.id }}-convert-to-question" href="{% url convert_to_question id=comment.id %}?node_type=comment" title="{% trans "Convert comment to question" %}"\r
-                        class="comment-convert-to-question" rel="nofollow"> </a>\r
-                {% endif %}\r
-\r
-                {% if comment.additional_controls %}\r
-                    {{ comment.additional_controls }}\r
-                {% endif %}\r
-\r
-                <span class="comment-age">({% diff_date comment.added_at %})</span>\r
-                <a class="comment-user userinfo" href="{{comment.user.get_profile_url}}">{{comment.user.decorated_name}}</a>\r
-                {% if show_gravatar %}{% gravatar comment.user 18 %}{% endif %}\r
-            </div>\r
-        </div>\r
-    {% endfor %}\r
-</div>\r
-<div id="comment-tools-{{ post.id }}" class="comment-tools">\r
-    {% ifnotequal showing total %}\r
-        <span class="comments-showing">\r
-            {% blocktrans %}showing {{ showing }} of {{ total }}{% endblocktrans %}\r
-        </span>\r
-        <a href="#" class="show-all-comments-link">{% blocktrans %}show {{ more_comments_count }} more comments{% endblocktrans %}</a>\r
-    {% endifnotequal %}\r
-    {% if can_comment %}\r
-        <a href="#" class="add-comment-link">{% trans "add new comment" %}</a>\r
-    {% endif %}\r
-</div>\r
-\r
-{% if not show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}\r
+{% load extra_tags %}
+{% load i18n %}
+
+{% if show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}
+
+<div class="comments-container" id="comments-container-{{ post.id }}">
+    {% for comment in comments %}
+        <a name="{{ comment.id }}"></a>
+        <div class="comment{% if not comment.top_scorer %} not_top_scorer{% endif %}" id="comment-{{comment.id}}">
+            <div id="post-{{ comment.id }}-score" class="comment-score">{% if comment.score %}{{ comment.score }}{% endif %}</div>
+            <div class="comment-text">{{ comment.comment }}</div>
+            <div class="comment-info" id="comment-{{comment.id}}-info">
+                {% if comment.can_like %}
+                    <a id="post-{{ comment.id }}-upvote" href="{% url "like_comment" id=comment.id %}"
+                     title="{% trans "I like this comment (click again to cancel)" %}" class="ajax-command comment-like{% if comment.likes %} on{% endif %}"
+                    rel="nofollow"> </a>
+                {% endif %}
+                {% if comment.can_edit %}
+                    <a id="comment-{{ comment.id }}-edit" href="{% url "node_markdown" id=comment.id %}" title="{% trans "Edit comment" %}"
+                        class="comment-edit" rel="nofollow"> </a>
+                {% endif %}
+                {% if comment.can_delete %}
+                    <a id="comment-{{ comment.id }}-delete" href="{% url "delete_comment" id=comment.id %}" title="{% trans "Delete comment" %}"
+                        class="ajax-command comment-delete confirm" rel="nofollow"> </a>
+                {% endif %}
+                {% if comment.can_convert %}
+                    <a rel="nofollow" id="comment-{{ comment.id }}-convert" href="{% url "convert_comment" id=comment.id %}" title="{% trans "Convert comment to answer" %}"
+                        class="ajax-command comment-convert confirm" rel="nofollow"> </a>
+                    <a rel="nofollow" id="comment-{{ comment.id }}-convert-to-question" href="{% url "convert_to_question" id=comment.id %}?node_type=comment" title="{% trans "Convert comment to question" %}"
+                        class="comment-convert-to-question" rel="nofollow"> </a>
+                {% endif %}
+
+                {% if comment.additional_controls %}
+                    {{ comment.additional_controls }}
+                {% endif %}
+
+                <span class="comment-age">({% diff_date comment.added_at %})</span>
+                <a class="comment-user userinfo" href="{{comment.user.get_profile_url}}">{{comment.user.decorated_name}}</a>
+                {% if show_gravatar %}{% gravatar comment.user 18 %}{% endif %}
+            </div>
+        </div>
+    {% endfor %}
+</div>
+<div id="comment-tools-{{ post.id }}" class="comment-tools">
+    {% ifnotequal showing total %}
+        <span class="comments-showing">
+            {% blocktrans %}showing {{ showing }} of {{ total }}{% endblocktrans %}
+        </span>
+        <a href="#" class="show-all-comments-link">{% blocktrans %}show {{ more_comments_count }} more comments{% endblocktrans %}</a>
+    {% endifnotequal %}
+    {% if can_comment %}
+        <a href="#" class="add-comment-link">{% trans "add new comment" %}</a>
+    {% endif %}
+</div>
+
+{% if not show_latest_comments_first %}{% include "node/comment_skeleton.html" %}{% endif %}
index 6cfaac9ce0dfe67cc6602bb6398f7fff9bfa332e..6540241ad530672d062bb30810fdaacad5f65381 100644 (file)
@@ -1,8 +1,8 @@
-{% load i18n %}\r
-\r
-<a id="favorite-mark" title="{% trans "mark/unmark this question as favorite (click again to cancel)" %}"\r
-    class="ajax-command favorite-mark {% if favorited %} on{% endif %}"\r
-    href="{% url mark_favorite id=question.id %}" rel="nofollow"> </a>\r
-<div id="favorite-count" class="favorite-count">\r
-   {% if favorite_count %}{{ favorite_count }}{% endif %}\r
-</div>\r
+{% load i18n %}
+
+<a id="favorite-mark" title="{% trans "mark/unmark this question as favorite (click again to cancel)" %}"
+    class="ajax-command favorite-mark {% if favorited %} on{% endif %}"
+    href="{% url "mark_favorite" id=question.id %}" rel="nofollow"> </a>
+<div id="favorite-count" class="favorite-count">
+   {% if favorite_count %}{{ favorite_count }}{% endif %}
+</div>
index bbe1e22effa35c85664a322183ebbc9bc706b776..3480a36ea138314d20559a0424ad12b5f12dd889 100644 (file)
@@ -1,22 +1,22 @@
-{% load i18n %}\r
-{% spaceless %}\r
-{% for control in controls %}\r
-    <span class="action-link">\r
-        <a rel="nofollow" title="{{ control.title }}" class="{{ control.classes }}" href="{{ control.url }}">{{ control.text }}</a>\r
-    </span>\r
-    {% ifnotequal controls|last control %}\r
-        <span class="action-link-separator">|</span>\r
-    {% endifnotequal %}\r
-{% endfor %}\r
-{% if menu|length %}\r
-    <span class="action-link-separator">|</span>\r
-    <span id="node-{{ post.id }}-menu" class="context-menu">\r
-        <span id="node-{{ post.id }}-menu-trigger" class="action-link context-menu-trigger">{% trans "more" %} &#9660;</span>\r
-        <ul id="node-{{ post.id }}-menu-dropdown" class="context-menu-dropdown">\r
-            {% for item in menu %}\r
-            <li class="item"><a rel="nofollow" class="{{ item.classes }}" href="{{ item.url }}" title="{{ item.title }}" >{{ item.text }}</a></li>\r
-            {% endfor %}\r
-        </ul>\r
-    </span>\r
-{% endif %}\r
+{% load i18n %}
+{% spaceless %}
+{% for control in controls %}
+    <span class="action-link">
+        <a rel="nofollow" title="{{ control.title }}" class="{{ control.classes }}" href="{{ control.url }}">{{ control.text }}</a>
+    </span>
+    {% ifnotequal controls|last control %}
+        <span class="action-link-separator">|</span>
+    {% endifnotequal %}
+{% endfor %}
+{% if menu|length %}
+    <span class="action-link-separator">|</span>
+    <span id="node-{{ post.id }}-menu" class="context-menu">
+        <span id="node-{{ post.id }}-menu-trigger" class="action-link context-menu-trigger">{% trans "more" %} &#9660;</span>
+        <ul id="node-{{ post.id }}-menu-dropdown" class="context-menu-dropdown">
+            {% for item in menu %}
+            <li class="item"><a rel="nofollow" class="{{ item.classes }}" href="{{ item.url }}" title="{{ item.title }}" >{{ item.text }}</a></li>
+            {% endfor %}
+        </ul>
+    </span>
+{% endif %}
 {% endspaceless %}
\ No newline at end of file
index 1635d7d6726f4dedbea54610a06c714685ed74e7..b1cfb8ceb29122db57263d731e2b2805977a18da 100644 (file)
@@ -1,14 +1,14 @@
-{% load i18n %}\r
-\r
-{% trans "Please select a reason bellow or use the text box to input your own reason." %}\r
-<select class="prompt-examples">\r
-    {% for type in types %}\r
-        <option value="{{ type }}">{{ type }}</option>\r
-    {% endfor %}\r
-</select>\r
-<textarea name="prompt">{{ types|first }}</textarea>\r
-<script>\r
-$('.prompt-examples').change(function() {\r
-    $('textarea[name=prompt]').val($(this).val())            \r
-})\r
+{% load i18n %}
+
+{% trans "Please select a reason bellow or use the text box to input your own reason." %}
+<select class="prompt-examples">
+    {% for type in types %}
+        <option value="{{ type }}">{{ type }}</option>
+    {% endfor %}
+</select>
+<textarea name="prompt">{{ types|first }}</textarea>
+<script>
+$('.prompt-examples').change(function() {
+    $('textarea[name=prompt]').val($(this).val())
+})
 </script>
\ No newline at end of file
index ac3df282bc898979b5e7bffeffaf06697d82728d..5dc5e4f08c2765c5d966d6f2632e04984f482258 100644 (file)
@@ -1,9 +1,9 @@
-{% load extra_tags %}\r
-<div class='post-update-info'>\r
-    <p style="line-height:12px;">\r
-        <strong>{% diff_date revision.revised_at %}</strong>\r
-    </p>\r
-    <a href="{{ revision.author.get_profile_url }}">{% gravatar revision.author 32 %}</a>\r
-    <p><a href="{{ revision.author.get_profile_url }}">{{ revision.author.username }}</a><br/>\r
-    {% get_score_badge revision.author %}</p>\r
+{% load extra_tags %}
+<div class='post-update-info'>
+    <p style="line-height:12px;">
+        <strong>{% diff_date revision.revised_at %}</strong>
+    </p>
+    <a href="{{ revision.author.get_profile_url }}">{% gravatar revision.author 32 %}</a>
+    <p><a href="{{ revision.author.get_profile_url }}">{{ revision.author.username }}</a><br/>
+    {% get_score_badge revision.author %}</p>
 </div>
\ No newline at end of file
index d6ac677509e109d3503ac56af1dada9c956c18b3..5e77e6aee1ff62c810daeccaa6c8f5a76c0d731b 100644 (file)
@@ -1,11 +1,11 @@
-{% spaceless %}\r
-    {% if title %}<h1>{{ title }}</h1>{% endif %}\r
-    <div class="text">{{ html }}</div>\r
-    {% if tags %}\r
-        <div class="tags">\r
-            {% for tag in tags %}\r
-            <a class="post-tag tag-link-{{ tag }}">{{ tag }}</a>\r
-            {% endfor %}\r
-        </div>\r
-    {% endif %}\r
+{% spaceless %}
+    {% if title %}<h1>{{ title }}</h1>{% endif %}
+    <div class="text">{{ html }}</div>
+    {% if tags %}
+        <div class="tags">
+            {% for tag in tags %}
+            <a class="post-tag tag-link-{{ tag }}">{{ tag }}</a>
+            {% endfor %}
+        </div>
+    {% endif %}
 {% endspaceless %}
\ No newline at end of file
index 9b95d607bf7b49232c66677c7b8fc72b3a2867ff..12ecfe412add7453d5dc4d9f93f9545b978a0597 100644 (file)
@@ -1,12 +1,12 @@
-{% load i18n %}\r
-\r
-<a id="post-{{ post.id }}-upvote" title="{% trans "I like this post (click again to cancel)" %}"\r
-    class="ajax-command post-vote up {% ifequal user_vote "up" %} on{% endifequal %}"\r
-     href="{% url vote_post id=post.id,vote_type='up' %}" rel="nofollow"> </a>\r
-<div id="post-{{ post.id }}-score" class="post-score"\r
-    title="{% trans "current number of votes" %}">\r
-    {{ post.score }}\r
-</div>\r
-<a id="post-{{ post.id }}-downvote" title="{% trans "I dont like this post (click again to cancel)" %}"\r
-    class="ajax-command post-vote down{% ifequal user_vote "down" %} on{% endifequal %}"\r
-     href="{% url vote_post id=post.id,vote_type='down' %}" rel="nofollow"> </a>
\ No newline at end of file
+{% load i18n %}
+
+<a id="post-{{ post.id }}-upvote" title="{% trans "I like this post (click again to cancel)" %}"
+    class="ajax-command post-vote up {% ifequal user_vote "up" %} on{% endifequal %}"
+     href="{% url "vote_post" id=post.id vote_type='up' %}" rel="nofollow"> </a>
+<div id="post-{{ post.id }}-score" class="post-score"
+    title="{% trans "current number of votes" %}">
+    {{ post.score }}
+</div>
+<a id="post-{{ post.id }}-downvote" title="{% trans "I dont like this post (click again to cancel)" %}"
+    class="ajax-command post-vote down{% ifequal user_vote "down" %} on{% endifequal %}"
+     href="{% url "vote_post" id=post.id vote_type='down' %}" rel="nofollow"> </a>
index d27b2161afb6e184f65d6726c28174d5e05f8b93..d301c3636b007647042c0ed045f6c4f065325c9b 100644 (file)
@@ -1,58 +1,56 @@
-{% extends "base.html" %}\r
-\r
-{% load i18n extra_tags general_sidebar_tags %}\r
-\r
-{% block title %}{% trans "Site Administration" %}{% endblock %}\r
-\r
-{% block forejs %}\r
-    <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/admin.css" %}"/>\r
-    <script type="text/javascript" src="{% media "/media/js/osqa.admin.js" %}"></script>\r
-    {% block adminjs %}{% endblock %}\r
-{% endblock %}\r
-\r
-{% block content %}\r
-    <div class="headNormal">\r
-           {% trans "OSQA administration area" %} - {% block subtitle %}{% endblock %}\r
-    </div>\r
-    <div id="admin_page_description">\r
-        {% block description %}{% endblock %}\r
-    </div>\r
-    <div>\r
-        {% block admincontent %}\r
-        {% endblock %}\r
-    </div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-    {% if hide_navigation %}\r
-\r
-    {% else %}\r
-    <div class="boxC">\r
-        <a href="{% url admin_switch_interface %}?to=djstyle">{% trans "Switch to django style interface" %}</a>\r
-        <h3 class="subtitle">{% trans "Administration menu" %}</h3>\r
-        <ul>\r
-        {% for set in allsets.values %}\r
-            <li><a href="{% url admin_set set.name %}">{{ set.title }}</a></li>\r
-        {% endfor %}\r
-        \r
-        {% for set in othersets %}\r
-            <li>\r
-                <a href="{% url admin_set set.name %}">{{ set.title }}</a>\r
-            </li>\r
-        {% endfor %}\r
-        \r
-        <li><a href="{% url admin_maintenance %}">{% trans "Maintenance mode" %}</a></li>\r
-        <li><a href="{% url admin_flagged_posts %}">{% trans "Flagged Posts" %}</a></li>\r
-        {% for name,tool in tools %}\r
-            <li><a href="{% url admin_tools name %}">{{ tool }}</a></li>\r
-        {% endfor %}\r
-        </ul>\r
-    </div>\r
-    {% if markdown %}\r
-        {% markdown_help %}\r
-    {% endif %}\r
-\r
-    {% endif %}\r
-{% endblock %}\r
-\r
-                \r
+{% extends "base.html" %}
+
+{% load i18n extra_tags general_sidebar_tags %}
+
+{% block title %}{% trans "Site Administration" %}{% endblock %}
+
+{% block forejs %}
+    <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/admin.css" %}"/>
+    <script type="text/javascript" src="{% media "/media/js/osqa.admin.js" %}"></script>
+    {% block adminjs %}{% endblock %}
+{% endblock %}
+
+{% block content %}
+    <div class="headNormal">
+        {% trans "OSQA administration area" %} - {% block subtitle %}{% endblock %}
+    </div>
+    <div id="admin_page_description">
+        {% block description %}{% endblock %}
+    </div>
+    <div>
+        {% block admincontent %}
+        {% endblock %}
+    </div>
+{% endblock %}
+
+{% block sidebar %}
+    {% if hide_navigation %}
+
+    {% else %}
+    <div class="boxC">
+        <a href="{% url "admin_switch_interface" %}?to=djstyle">{% trans "Switch to django style interface" %}</a>
+        <h3 class="subtitle">{% trans "Administration menu" %}</h3>
+        <ul>
+        {% for set in allsets.values %}
+            <li><a href="{% url "admin_set" set.name %}">{{ set.title }}</a></li>
+        {% endfor %}
+
+        {% for set in othersets %}
+            <li>
+                <a href="{% url "admin_set" set.name %}">{{ set.title }}</a>
+            </li>
+        {% endfor %}
+
+        <li><a href="{% url "admin_maintenance" %}">{% trans "Maintenance mode" %}</a></li>
+        <li><a href="{% url "admin_flagged_posts" %}">{% trans "Flagged Posts" %}</a></li>
+        {% for name,tool in tools %}
+            <li><a href="{% url "admin_tools" name %}">{{ tool }}</a></li>
+        {% endfor %}
+        </ul>
+    </div>
+    {% if markdown %}
+        {% markdown_help %}
+    {% endif %}
+
+    {% endif %}
+{% endblock %}
\ No newline at end of file
index ec56e7808ac503d66682edee0961e5ad4f84cdb3..f5586a85deeefaab3e8c9eca0671b471e2527d4e 100644 (file)
                         {% endifequal %}
                     {% endifequal %}
                     {% ifnotequal settings_pack "default" %}
-                        <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url admin_go_defaults %}';">{% trans "revert to defaults" %}</button>
+                        <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url "admin_go_defaults" %}';">{% trans "revert to defaults" %}</button>
                     {% endifnotequal %}
                     {% ifnotequal settings_pack "bootstrap" %}
-                        <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url admin_go_bootstrap %}';">{% trans "go bootstrap" %}</button>
+                        <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url "admin_go_bootstrap" %}';">{% trans "go bootstrap" %}</button>
                     {% endifnotequal %}
                 </td>
             </tr>
index 2f771921d2267c5ab26c711797fa1d0c44229aa7..32a87bc985e1aab890c019f6d0f5952a43c421f3 100644 (file)
@@ -1,4 +1,4 @@
-{% load extra_tags extra_filters i18n %}
+{% load extra_tags extra_filters i18n admin_static %}
 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
@@ -6,10 +6,10 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-    <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/base.css" type="text/css"/>
-    <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/forms.css" type="text/css"/>
-    <link rel="stylesheet" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/changelists.css" type="text/css"/>
-    <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{{ settings.ADMIN_MEDIA_PREFIX }}css/ie.css" /><![endif]-->
+    <link rel="stylesheet" href="{% static 'admin/css/base.css' %}" type="text/css"/>
+    <link rel="stylesheet" href="{% static 'admin/css/forms.css' %}" type="text/css"/>
+    <link rel="stylesheet" href="{% static 'admin/css/changelists.css' %}" type="text/css"/>
+    <!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="{% static 'admin/css/ie.css' %}" /><![endif]-->
     <link rel="stylesheet" type="text/css" media="screen" href="{% media "/media/style/djstyle_admin.css" %}"/>
     <script src="http://www.google.com/jsapi" type="text/javascript"></script>
     <script type="text/javascript">
             <div id="user-tools">
                 {% trans "Welcome," %}
                 <strong>{{ request.user.username }}</strong>.
-                <a href="{% url admin_switch_interface %}?to=default">{% trans "To standard interface" %}</a>
-                / <a href="{% url index %}">{% trans "Back to home page" %}</a>
-                / <a href="{% url logout %}">{% trans "Log out" %}</a>
+                <a href="{% url "admin_switch_interface" %}?to=default">{% trans "To standard interface" %}</a>
+                / <a href="{% url "index" %}">{% trans "Back to home page" %}</a>
+                / <a href="{% url "logout" %}">{% trans "Log out" %}</a>
             </div>
         </div>
         <div class="breadcrumbs">
-            <a href="{% url index %}">{% trans "Home" %}</a> &gt;
-            <a href="{% url admin_index %}">{% trans "Dashboard" %}</a> &gt;
+            <a href="{% url "index" %}">{% trans "Home" %}</a> &gt;
+            <a href="{% url "admin_index" %}">{% trans "Dashboard" %}</a> &gt;
             {% block pagename %}{% endblock %} - 
             {% block description %}{% endblock %}
         </div>
@@ -60,7 +60,7 @@
                 <div id="changes-box" class="module">
                     <h2>{% trans "Unpublished changes" %}</h2>
                     <p>
-                        <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" />
+                        <img src="{% static 'admin/img/admin/icon_alert.gif' %}" />
                         {% trans "Items marked with this icon have unpublished changes." %}
                     </p>
                 </div>
                 <div id="basic-sets-menu" class="module">
                     <h2>{% trans "Basic settings" %}</h2>
                     <ul>
-                        <li><a href="{% url admin_set allsets.basic.name %}">{{ allsets.basic.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.users.name %}">{{ allsets.users.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.email.name %}">{{ allsets.email.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.paths.name %}">{{ allsets.paths.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.urls.name %}">{{ allsets.urls.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.extkeys.name %}">{{ allsets.extkeys.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.basic.name %}">{{ allsets.basic.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.users.name %}">{{ allsets.users.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.email.name %}">{{ allsets.email.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.paths.name %}">{{ allsets.paths.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.urls.name %}">{{ allsets.urls.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.extkeys.name %}">{{ allsets.extkeys.title }}</a></li>
                     </ul>
                 </div>
                 <div id="workflow-sets-menu" class="module">
                     <h2>{% trans "Workflow settings" %}</h2>
                     <ul>
-                        <li><a href="{% url admin_set allsets.repgain.name %}">{{ allsets.repgain.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.minrep.name %}">{{ allsets.minrep.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.voting.name %}">{{ allsets.voting.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.accept.name %}">{{ allsets.accept.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.badges.name %}">{{ allsets.badges.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.repgain.name %}">{{ allsets.repgain.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.minrep.name %}">{{ allsets.minrep.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.voting.name %}">{{ allsets.voting.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.accept.name %}">{{ allsets.accept.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.badges.name %}">{{ allsets.badges.title }}</a></li>
                     </ul>
                 </div>
                 <div id="forum-sets-menu" class="module">
                     <h2>{% trans "Forum settings" %}</h2>
                     <ul>
-                        <li><a href="{% url admin_set allsets.form.name %}">{{ allsets.form.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.view.name %}">{{ allsets.view.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.moderation.name %}">{{ allsets.moderation.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.form.name %}">{{ allsets.form.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.view.name %}">{{ allsets.view.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.moderation.name %}">{{ allsets.moderation.title }}</a></li>
                     </ul>
                 </div>
                 <div id="pages-sets-menu" class="module">
                     <h2>{% trans "Static content" %}</h2>
                     <ul>
-                        <li><a href="{% url admin_static_pages %}">{% trans "Custom Pages" %}</a></li>
-                        <li><a href="{% url admin_set allsets.about.name %}">{{ allsets.about.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.faq.name %}">{{ allsets.faq.title }}</a></li>
-                        <li><a href="{% url admin_set allsets.sidebar.name %}">{{ allsets.sidebar.title }}</a></li>
+                        <li><a href="{% url "admin_static_pages" %}">{% trans "Custom Pages" %}</a></li>
+                        <li><a href="{% url "admin_set" allsets.about.name %}">{{ allsets.about.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.faq.name %}">{{ allsets.faq.title }}</a></li>
+                        <li><a href="{% url "admin_set" allsets.sidebar.name %}">{{ allsets.sidebar.title }}</a></li>
                         <li>
-                            <a href="{% url admin_set allsets.css.name %}">{{ allsets.css.title }}</a>
-                            {% if "css"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+                            <a href="{% url "admin_set" allsets.css.name %}">{{ allsets.css.title }}</a>
+                            {% if "css"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
                         </li>
                         <li>
-                            <a href="{% url admin_set allsets.headandfoot.name %}">{{ allsets.headandfoot.title }}</a>
-                            {% if "headandfoot"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+                            <a href="{% url "admin_set" allsets.headandfoot.name %}">{{ allsets.headandfoot.title }}</a>
+                            {% if "headandfoot"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
                         </li>
                         <li>
-                            <a href="{% url admin_set allsets.head.name %}">{{ allsets.head.title }}</a>
-                            {% if "head"|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+                            <a href="{% url "admin_set" allsets.head.name %}">{{ allsets.head.title }}</a>
+                            {% if "head"|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
                         </li>
                     </ul>
                 </div>
                     <ul>
                     {% for set in othersets %}
                         <li>
-                            <a href="{% url admin_set set.name %}">{{ set.title }}</a>
-                            {% if set.name|contained_in:unsaved %}<img width="12" height="12" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_alert.gif" alt="{% trans "Unsaved changes" %}" />{% endif %}
+                            <a href="{% url "admin_set" set.name %}">{{ set.title }}</a>
+                            {% if set.name|contained_in:unsaved %}<img width="12" height="12" src="{% static 'admin/img/admin/icon_alert.gif' %}" alt="{% trans "Unsaved changes" %}" />{% endif %}
                         </li>
                     {% endfor %}
                     </ul>
                 <div id="tools-menu" class="module">
                     <h2>{% trans "Tools" %}</h2>
                     <ul>
-                        <li><a href="{% url admin_maintenance %}">{% trans "Maintenance mode" %}</a></li>
-                        <li><a href="{% url admin_flagged_posts %}">{% trans "Flagged Posts" %}</a></li>
+                        <li><a href="{% url "admin_maintenance" %}">{% trans "Maintenance mode" %}</a></li>
+                        <li><a href="{% url "admin_flagged_posts" %}">{% trans "Flagged Posts" %}</a></li>
                         {% for name,tool in tools %}
-                            <li><a href="{% url admin_tools name %}">{{ tool }}</a></li>
+                            <li><a href="{% url "admin_tools" name %}">{{ tool }}</a></li>
                         {% endfor %}
                     </ul>
                 </div>
             {% endif %}
         </div>
         <div id="footer" class="breadcumbs">
-            <a href="http://www.osqa.net">OSQA</a> <span class="version">{{ settings.OSQA_VERSION }} ({{ settings.SVN_REVISION }})</span>
+            <a href="http://www.osqa.net">OSQA</a> <span class="version">{{ settings.OSQA_VERSION }} ({{ settings.VCS_REVISION }})</span>
         </div>
     </div>
-</body>
\ No newline at end of file
+</body>
index ea7c0a98369ffc85bee30a45c145ebc9d7263974..76ee1a7861e0d931cfb86ac06296a137c81d2ab1 100644 (file)
@@ -4,7 +4,7 @@
 
 {% block subtitle %}{% trans "Editing page" %}{% endblock %}
 {% block pagename %}
-    <a href="{% url admin_static_pages %}">{% trans "Static Pages" %}</a> &gt;
+    <a href="{% url "admin_static_pages" %}">{% trans "Static Pages" %}</a> &gt;
     {% if page %}{% trans "Editing page" %}{% else %}{% trans "Creating page" %}{% endif %}
 {% endblock %}
 {% block description %}
index 30c3f65e415c24b18ca31d82d56d0f2ffbc2706e..9943dcaaa2f22e59079904dc43c8768270801f00 100644 (file)
@@ -1,80 +1,80 @@
-{% extends "osqaadmin/base.html" %}\r
-\r
-{% load i18n %}\r
-{% load user_tags %}\r
-\r
-{% block subtitle %}\r
-    {% trans "Dashboard" %}\r
-{% endblock %}\r
-{% block description %}\r
-    {% trans "Welcome to the OSQA administration area." %}\r
-{% endblock %}\r
-\r
-{% block admincontent %}\r
-    <table width="100%">\r
-        <tr>\r
-            <td width="50%" valign="top">\r
-                <h3>{%trans "Site statistics" %}</h3>\r
-                <table>\r
-                    <tr>\r
-                        <td>\r
-                        {{ statistics.total_questions }} {% trans "question" %}{{ statistics.total_questions|pluralize }} ({{ statistics.questions_last_24 }} {% trans "in the last 24 hours" %})\r
-                        </td>\r
-                    </tr>\r
-                    <tr>\r
-                        <td>\r
-                        {{ statistics.total_answers }} {% trans "answer" %}{{ statistics.total_answers|pluralize }} ({{ statistics.answers_last_24 }} {% trans "in the last 24 hours" %})\r
-                        </td>\r
-                    </tr>\r
-                    <tr>\r
-                        <td>\r
-                        {{ statistics.total_users }} {% trans "user" %}{{ statistics.total_users|pluralize }} ({{ statistics.users_last_24 }} {% trans "joined in the last 24 hours" %})\r
-                        </td>\r
-                    </tr>\r
-                </table>\r
-            </td>\r
-            <td valign="top">\r
-                <h3>{%trans "Site status" %}</h3>\r
-                <table>\r
-                    <tr>\r
-                        <td>\r
-                            {% ifequal settings_pack "bootstrap" %}\r
-                                {% trans "Your site is running in bootstrap mode, click the button below to revert to defaults." %}<br />\r
-                            {% else %}\r
-                                {% ifequal settings_pack "default" %}\r
-                                    {% trans "Your site is running in standard mode, click the button below to run in bootstrap mode." %}<br />\r
-                                {% else %}\r
-                                    {% trans "Your site is running with some customized settings, click the buttons below to run with defaults or in bootstrap mode" %}\r
-                                {% endifequal %}\r
-                            {% endifequal %}\r
-                            {% ifnotequal settings_pack "default" %}\r
-                                <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url admin_go_defaults %}';">{% trans "revert to defaults" %}</button>\r
-                            {% endifnotequal %}\r
-                            {% ifnotequal settings_pack "bootstrap" %}\r
-                                <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url admin_go_bootstrap %}';">{% trans "go bootstrap" %}</button>\r
-                            {% endifnotequal %}\r
-                        </td>\r
-                    </tr>\r
-                    <tr>\r
-                        <td>\r
-                            <em>"Bootstrap mode" relaxes the minimum required reputation to perform actions like voting and commenting.\r
-                            This is useful to help new communities get started.</em>\r
-                        </td>\r
-                    </tr>\r
-                </table>\r
-                <h3>{%trans "Recalculate scores and reputation" %}</h3>\r
-                 <button onclick="if (window.confirm('{% trans "This is a heavy operation, are you sure?" %}')) window.location='{% url admin_denormalize %}';">{% trans "Recalculate" %}</button>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td colspan="2">\r
-                <h3>{% trans "Recent activity" %}</h3>\r
-                <table width="100%">\r
-                {% for activity in recent_activity %}\r
-                    {% activity_item activity request.user %}\r
-                {% endfor %}\r
-                </table>\r
-            </td>\r
-        </tr>\r
-    </table>        \r
+{% extends "osqaadmin/base.html" %}
+
+{% load i18n %}
+{% load user_tags %}
+
+{% block subtitle %}
+    {% trans "Dashboard" %}
+{% endblock %}
+{% block description %}
+    {% trans "Welcome to the OSQA administration area." %}
+{% endblock %}
+
+{% block admincontent %}
+    <table width="100%">
+        <tr>
+            <td width="50%" valign="top">
+                <h3>{%trans "Site statistics" %}</h3>
+                <table>
+                    <tr>
+                        <td>
+                        {{ statistics.total_questions }} {% trans "question" %}{{ statistics.total_questions|pluralize }} ({{ statistics.questions_last_24 }} {% trans "in the last 24 hours" %})
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>
+                        {{ statistics.total_answers }} {% trans "answer" %}{{ statistics.total_answers|pluralize }} ({{ statistics.answers_last_24 }} {% trans "in the last 24 hours" %})
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>
+                        {{ statistics.total_users }} {% trans "user" %}{{ statistics.total_users|pluralize }} ({{ statistics.users_last_24 }} {% trans "joined in the last 24 hours" %})
+                        </td>
+                    </tr>
+                </table>
+            </td>
+            <td valign="top">
+                <h3>{%trans "Site status" %}</h3>
+                <table>
+                    <tr>
+                        <td>
+                            {% ifequal settings_pack "bootstrap" %}
+                                {% trans "Your site is running in bootstrap mode, click the button below to revert to defaults." %}<br />
+                            {% else %}
+                                {% ifequal settings_pack "default" %}
+                                    {% trans "Your site is running in standard mode, click the button below to run in bootstrap mode." %}<br />
+                                {% else %}
+                                    {% trans "Your site is running with some customized settings, click the buttons below to run with defaults or in bootstrap mode" %}
+                                {% endifequal %}
+                            {% endifequal %}
+                            {% ifnotequal settings_pack "default" %}
+                                <button onclick="if (window.confirm('{% trans "Are you sure you want to revert to the defaults?" %}')) window.location='{% url "admin_go_defaults" %}';">{% trans "revert to defaults" %}</button>
+                            {% endifnotequal %}
+                            {% ifnotequal settings_pack "bootstrap" %}
+                                <button onclick="if (window.confirm('{% trans "Are you sure you want to run bootstrap mode?" %}')) window.location='{% url "admin_go_bootstrap" %}';">{% trans "go bootstrap" %}</button>
+                            {% endifnotequal %}
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>
+                            <em>"Bootstrap mode" relaxes the minimum required reputation to perform actions like voting and commenting.
+                            This is useful to help new communities get started.</em>
+                        </td>
+                    </tr>
+                </table>
+                <h3>{%trans "Recalculate scores and reputation" %}</h3>
+                 <button onclick="if (window.confirm('{% trans "This is a heavy operation, are you sure?" %}')) window.location='{% url "admin_denormalize" %}';">{% trans "Recalculate" %}</button>
+            </td>
+        </tr>
+        <tr>
+            <td colspan="2">
+                <h3>{% trans "Recent activity" %}</h3>
+                <table width="100%">
+                {% for activity in recent_activity %}
+                    {% activity_item activity request.user %}
+                {% endfor %}
+                </table>
+            </td>
+        </tr>
+    </table>
 {% endblock %}
\ No newline at end of file
index 050f1f176aef861a6447a0c779fb091f48068243..b17792cc70f4a0c29c9bb7a35f862fef7e383dc2 100644 (file)
@@ -1,6 +1,6 @@
 {% extends basetemplate %}
 
-{% load i18n humanize %}
+{% load i18n humanize admin_static %}
 
 {% block subtitle %}{% trans "Moderation" %}{% endblock %}
 {% block pagename %}{% trans "Moderation" %}{% endblock %}
@@ -56,9 +56,9 @@
                         <p><a href="{{ cheater.get_profile_url }}">{{ cheater.username }}</a></p>
                         <p><b>{% trans "Email" %}</b>
                         {% if cheater.email_isvalid %}
-                            <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-yes.gif" alt="{% trans "Validated" %}" />
+                            <img src="{% static 'img/admin/icon-yes.gif' %}" alt="{% trans "Validated" %}" />
                         {% else %}
-                            <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-no.gif" alt="{% trans "Not validated" %}" />
+                            <img src="{% static 'img/admin/icon-no.gif' %}" alt="{% trans "Not validated" %}" />
                         {% endif %}
                         <a href="mailto: {{ cheater.email }}">{{ cheater.email }}</a></p>
                         <p><b>{% trans "Reputation:" %}</b> {{ cheater.reputation|intcomma }}</p>
@@ -80,9 +80,9 @@
                                 <td><a href="{{ fake.get_profile_url }}">{{ fake.username }}</a></td>
                                 <td>
                                     {% if fake.email_isvalid %}
-                                        <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-yes.gif" alt="{% trans "Validated" %}" />
+                                        <img src="{% static 'img/admin/icon-yes.gif' %}" alt="{% trans "Validated" %}" />
                                     {% else %}
-                                        <img src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon-no.gif" alt="{% trans "Not validated" %}" />
+                                        <img src="{% static 'img/admin/icon-no.gif' %}" alt="{% trans "Not validated" %}" />
                                     {% endif %}
                                     <a href="mailto: {{ fake.email }}">{{ fake.email }}</a>
                                 </td>
@@ -99,4 +99,4 @@
         </table>
         {% endif %}
     </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
index ca86af5b5604ea9b8368606f5b9c0e0ae9cdf0b3..784d49aa7a8f8b57a2cc089b0da379e2a89ded33 100644 (file)
@@ -1,6 +1,6 @@
 {% extends basetemplate %}
 
-{% load i18n user_tags extra_tags extra_filters %}
+{% load i18n user_tags extra_tags extra_filters admin_static %}
 
 {% block adminjs %}
     <script type="text/javascript">
@@ -64,7 +64,7 @@
                 }
             });
 
-            $('#author-selector').autocomplete('{% url matching_users %}', {
+            $('#author-selector').autocomplete('{% url "matching_users" %}', {
                 minChars: 1,
                 matchContains: true,
                 max: 10,
@@ -93,7 +93,7 @@
                 }
             });
 
-            $('#tag-selector').autocomplete('{% url matching_tags %}', {
+            $('#tag-selector').autocomplete('{% url "matching_tags" %}', {
                 minChars: 1,
                 matchContains: true,
                 max: 10,
             padding: 0 0 0 0;
         }
     </style>
-    <script type="text/javascript">window.__admin_media_prefix__ = "{{ settings.ADMIN_MEDIA_PREFIX }}";</script>
-    <link href="{{ settings.ADMIN_MEDIA_PREFIX }}css/base.css" rel="stylesheet" type="text/css" media="screen" />
+    <link href="{% static 'admin/css/base.css' %}" rel="stylesheet" type="text/css" media="screen" />
     <script type="text/javascript">
     /* gettext identity library */
 
     }
     
     </script>
-    <script type="text/javascript" src="{{ settings.ADMIN_MEDIA_PREFIX }}js/core.js"></script>
+    <script type="text/javascript" src="{% static 'admin/js/core.js' %}"></script>
 {% endblock %}
 
 {% block subtitle %}
             {% csrf_token %}
             <div>
                 <div>
-                    <label><img alt="Search" src="{{ settings.ADMIN_MEDIA_PREFIX }}img/admin/icon_searchbox.png"></label>
+                    <label><img alt="Search" src="{% static 'admin/img/admin/icon_searchbox.png' %}"></label>
                     <input type="text" size="40" name="text" id="text-filter-input" value="{{ text }}">
                     <input type="submit" value="{% trans "Search" %}">
                     {% if text %}
             {% endif %}
             <ul id="pre-filter-container">
                 {% for name, uri in settings.NODE_MAN_FILTERS %}
-                <li class="selected"><a href="{% url admin_tools "nodeman" %}?{{ uri }}">{{ name }}</a></li>
+                <li class="selected"><a href="{% url "admin_tools" "nodeman" %}?{{ uri }}">{{ name }}</a></li>
                 {% endfor %}
             </ul>
             <form action="" method="POST">
             {{ nodes.paginator.page_numbers }}
         </form>
     </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
index 3128d79565acc87da7649332f291d1402a669f70..1ff3525e8e8e5cdde9f209b0e3c2bffed7b097c2 100644 (file)
@@ -1,28 +1,28 @@
-{% extends basetemplate %}\r
-\r
-{% load i18n extra_tags extra_filters %}\r
-\r
-{% block subtitle %}{{ form.set.title }}{% endblock %}\r
-{% block pagename %}{{ form.set.title }}{% endblock %}\r
-{% block description %}{{ form.set.description }}{% endblock %}\r
-\r
-{% block admincontent %}\r
-    <form action="" method="POST" enctype="multipart/form-data" accept-charset="utf-8">\r
-        {% csrf_token %}\r
-        <table id="admin_form" style="width: 100%">\r
-            {{ form.as_table }}\r
-            <tr>\r
-                <th></th>\r
-                <td>\r
-                    <input id="submit" name="submit" type="submit" value="{% trans "Save" %}" onclick="this.form.target=''; return true;" />\r
-                    {% if form.set.can_preview %}\r
-                        <input id="preview" name="preview" type="submit" value="{% trans "Preview" %}" onclick="this.form.target='_blank'; return true;" />\r
-                        {% if form.set.name|contained_in:unsaved %}\r
-                            <input id="reset" name="reset" type="submit" value="{% trans "Reset Changes" %}" onclick="this.form.target=''; return true;" />\r
-                        {% endif %}\r
-                    {% endif %}\r
-                </td>\r
-            </tr>\r
-        </table>\r
-    </form>\r
+{% extends basetemplate %}
+
+{% load i18n extra_tags extra_filters %}
+
+{% block subtitle %}{{ form.set.title }}{% endblock %}
+{% block pagename %}{{ form.set.title }}{% endblock %}
+{% block description %}{{ form.set.description }}{% endblock %}
+
+{% block admincontent %}
+    <form action="" method="POST" enctype="multipart/form-data" accept-charset="utf-8">
+        {% csrf_token %}
+        <table id="admin_form" style="width: 100%">
+            {{ form.as_table }}
+            <tr>
+                <th></th>
+                <td>
+                    <input id="submit" name="submit" type="submit" value="{% trans "Save" %}" onclick="this.form.target=''; return true;" />
+                    {% if form.set.can_preview %}
+                        <input id="preview" name="preview" type="submit" value="{% trans "Preview" %}" onclick="this.form.target='_blank'; return true;" />
+                        {% if form.set.name|contained_in:unsaved %}
+                            <input id="reset" name="reset" type="submit" value="{% trans "Reset Changes" %}" onclick="this.form.target=''; return true;" />
+                        {% endif %}
+                    {% endif %}
+                </td>
+            </tr>
+        </table>
+    </form>
 {% endblock %}
\ No newline at end of file
index ea49a26050ee4211ec2af58417bb959c252dee36..d626e17e4e7c749435ec6770b40244b233fe18f4 100644 (file)
@@ -9,7 +9,7 @@
 {% block admincontent %}
     <h1>{% trans "Select page to edit" %}</h1>
     <ul class="object-tools">
-        <li><a class="addlink" href="{% url admin_new_page %}">{% trans "New page" %}</a></li>
+        <li><a class="addlink" href="{% url "admin_new_page" %}">{% trans "New page" %}</a></li>
     </ul>
     <div class="module">
         <table style="width: 100%">
             <tbody>
                 {% for page in pages %}
                     <tr>
-                        <th scope="row"><a href="{% url admin_edit_page id=page.id %}">{{ page.headline }}</a></th>
-                        <td style="width: 125px;"><a class="changelink" href="{% url admin_edit_page id=page.id %}">{% trans "Edit" %}</a></td>
+                        <th scope="row"><a href="{% url "admin_edit_page" id=page.id %}">{{ page.headline }}</a></th>
+                        <td style="width: 125px;"><a class="changelink" href="{% url "admin_edit_page" id=page.id %}">{% trans "Edit" %}</a></td>
                         <td style="width: 125px;">
-                            <a onclick="return confirm('{% trans "Are you sure you want to delete this page?" %}');" class="deletelink" href="{% url admin_delete_page id=page.id %}">
+                            <a onclick="return confirm('{% trans "Are you sure you want to delete this page?" %}');" class="deletelink" href="{% url "admin_delete_page" id=page.id %}">
                                 {% trans "Delete" %}
                             </a>
                         </td>
index cf9b459d0ee06de653ad07f6a9ce3e809cac6fc5..6465c77a6d9ccdd742dbb7cfb7bf0fa91c105d7b 100644 (file)
@@ -1,5 +1,5 @@
 {% extends base %}
-{% load i18n markup node_tags general_sidebar_tags %}
+{% load i18n node_tags general_sidebar_tags %}
 {% block title %}{% spaceless %}{{ page.title }}{% endspaceless %}{% endblock %}
 
 {% block content %}
index 228285730fd1946d0fbfe269fd765e4b6d94d203..8757469098900b1752747eaca817c55078dddcd7 100644 (file)
-{% extends "base.html" %}\r
-<!-- question.html -->\r
-{% load node_tags %}\r
-{% load extra_tags %}\r
-{% load extra_filters %}\r
-{% load general_sidebar_tags %}\r
-{% load smart_if %}\r
-{% load humanize %}\r
-{% load i18n %}\r
-{% load cache %}\r
-{% block metadescription %}{{ question.meta_description }}{% endblock %}\r
-{% block metakeywords %}{{question.tagname_meta_generator}}{% endblock %}\r
-{% block meta %}\r
-        <link rel="canonical" href="{{settings.APP_BASE_URL}}{{question.get_absolute_url}}" />\r
-        <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ question.get_absolute_url }}?type=rss">\r
-{% endblock %}\r
-{% block title %}{% spaceless %}{{ question.headline }}{% endspaceless %}{% endblock %}\r
-{% block forejs %}\r
-        {% if not question.nis.closed %}\r
-        <script type='text/javascript' src='{% media  "/media/js/osqa.question.js" %}'></script>\r
-        <script type='text/javascript' src='{% media  "/media/js/jquery.caret.js" %}'></script>\r
-        <script type='text/javascript' src='{% media  "/media/js/wmd/showdown.js" %}'></script>\r
-        <script type='text/javascript' src='{% media  "/media/js/wmd/wmd.js" %}'></script>\r
-        <script type='text/javascript' src='{% media  "/media/js/html_sanitizer.js" %}'></script>\r
-        <link rel="stylesheet" type="text/css" href="{% media  "/media/js/wmd/wmd.css" %}" />\r
-\r
-        {% if embed_youtube_videos %}\r
-        <script type='text/javascript' src='{% media  "/media/js/viewbox_min.js" %}'></script>\r
-        <script type='text/javascript' src='{% media  "/media/js/youtube.js" %}'></script>\r
-        <link rel="stylesheet" type="text/css" href="{% media  "/media/js/viewbox.css" %}" />\r
-        {% endif %}\r
-        {% endif %}\r
-\r
-        <script type="text/javascript">\r
-        $().ready(function(){\r
-            $("#nav_questions").attr('className',"on");\r
-            var answer_sort_tab = "{{ tab_id }}";\r
-\r
-            if (answer_sort_tab) {\r
-                $("#" + answer_sort_tab).attr('className',"on");\r
-            }\r
-\r
-            $('#editor').TextAreaResizer();\r
-\r
-            //toggle preview of editor\r
-            var display = true;\r
-            var txt = "[{% trans "hide preview" %}]";\r
-            $('#pre-collapse').text(txt);\r
-            $('#pre-collapse').bind('click', function(){\r
-                txt = display ? "[{% trans "show preview" %}]" : "[{% trans "hide preview" %}]";\r
-                display = !display;\r
-                $('#previewer').toggle();\r
-                $('#pre-collapse').text(txt);\r
-            });\r
-        });\r
-\r
-        function submitClicked(e, f) {\r
-            if(!(browserTester('chrome') || browserTester('safari'))) {\r
-                $("input.submit")[0].disabled=true;\r
-            }\r
-            window.removeEventListener('beforeunload', beforeUnload, true);\r
-            if (f) {\r
-                f.submit();\r
-            }\r
-        }\r
-\r
-        function beforeUnload(e) {\r
-\r
-            if($("textarea#editor")[0].value != "") {\r
-                return yourWorkWillBeLost(e);\r
-            }\r
-\r
-            var commentBoxes = $("textarea.commentBox");\r
-            for(var index = 0; index < commentBoxes.length; index++) {\r
-                if(commentBoxes[index].value != "") {\r
-                    return yourWorkWillBeLost(e);\r
-                }\r
-            }\r
-        }\r
-        window.addEventListener('beforeunload', beforeUnload, true);\r
-        </script>\r
-        <noscript>\r
-            <style>\r
-                .comment.not_top_scorer {\r
-                    display: block;\r
-                }\r
-                .comment-form-container {\r
-                    display: block;\r
-                }\r
-                .div.comment-tools {\r
-                    display: none;\r
-                }\r
-            </style>\r
-        </noscript>\r
-{% endblock %}\r
-        \r
-{% block content %}\r
-<div class="headNormal">\r
-    <h1><a href="{{ question.get_absolute_url }}">{{ question.headline }}</a></h1>\r
-</div>\r
-<div id="main-body" class="">\r
-    <div id="askform">\r
-            <table style="width:100%;" id="question-table" {% post_classes question %}>\r
-                <tr>\r
-                    <td style="width:30px;vertical-align:top">\r
-                        <div class="vote-buttons">\r
-                            {% vote_buttons question request.user %}\r
-                            {% favorite_mark question request.user %}                            \r
-                        </div>\r
-                    </td>\r
-                    <td>\r
-                        <div id="item-right">\r
-                            <div class="question-body">\r
-                                {{ question.html|safe }}\r
-                            </div>\r
-                            <div id="question-tags" class="tags-container tags">\r
-                                {% for tag in question.tagname_list %}\r
-                                    <a href="{% url tag_questions tag|urlencode %}" class="post-tag tag-link-{{ tag }}"\r
-                                        title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>\r
-                                {% endfor %}\r
-                            </div>\r
-                            <div id="question-controls" class="post-controls">                            \r
-                                {% post_controls question request.user %}\r
-                                {% wiki_symbol request.user question %}\r
-                            </div>\r
-                            <div class="post-update-info-container">\r
-                                    {% contributors_info question %}\r
-                            </div>\r
-                            {% comments question request.user %}\r
-                        </div>\r
-                        \r
-                    </td>\r
-                </tr>\r
-            </table>\r
-            {% if question.nis.closed %}\r
-            <div class="question-status" style="margin-bottom:15px">\r
-            <h3>\r
-                {% blocktrans with question.nstate.closed.extra as close_reason %}The question has been closed for the following reason "{{ close_reason }}" by{% endblocktrans %}\r
-                <a href="{{ question.nstate.closed.by.get_profile_url }}">{{ question.nstate.closed.by.username }}</a>\r
-                 {% diff_date question.nstate.closed.at %}\r
-            </h3>\r
-            </div>\r
-            {% endif %}\r
-            {% if answers %}\r
-                <hr/>\r
-                <div class="tabBar">\r
-                    <a name="sort-top"></a>\r
-                    <div class="headQuestions">\r
-                    {% blocktrans count answers.paginator.count as counter %}One Answer:{% plural %}{{counter}} Answers:{% endblocktrans %}\r
-                    </div>\r
-                    {{ answers.paginator.sort_tabs }}\r
-                </div>\r
-                {{ answers.paginator.page_numbers }}\r
-  \r
-                {% for answer in answers.paginator.page %}\r
-                    <a name="{{ answer.id }}"></a>\r
-                    <div id="answer-container-{{ answer.id }}" class="answer {% post_classes answer %}{% ifequal answer.id focused_answer_id %} focusedAnswer{% endifequal %}">\r
-                        <table style="width:100%;">\r
-                            <tr>\r
-                                <td style="width:30px;vertical-align:top">\r
-                                    <div class="vote-buttons">\r
-                                        {% vote_buttons answer request.user %}\r
-                                        {% accept_button answer request.user %}\r
-                                    </div>\r
-                                </td>\r
-                                <td>\r
-                                    <div class="item-right">\r
-                                        <div class="answer-body">\r
-                                            {{ answer.html|safe }}\r
-                                        </div>\r
-                                        <div class="answer-controls post-controls">\r
-                                            {% post_controls answer request.user %}\r
-                                            {% wiki_symbol request.user answer %}\r
-                                        </div>\r
-                                        <div class="post-update-info-container">\r
-                                            {% contributors_info answer %}\r
-                                        </div>\r
-                                        {% comments answer request.user %}\r
-                                    </div>\r
-                                </td>\r
-                            </tr>\r
-                        </table>\r
-                    </div>\r
-                {% endfor %}\r
-                <div class="paginator-container-left">\r
-                    {{ answers.paginator.page_numbers }}\r
-                </div>\r
-            {% endif %}\r
-        <form id="fmanswer" action="{% url answer question.id %}" method="post">\r
-            {% csrf_token %}\r
-            <div style="clear:both">\r
-            </div>\r
-            \r
-            {% if not question.closed %}\r
-                <div style="padding:10px 0 0 0;">\r
-                    {% spaceless %}\r
-                    <div class="headNormal">\r
-                        {% if answers %}\r
-                            {% trans "Your answer" %}\r
-                        {% else %}\r
-                            {% trans "Be the first one to answer this question!" %}\r
-                        {% endif %}\r
-                    </div>\r
-                    {% endspaceless %}\r
-                </div>\r
-                {% comment %}\r
-                {% if not request.user.is_authenticated %}\r
-                    <div class="message">{% trans "You can answer anonymously and then login." %}</div>\r
-                {% else %}\r
-                    <p class="message">\r
-                        {% ifequal request.user question.author  %}\r
-                            {% trans "Answer your own question only to give an answer." %}\r
-                        {% else %}\r
-                            {% trans "Please only give an answer, no discussions." %}\r
-                        {% endifequal %}\r
-                        {% if not request.user.email_valid_and_can_answer %}\r
-                            {% blocktrans %}Remember, your answer will not be published until you validate your email.{% endblocktrans %}\r
-                            <a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>\r
-                        {% endif %}\r
-                    </p>\r
-                {% endif %}\r
-                {% endcomment %}\r
-\r
-                <div id="description" class="" >\r
-                    <div id="wmd-button-bar" class="wmd-panel"></div>\r
-                    {{ answer.text }}\r
-                    <div class="preview-toggle">\r
-                        <table width="100%">\r
-                            <tr>\r
-                                <td>\r
-                                    <span id="pre-collapse" \r
-                                        title="{% trans "Toggle the real time Markdown editor preview" %}">\r
-                                            {% trans "toggle preview" %}\r
-                                    </span>\r
-                                </td>\r
-                                <td style="text-align: right;" id="editor-metrics"></td>\r
-                                {% if settings.WIKI_ON %}\r
-                                <td style="text-align:right;">\r
-                                    {{ answer.wiki }} \r
-                                    <span style="font-weight:normal;cursor:help" \r
-                                        title="{{answer.wiki.help_text}}">\r
-                                            {{ answer.wiki.label_tag }} \r
-                                    </span>\r
-                                </td>\r
-                                {% endif %}\r
-                            </tr>\r
-                        \r
-                        </table>  \r
-                    </div>\r
-                    {{ answer.text.errors }}\r
-                    <div id="previewer" class="wmd-preview"></div>\r
-                </div>\r
-\r
-                   {% if answer.recaptcha %}\r
-                   <div class="question-captcha" style="float: left;">\r
-                       {{ answer.recaptcha.errors }}\r
-                       {{ answer.recaptcha }}\r
-                   </div>\r
-                   <div class="clear"></div>\r
-                   {% endif %}\r
-                \r
-                <p><span class="form-error"></span></p>\r
-                <input type="button"\r
-                    {% if user.is_anonymous %}\r
-                        value="{% trans "Login/Signup to Post Your Answer" %}" \r
-                    {% else %}\r
-                        {% if user == question.author %}\r
-                        value="{% trans "Answer Your Own Question" %}" \r
-                        {% else %}\r
-                        value="{% trans "Answer the question" %}" \r
-                        {% endif %}\r
-                    {% endif %}\r
-                    class="submit" style="float:left" onclick="submitClicked(event, this.form)"/>\r
-            {% endif %}\r
-        </form>\r
-    </div>\r
-</div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-<div class="boxC" id="subscription_box">\r
-    {% include "subscription_status.html" %}\r
-</div>\r
-\r
-{% markdown_help %}\r
-\r
-{% sidebar_upper %}\r
-\r
-{% cache 60 questions_tags settings.APP_URL question.id %}\r
-<div class="boxC">\r
-    <p>\r
-               {% trans "Question tags" %}:\r
-    </p>\r
-    <p class="tags" >\r
-        {% for tag in question.tags.all %}\r
-               <a href="{% url tag_questions tag.name|urlencode %}"\r
-            class="tag-link-{{ tag.name }}"\r
-                       title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"\r
-                       rel="tag">{{ tag.name }}</a> <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>\r
-        {% endfor %}\r
-    </p>\r
-    <p>\r
-        {% trans "question asked" %}: <strong title="{{ question.added_at }}">{% diff_date question.added_at %}</strong>\r
-    </p>\r
-    <p> \r
-       {% trans "question was seen" %}: <strong>{{ question.view_count|intcomma }} {% trans "times" %}</strong>\r
-    </p>\r
-    <p> \r
-        {% trans "last updated" %}: <strong title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</strong>\r
-    </p>\r
-</div>\r
-{% endcache %}\r
-{% sidebar_lower %}\r
-<div class="boxC">\r
-    <h3 class="subtitle">{% trans "Related questions" %}</h3>\r
-    <div class="questions-related">\r
-\r
-        {% for question in similar_questions %}\r
-        <p>\r
-            <a href="{{ question.get_absolute_url }}">{{ question.headline }}</a>\r
-        </p>\r
-        {% endfor %}\r
-\r
-    </div>\r
-</div>\r
-\r
-{% endblock %}\r
-\r
-{% block endjs %}\r
-{% endblock %}\r
-<!-- end question.html -->\r
+{% extends "base.html" %}
+<!-- question.html -->
+{% load node_tags %}
+{% load extra_tags %}
+{% load extra_filters %}
+{% load general_sidebar_tags %}
+{% load smart_if %}
+{% load humanize %}
+{% load i18n %}
+{% load cache %}
+{% block metadescription %}{{ question.meta_description }}{% endblock %}
+{% block metakeywords %}{{question.tagname_meta_generator}}{% endblock %}
+{% block meta %}
+        <link rel="canonical" href="{{settings.APP_BASE_URL}}{{question.get_absolute_url}}" />
+        <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ question.get_absolute_url }}?type=rss">
+{% endblock %}
+{% block title %}{% spaceless %}{{ question.headline }}{% endspaceless %}{% endblock %}
+{% block forejs %}
+        {% if not question.nis.closed %}
+        <script type='text/javascript' src='{% media  "/media/js/osqa.question.js" %}'></script>
+        <script type='text/javascript' src='{% media  "/media/js/jquery.caret.js" %}'></script>
+        <script type='text/javascript' src='{% media  "/media/js/wmd/showdown.js" %}'></script>
+        <script type='text/javascript' src='{% media  "/media/js/wmd/wmd.js" %}'></script>
+        <script type='text/javascript' src='{% media  "/media/js/html_sanitizer.js" %}'></script>
+        <link rel="stylesheet" type="text/css" href="{% media  "/media/js/wmd/wmd.css" %}" />
+
+        {% if embed_youtube_videos %}
+        <script type='text/javascript' src='{% media  "/media/js/viewbox_min.js" %}'></script>
+        <script type='text/javascript' src='{% media  "/media/js/youtube.js" %}'></script>
+        <link rel="stylesheet" type="text/css" href="{% media  "/media/js/viewbox.css" %}" />
+        {% endif %}
+        {% endif %}
+
+        <script type="text/javascript">
+        $().ready(function(){
+            $("#nav_questions").attr('className',"on");
+            var answer_sort_tab = "{{ tab_id }}";
+
+            if (answer_sort_tab) {
+                $("#" + answer_sort_tab).attr('className',"on");
+            }
+
+            $('#editor').TextAreaResizer();
+
+            //toggle preview of editor
+            var display = true;
+            var txt = "[{% trans "hide preview" %}]";
+            $('#pre-collapse').text(txt);
+            $('#pre-collapse').bind('click', function(){
+                txt = display ? "[{% trans "show preview" %}]" : "[{% trans "hide preview" %}]";
+                display = !display;
+                $('#previewer').toggle();
+                $('#pre-collapse').text(txt);
+            });
+        });
+
+        function submitClicked(e, f) {
+            if(!(browserTester('chrome') || browserTester('safari'))) {
+                $("input.submit")[0].disabled=true;
+            }
+            window.removeEventListener('beforeunload', beforeUnload, true);
+            if (f) {
+                f.submit();
+            }
+        }
+
+        function beforeUnload(e) {
+
+            if($("textarea#editor")[0].value != "") {
+                return yourWorkWillBeLost(e);
+            }
+
+            var commentBoxes = $("textarea.commentBox");
+            for(var index = 0; index < commentBoxes.length; index++) {
+                if(commentBoxes[index].value != "") {
+                    return yourWorkWillBeLost(e);
+                }
+            }
+        }
+        window.addEventListener('beforeunload', beforeUnload, true);
+        </script>
+        <noscript>
+            <style>
+                .comment.not_top_scorer {
+                    display: block;
+                }
+                .comment-form-container {
+                    display: block;
+                }
+                .div.comment-tools {
+                    display: none;
+                }
+            </style>
+        </noscript>
+{% endblock %}
+
+{% block content %}
+<div class="headNormal">
+    <h1><a href="{{ question.get_absolute_url }}">{{ question.headline }}</a></h1>
+</div>
+<div id="main-body" class="">
+    <div id="askform">
+            <table style="width:100%;" id="question-table" {% post_classes question %}>
+                <tr>
+                    <td style="width:30px;vertical-align:top">
+                        <div class="vote-buttons">
+                            {% vote_buttons question request.user %}
+                            {% favorite_mark question request.user %}
+                        </div>
+                    </td>
+                    <td>
+                        <div id="item-right">
+                            <div class="question-body">
+                                {{ question.html|safe }}
+                            </div>
+                            <div id="question-tags" class="tags-container tags">
+                                {% for tag in question.tagname_list %}
+                                    <a href="{% url "tag_questions" tag|urlencode %}" class="post-tag tag-link-{{ tag }}"
+                                        title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
+                                {% endfor %}
+                            </div>
+                            <div id="question-controls" class="post-controls">
+                                {% post_controls question request.user %}
+                                {% wiki_symbol request.user question %}
+                            </div>
+                            <div class="post-update-info-container">
+                                    {% contributors_info question %}
+                            </div>
+                            {% comments question request.user %}
+                        </div>
+
+                    </td>
+                </tr>
+            </table>
+            {% if question.nis.closed %}
+            <div class="question-status" style="margin-bottom:15px">
+            <h3>
+                {% blocktrans with question.nstate.closed.extra as close_reason %}The question has been closed for the following reason "{{ close_reason }}" by{% endblocktrans %}
+                <a href="{{ question.nstate.closed.by.get_profile_url }}">{{ question.nstate.closed.by.username }}</a>
+                 {% diff_date question.nstate.closed.at %}
+            </h3>
+            </div>
+            {% endif %}
+            {% if answers %}
+                <hr/>
+                <div class="tabBar">
+                    <a name="sort-top"></a>
+                    <div class="headQuestions">
+                    {% blocktrans count answers.paginator.count as counter %}One Answer:{% plural %}{{counter}} Answers:{% endblocktrans %}
+                    </div>
+                    {{ answers.paginator.sort_tabs }}
+                </div>
+                {{ answers.paginator.page_numbers }}
+
+                {% for answer in answers.paginator.page %}
+                    <a name="{{ answer.id }}"></a>
+                    <div id="answer-container-{{ answer.id }}" class="answer {% post_classes answer %}{% ifequal answer.id focused_answer_id %} focusedAnswer{% endifequal %}">
+                        <table style="width:100%;">
+                            <tr>
+                                <td style="width:30px;vertical-align:top">
+                                    <div class="vote-buttons">
+                                        {% vote_buttons answer request.user %}
+                                        {% accept_button answer request.user %}
+                                    </div>
+                                </td>
+                                <td>
+                                    <div class="item-right">
+                                        <div class="answer-body">
+                                            {{ answer.html|safe }}
+                                        </div>
+                                        <div class="answer-controls post-controls">
+                                            {% post_controls answer request.user %}
+                                            {% wiki_symbol request.user answer %}
+                                        </div>
+                                        <div class="post-update-info-container">
+                                            {% contributors_info answer %}
+                                        </div>
+                                        {% comments answer request.user %}
+                                    </div>
+                                </td>
+                            </tr>
+                        </table>
+                    </div>
+                {% endfor %}
+                <div class="paginator-container-left">
+                    {{ answers.paginator.page_numbers }}
+                </div>
+            {% endif %}
+        <form id="fmanswer" action="{% url "answer" question.id %}" method="post">
+            {% csrf_token %}
+            <div style="clear:both">
+            </div>
+
+            {% if not question.closed %}
+                <div style="padding:10px 0 0 0;">
+                    {% spaceless %}
+                    <div class="headNormal">
+                        {% if answers %}
+                            {% trans "Your answer" %}
+                        {% else %}
+                            {% trans "Be the first one to answer this question!" %}
+                        {% endif %}
+                    </div>
+                    {% endspaceless %}
+                </div>
+                {% comment %}
+                {% if not request.user.is_authenticated %}
+                    <div class="message">{% trans "You can answer anonymously and then login." %}</div>
+                {% else %}
+                    <p class="message">
+                        {% ifequal request.user question.author  %}
+                            {% trans "Answer your own question only to give an answer." %}
+                        {% else %}
+                            {% trans "Please only give an answer, no discussions." %}
+                        {% endifequal %}
+                        {% if not request.user.email_valid_and_can_answer %}
+                            {% blocktrans %}Remember, your answer will not be published until you validate your email.{% endblocktrans %}
+                            <a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
+                        {% endif %}
+                    </p>
+                {% endif %}
+                {% endcomment %}
+
+                <div id="description" class="" >
+                    <div id="wmd-button-bar" class="wmd-panel"></div>
+                    {{ answer.text }}
+                    <div class="preview-toggle">
+                        <table width="100%">
+                            <tr>
+                                <td>
+                                    <span id="pre-collapse" 
+                                        title="{% trans "Toggle the real time Markdown editor preview" %}">
+                                            {% trans "toggle preview" %}
+                                    </span>
+                                </td>
+                                <td style="text-align: right;" id="editor-metrics"></td>
+                                {% if settings.WIKI_ON %}
+                                <td style="text-align:right;">
+                                    {{ answer.wiki }} 
+                                    <span style="font-weight:normal;cursor:help" 
+                                        title="{{answer.wiki.help_text}}">
+                                            {{ answer.wiki.label_tag }} 
+                                    </span>
+                                </td>
+                                {% endif %}
+                            </tr>
+
+                        </table>
+                    </div>
+                    {{ answer.text.errors }}
+                    <div id="previewer" class="wmd-preview"></div>
+                </div>
+
+                {% if answer.recaptcha %}
+                <div class="question-captcha" style="float: left;">
+                    {{ answer.recaptcha.errors }}
+                    {{ answer.recaptcha }}
+                </div>
+                <div class="clear"></div>
+                {% endif %}
+
+                <p><span class="form-error"></span></p>
+                <input type="button"
+                    {% if user.is_anonymous %}
+                        value="{% trans "Login/Signup to Post Your Answer" %}" 
+                    {% else %}
+                        {% if user == question.author %}
+                        value="{% trans "Answer Your Own Question" %}" 
+                        {% else %}
+                        value="{% trans "Answer the question" %}" 
+                        {% endif %}
+                    {% endif %}
+                    class="submit" style="float:left" onclick="submitClicked(event, this.form)"/>
+            {% endif %}
+        </form>
+    </div>
+</div>
+{% endblock %}
+
+{% block sidebar %}
+<div class="boxC" id="subscription_box">
+    {% include "subscription_status.html" %}
+</div>
+
+{% markdown_help %}
+
+{% sidebar_upper %}
+
+{% cache 60 questions_tags settings.APP_URL question.id %}
+<div class="boxC">
+    <p>
+        {% trans "Question tags" %}:
+    </p>
+    <p class="tags" >
+        {% for tag in question.tags.all %}
+        <a href="{% url "tag_questions" tag.name|urlencode %}"
+            class="tag-link-{{ tag.name }}"
+            title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"
+            rel="tag">{{ tag.name }}</a> <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>
+        {% endfor %}
+    </p>
+    <p>
+        {% trans "question asked" %}: <strong title="{{ question.added_at }}">{% diff_date question.added_at %}</strong>
+    </p>
+    <p> 
+       {% trans "question was seen" %}: <strong>{{ question.view_count|intcomma }} {% trans "times" %}</strong>
+    </p>
+    <p> 
+        {% trans "last updated" %}: <strong title="{{ question.last_activity_at }}">{% diff_date question.last_activity_at %}</strong>
+    </p>
+</div>
+{% endcache %}
+{% sidebar_lower %}
+<div class="boxC">
+    <h3 class="subtitle">{% trans "Related questions" %}</h3>
+    <div class="questions-related">
+
+        {% for question in similar_questions %}
+        <p>
+            <a href="{{ question.get_absolute_url }}">{{ question.headline }}</a>
+        </p>
+        {% endfor %}
+
+    </div>
+</div>
+
+{% endblock %}
+
+{% block endjs %}
+{% endblock %}
+<!-- end question.html -->
index 4f4395080af6cc136e1e8796111129f745f13941..b3fcd94729d4d3bf2252c5ba0819476a523ddd03 100644 (file)
@@ -27,7 +27,7 @@
             });
             
             //Tags autocomplete action
-               $("#id_tags").autocomplete("{% url matching_tags %}", {
+               $("#id_tags").autocomplete("{% url "matching_tags" %}", {
                        matchContains: true,
                 max: 20,
                 multiple: true,
index ce7ac952c8b348d859d3d6a95dd36be33d0921d0..77bfa05fd7556c644e7e498c6edd2ddbbace6284 100644 (file)
@@ -1,12 +1,11 @@
 <!-- question_edit_tips.html -->
-{% load markup %}
-{% load i18n general_sidebar_tags %}
+{% load i18n general_sidebar_tags extra_filters %}
 <div class="boxC" id="title_side_bar">
     <p class="subtitle darkred">{% trans "Title Tips" %}</p>
     <div class="list-item">
-        {{ settings.QUESTION_TITLE_TIPS|markdown:"settingsparser" }}
+        {{ settings.QUESTION_TITLE_TIPS|static_content:"markdown" }}
         <p class='info-box-follow-up-links'>
-            <a href="{% url faq %}" target="_blank" title="{% trans "see frequently asked questions" %}">{% trans "faq" %} &raquo;</a>
+            <a href="{% url "faq" %}" target="_blank" title="{% trans "see frequently asked questions" %}">{% trans "faq" %} &raquo;</a>
         </p>
     </div>
 </div>
 <div class="boxC" id="tags_side_bar" align="left">
     <p class="subtitle darkred">{% trans "What Are Tags" %}</p>
     <div class="list-item">
-        {{ settings.QUESTION_TAG_TIPS|markdown:"settingsparser" }}
+        {{ settings.QUESTION_TAG_TIPS|static_content:"markdown" }}
     </div>
 </div>
 
 
 <!-- end question_edit_tips.html  -->
-                                  
\ No newline at end of file
index dbb45eb8ed70af83747eb4c6a598c68dc016cb27..1e806dd66a181aaab7d8999fb5baff8d022fca81 100644 (file)
@@ -1,26 +1,26 @@
-{% spaceless %}\r
-{% load i18n humanize extra_tags %}\r
-{% declare %}\r
-    answer_count = questions.children_count('answer')\r
-{% enddeclare %}\r
-\r
-<div class="boxC">\r
-    <div class="questions-count">\r
-        {{ questions.paginator.count }}<span style="color:black;font-size:14px;margin-left:5px">{{ list_description }}</span>\r
-    </div>\r
-\r
-\r
-    {% if answer_count %}\r
-    <div class="questions-count">\r
-        {{ answer_count }}<span style="color:black;font-size:14px;margin-left:5px">{% trans "answers" %}</span>\r
-    </div>\r
-\r
-    {% endif %}\r
-\r
-    <div>\r
-        <p class="nomargin">\r
-            {{ questions.paginator.sort_description }}\r
-        </p>\r
-    </div>\r
-</div>\r
+{% spaceless %}
+{% load i18n humanize extra_tags %}
+{% declare %}
+    answer_count = questions.children_count('answer')
+{% enddeclare %}
+
+<div class="boxC">
+    <div class="questions-count">
+        {{ questions.paginator.count }}<span style="color:black;font-size:14px;margin-left:5px">{{ list_description }}</span>
+    </div>
+
+
+    {% if answer_count %}
+    <div class="questions-count">
+        {{ answer_count }}<span style="color:black;font-size:14px;margin-left:5px">{% trans "answers" %}</span>
+    </div>
+
+    {% endif %}
+
+    <div>
+        <p class="nomargin">
+            {{ questions.paginator.sort_description }}
+        </p>
+    </div>
+</div>
 {% endspaceless %}
\ No newline at end of file
index 1ad2ba5c8e98859e3da6cb9843e79e651fcec7a8..e3dd4b354f7f81951a7760e030951495e8c86bee 100644 (file)
@@ -1,40 +1,40 @@
-{% load i18n humanize extra_filters extra_tags user_tags %}\r
-<div class="short-summary">\r
-    <div class="counts">{% if favorite_count %}\r
-        <div class="favorites">\r
-            <span class="favorite-mark{% if question.favourite_count %} on{% endif %}"></span>\r
-            <div class="item-count">{{question.favourite_count|intcomma}}</div>\r
-        </div>\r
-        {% endif %}\r
-        <div class="votes">\r
-            <div class="item-count">{{question.score|intcomma}}</div>\r
-            <div>{% ifequal question.score 1 %}{% trans "vote" %}{% else %}{% trans "votes" %}{% endifequal %}</div>\r
-        </div >\r
-        <div {% if question.accepted_count %}title="{% trans "this question has an accepted answer" %}"{% endif %} class="status {% if question.accepted_count %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">\r
-            <div class="item-count">{{question.answer_count|intcomma}}</div>\r
-            <div>{% ifequal question.answer_count 1 %}{% trans "answer" %}{% else %}{% trans "answers" %}{% endifequal %}</div>\r
-        </div>\r
-        <div class="views">\r
-             <div class="item-count">{{question.view_count|decorated_int|safe}}</div>\r
-             <div>{% ifequal question.view_count 1 %}{% trans "view" %}{% else %}{% trans "views" %}{% endifequal %}</div>\r
-        </div>\r
-    </div>\r
-\r
-    <div class="question-summary-wrapper">\r
-        <h2><a {% if not question_summary %}title="{{ question.summary }}"{% endif %} href="{{ question.get_absolute_url }}">{{question.headline}}</a></h2>\r
-        {% if question_summary %}\r
-        <div class="summary">\r
-          {{ question.summary }}\r
-        </div>\r
-        {% endif %}\r
-        <div class="userinfo">\r
-            <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>\r
-            {% if question.last_activity_by %}{% user_signature question.last_activity_by signature_type %}{% endif %}\r
-        </div>\r
-\r
-        <div class="tags">{% for tag in question.tagname_list %}\r
-            <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}'" rel="tag">{{ tag }}</a>{% endfor %}\r
-        </div>\r
-    </div>\r
-\r
+{% load i18n humanize extra_filters extra_tags user_tags %}
+<div class="short-summary">
+    <div class="counts">{% if favorite_count %}
+        <div class="favorites">
+            <span class="favorite-mark{% if question.favourite_count %} on{% endif %}"></span>
+            <div class="item-count">{{question.favourite_count|intcomma}}</div>
+        </div>
+        {% endif %}
+        <div class="votes">
+            <div class="item-count">{{question.score|intcomma}}</div>
+            <div>{% ifequal question.score 1 %}{% trans "vote" %}{% else %}{% trans "votes" %}{% endifequal %}</div>
+        </div >
+        <div {% if question.accepted_count %}title="{% trans "this question has an accepted answer" %}"{% endif %} class="status {% if question.accepted_count %}answered-accepted{% endif %} {% ifequal question.answer_count 0 %}unanswered{% endifequal %}{% ifnotequal question.answer_count 0 %}answered{% endifnotequal %}">
+            <div class="item-count">{{question.answer_count|intcomma}}</div>
+            <div>{% ifequal question.answer_count 1 %}{% trans "answer" %}{% else %}{% trans "answers" %}{% endifequal %}</div>
+        </div>
+        <div class="views">
+             <div class="item-count">{{question.view_count|decorated_int|safe}}</div>
+             <div>{% ifequal question.view_count 1 %}{% trans "view" %}{% else %}{% trans "views" %}{% endifequal %}</div>
+        </div>
+    </div>
+
+    <div class="question-summary-wrapper">
+        <h2><a {% if not question_summary %}title="{{ question.summary }}"{% endif %} href="{{ question.get_absolute_url }}">{{question.headline}}</a></h2>
+        {% if question_summary %}
+        <div class="summary">
+          {{ question.summary }}
+        </div>
+        {% endif %}
+        <div class="userinfo">
+            <span class="relativetime" title="{{question.last_activity_at}}">{% diff_date question.last_activity_at %}</span>
+            {% if question.last_activity_by %}{% user_signature question.last_activity_by signature_type %}{% endif %}
+        </div>
+
+        <div class="tags">{% for tag in question.tagname_list %}
+            <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}'" rel="tag">{{ tag }}</a>{% endfor %}
+        </div>
+    </div>
+
 </div>
\ No newline at end of file
index 6ec2a75c17d688b2798c456d6409e00879198fed..8a2bae51b309011b23c60e2539e9dbab4fe40a06 100644 (file)
@@ -1,15 +1,15 @@
-{% load i18n %}\r
-{% load humanize %}\r
-\r
-{% if tags %}\r
-    <div class="boxC">\r
-        <h3 class="subtitle">{% trans "Related tags" %}</h3>\r
-        <div class="tags" id="recent-tags">\r
-            {% for tag in tags %}\r
-                <a rel="tag" class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"  href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>\r
-                <span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>\r
-                <br />\r
-            {% endfor %}\r
-        </div>\r
-    </div>\r
+{% load i18n %}
+{% load humanize %}
+
+{% if tags %}
+    <div class="boxC">
+        <h3 class="subtitle">{% trans "Related tags" %}</h3>
+        <div class="tags" id="recent-tags">
+            {% for tag in tags %}
+                <a rel="tag" class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"  href="{% url "tag_questions" tag.name|urlencode %}">{{ tag.name }}</a>
+                <span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
+                <br />
+            {% endfor %}
+        </div>
+    </div>
 {% endif %}
\ No newline at end of file
index eff04084c96469be3ed6a3b69df2154db3296f78..5e35fea18a13e9e3888d088ee2d375a7ea97f033 100644 (file)
@@ -1,8 +1,8 @@
-{% load i18n %}\r
-\r
-<div class="tabsA">\r
-    <a id="active" href="{{ base_url }}active"{% ifequal current "active" %} class="on"{% endifequal %} title="{% trans "most recently updated questions" %}">{% trans "active" %}</a>\r
-    <a id="latest" href="{{ base_url }}latest"{% ifequal current "latest" %} class="on"{% endifequal %} title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a>\r
-    <a id="hottest" href="{{ base_url }}hottest"{% ifequal current "hottest" %} class="on"{% endifequal %} title="{% trans "hottest questions" %}">{% trans "hottest" %}</a>\r
-    <a id="mostvoted" href="{{ base_url }}mostvoted"{% ifequal current "mostvoted" %} class="on"{% endifequal %} title="{% trans "most voted questions" %}">{% trans "most voted" %}</a>\r
-</div>\r
+{% load i18n %}
+
+<div class="tabsA">
+    <a id="active" href="{{ base_url }}active"{% ifequal current "active" %} class="on"{% endifequal %} title="{% trans "most recently updated questions" %}">{% trans "active" %}</a>
+    <a id="latest" href="{{ base_url }}latest"{% ifequal current "latest" %} class="on"{% endifequal %} title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a>
+    <a id="hottest" href="{{ base_url }}hottest"{% ifequal current "hottest" %} class="on"{% endifequal %} title="{% trans "hottest questions" %}">{% trans "hottest" %}</a>
+    <a id="mostvoted" href="{{ base_url }}mostvoted"{% ifequal current "mostvoted" %} class="on"{% endifequal %} title="{% trans "most voted questions" %}">{% trans "most voted" %}</a>
+</div>
index 3f1f688f9870235648c65ecffdbbe769fc5c9d6c..faa0e18bda1a19c6c554289d3e6f1682963b7687 100644 (file)
@@ -1,6 +1,6 @@
 {% load i18n humanize extra_filters extra_tags user_tags %}
 <div class="subscription_summary">
-    <div style="height:100%"><a class="sidebar_button subscription_unsubscribe_button" href="{% url subscribe id=subscription.question.id user=subscription.user.id %}">
+    <div style="height:100%"><a class="sidebar_button subscription_unsubscribe_button" href="{% url "subscribe" id=subscription.question.id user=subscription.user.id %}">
         {% trans "Unsubscribe" %}
     </a></div>
 
index 89817a972952a8a84a284b2bff42265df3abe006..ab87ba5e4d7f8a0881d5a60fe3a1c7791373f9be 100644 (file)
@@ -12,7 +12,7 @@
             <a rel="tag" 
                 class="tag-link-{{ tag_name }}"
                 title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
-                href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+                href="{% url "tag_questions" tag_name|urlencode %}">{{tag_name}}</a>
             <img class="delete-icon" 
                 src="{% media  "/media/images/close-small-dark.png" %}"
                 title="{% blocktrans %}remove '{{tag_name}}' from the list of interesting tags{% endblocktrans %}"/>
@@ -30,7 +30,7 @@
             <a rel="tag" 
                 class="tag-link-{{ tag_name }}"
                 title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
-                href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+                href="{% url "tag_questions" tag_name|urlencode %}">{{tag_name}}</a>
             <img class="delete-icon" 
                 src="{% media  "/media/images/close-small-dark.png" %}"
                 title="{% blocktrans %}remove '{{tag_name}}' from the list of ignored tags{% endblocktrans %}"/>
index bb6268fefd8fa48ba73935c6efdae35be6e7c6e5..dcec33def8e1754f830d556fe35d6a7bd3f461ad 100644 (file)
@@ -1,25 +1,25 @@
-{% load i18n %}\r
-\r
-<div class="headQuestions">\r
-    {% if searchtag %}\r
-        {% trans "Found by tags" %}\r
-    {% else %}\r
-        {% if searchtitle %}\r
-            {% if settings.USE_SPHINX_SEARCH %}\r
-                {% trans "Search results" %}\r
-            {% else %}\r
-                {% trans "Found by title" %}\r
-            {% endif %}\r
-        {% else %}\r
-            {% if is_unanswered %}\r
-                {% trans "Unanswered questions" %}\r
-            {% else %}\r
-                {% if page_title %}\r
-                    {% trans page_title %}\r
-                {% else %}\r
-                    {% trans "All Questions" %}\r
-                {% endif %}\r
-            {% endif %}\r
-        {% endif %}\r
-    {% endif %}\r
+{% load i18n %}
+
+<div class="headQuestions">
+    {% if searchtag %}
+        {% trans "Found by tags" %}
+    {% else %}
+        {% if searchtitle %}
+            {% if settings.USE_SPHINX_SEARCH %}
+                {% trans "Search results" %}
+            {% else %}
+                {% trans "Found by title" %}
+            {% endif %}
+        {% else %}
+            {% if is_unanswered %}
+                {% trans "Unanswered questions" %}
+            {% else %}
+                {% if page_title %}
+                    {% trans page_title %}
+                {% else %}
+                    {% trans "All Questions" %}
+                {% endif %}
+            {% endif %}
+        {% endif %}
+    {% endif %}
 </div>
\ No newline at end of file
index 6a5266c68f0830540fc6447b874df8e7c8c84643..dcb8058d7a04bfd61798b03747486ac86250d3c4 100644 (file)
@@ -7,7 +7,7 @@
         <script type="text/javascript">
         
         $().ready(function(){
-            $("#id_tags").autocomplete("{% url matching_tags %}", {
+            $("#id_tags").autocomplete("{% url "matching_tags" %}", {
                        matchContains: true,
                 max: 20,
                 multiple: true,
@@ -41,7 +41,7 @@
 </div>
 <div id="main-body" class="ask-body">
     <div id="askform">
-        <form id="fmretag" action="{% url edit_question question.id %}" method="post">
+        <form id="fmretag" action="{% url "edit_question" question.id %}" method="post">
             {% csrf_token %}
             <h3>
                 {{ question.headline }}
@@ -78,7 +78,7 @@
         </li>
     </ul>
     <p class='info-box-follow-up-links'>
-        <a href="{% url faq %}">faq &raquo;</a>
+        <a href="{% url "faq" %}">faq &raquo;</a>
     </p>
 </div>
 
index b2ce45fc76f1afc9dfd1f78b6e006796ef170e3a..2a778bc4b6270bacbe83a57b568dd6448c72efd3 100644 (file)
@@ -49,7 +49,7 @@
         
         <div class="tags">
         {% for tag in question.tagname_list %}
-        <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+        <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
         {% endfor %}
         </div>
     </div>
index f470ba3ef36fb58e5ed971a911ddb8d137660c04..1fec6af6ee211d2dd95402256afc2ff6af274a07 100644 (file)
@@ -1,49 +1,49 @@
-{% extends "base.html" %}\r
-<!-- questions.html -->\r
-{% load question_list_tags %}\r
-{% load i18n %}\r
-{% load extra_tags %}\r
-{% load general_sidebar_tags %}\r
-\r
-{% block title %}{% spaceless %}{{ page_title }}{% endspaceless %}{% endblock %}\r
-\r
-{% block metadescription %}{% spaceless %}\r
-    {% if tag %}\r
-        {% blocktrans with settings.APP_TITLE as app_title %}Questions and answers about {{ tag }} on {{ app_title }}{% endblocktrans %}\r
-    {% endif %}\r
-{% endspaceless %}{% endblock %}\r
-\r
-{% block meta %}\r
-    <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed_url }}" />\r
-{% endblock %}\r
-\r
-{% block content %}\r
-\r
-<div class="tabBar">\r
-    {% include "question_list/title.html" %}\r
-    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');" href="{{ feed_url }}" title="{% trans "subscribe to question RSS feed" %}"></a>\r
-    {{ questions.paginator.sort_tabs }}\r
-</div>\r
-<div id="listA">{% for question in questions.paginator.page %}\r
-    {% if show_summary %}\r
-      {% question_list_item question question_summary=yes %}\r
-    {% else %}\r
-      {% question_list_item question %}\r
-    {% endif %}\r
-{% endfor %}</div>\r
-{% endblock %}\r
-\r
-{% block tail %}\r
-    <div class="pager">{{ questions.paginator.page_numbers }}</div>\r
-    <div class="pagesize">{{ questions.paginator.page_sizes }}</div>\r
-{% endblock %}\r
-\r
-{% block sidebar %}\r
-    {% include "question_list/count.html" %}\r
-    {% sidebar_upper %}\r
-    {% tag_selector %}\r
-    {% sidebar_lower %}\r
-    {% question_list_related_tags questions.paginator.page %}\r
-\r
-{% endblock %}\r
-<!-- end questions.html -->\r
+{% extends "base.html" %}
+<!-- questions.html -->
+{% load question_list_tags %}
+{% load i18n %}
+{% load extra_tags %}
+{% load general_sidebar_tags %}
+
+{% block title %}{% spaceless %}{{ page_title }}{% endspaceless %}{% endblock %}
+
+{% block metadescription %}{% spaceless %}
+    {% if tag %}
+        {% blocktrans with settings.APP_TITLE as app_title %}Questions and answers about {{ tag }} on {{ app_title }}{% endblocktrans %}
+    {% endif %}
+{% endspaceless %}{% endblock %}
+
+{% block meta %}
+    <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ feed_url }}" />
+{% endblock %}
+
+{% block content %}
+
+<div class="tabBar">
+    {% include "question_list/title.html" %}
+    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');" href="{{ feed_url }}" title="{% trans "subscribe to question RSS feed" %}"></a>
+    {{ questions.paginator.sort_tabs }}
+</div>
+<div id="listA">{% for question in questions.paginator.page %}
+    {% if show_summary %}
+      {% question_list_item question question_summary=yes %}
+    {% else %}
+      {% question_list_item question %}
+    {% endif %}
+{% endfor %}</div>
+{% endblock %}
+
+{% block tail %}
+    <div class="pager">{{ questions.paginator.page_numbers }}</div>
+    <div class="pagesize">{{ questions.paginator.page_sizes }}</div>
+{% endblock %}
+
+{% block sidebar %}
+    {% include "question_list/count.html" %}
+    {% sidebar_upper %}
+    {% tag_selector %}
+    {% sidebar_lower %}
+    {% question_list_related_tags questions.paginator.page %}
+
+{% endblock %}
+<!-- end questions.html -->
index 7de075ee14411f4b7df0c9ff643c2550d0ab9580..9af3f4f2469377451bb0163a7aa65663f3512f4f 100644 (file)
@@ -23,7 +23,7 @@
         </strong>
     </p>
     
-    <form id="fmclose" action="{% url reopen question.id %}" method="post">
+    <form id="fmclose" action="{% url "reopen" question.id %}" method="post">
         {% csrf_token %}
         <div id="" style="padding:20px 0 20px 0">
             <input type="submit" value="{% trans "Reopen this question" %}" class="submit" />
index 05b9de6fad3fa018b2b204e51195094ad0cf065d..1cd95d7a62c6a480e9c2abd69b059a62c04ca097 100644 (file)
@@ -9,7 +9,7 @@
        {%  endblocktrans %}
 </div>
 <div id="main-body" style="text-align: center; height: 400px;">
-<form action="{% url search %}" method="get">
+<form action="{% url "search" %}" method="get">
     {% csrf_token %}
     <div>
         <input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" style="width: 600px" />
index 5a00975578b71206e93912ae5b2d9be4a3f7f9e6..4c83e63db1d4250451e6ae485f235c3883d6b63a 100644 (file)
@@ -30,6 +30,6 @@
         </li>
     </ul>
     <p class='info-box-follow-up-links'>
-        <a href="{% url markdown_help %}" target="_blank">{% trans "learn more about Markdown" %} </a>
+        <a href="{% url "markdown_help" %}" target="_blank">{% trans "learn more about Markdown" %} </a>
     </p>
 </div>
index 37672c4bf0fb84b8d0347e004a335e75ca361ad2..4eb47f6c0b1f1cda17532e2b64677f0babd39a54 100644 (file)
@@ -1,17 +1,17 @@
-{% load i18n %}\r
-\r
-<div class="boxC">\r
-    <h3>{% trans "Recent awards" %}</h3>\r
-    <div class="body">\r
-         <ul class="badge-list">\r
-         {% for award in awards %}\r
-            <li>\r
-            <a href="{% url badges %}{{award.badge.id}}/{{award.badge.name|slugify}}" title="{{ award.badge.description }}" class="medal">\r
-            <span class="badge{{ award.badge.type }}">&#9679;</span>&nbsp;{{ award.badge.name }}</a>\r
-            <a href="{{ award.user.get_profile_url }}">{{ award.user.decorated_name }}</a>\r
-            </li>\r
-        {% endfor %}\r
-        </ul>\r
-        <div class="more"><a href="{% url badges %}">{% trans "all awards" %} </a> </div>\r
-     </div>\r
+{% load i18n %}
+
+<div class="boxC">
+    <h3>{% trans "Recent awards" %}</h3>
+    <div class="body">
+         <ul class="badge-list">
+         {% for award in awards %}
+            <li>
+            <a href="{% url "badges" %}{{award.badge.id}}/{{award.badge.name|slugify}}" title="{{ award.badge.description }}" class="medal">
+            <span class="badge{{ award.badge.type }}">&#9679;</span>&nbsp;{{ award.badge.name }}</a>
+            <a href="{{ award.user.get_profile_url }}">{{ award.user.decorated_name }}</a>
+            </li>
+        {% endfor %}
+        </ul>
+        <div class="more"><a href="{% url "badges" %}">{% trans "all awards" %} </a> </div>
+     </div>
 </div>
\ No newline at end of file
index 40209c0dcdbcc06e4745976dd1f6cbac1efb61d4..be1d732ce8787ff3bfc2b74950288e8779628e5c 100644 (file)
@@ -1,16 +1,16 @@
-{% load i18n extra_tags %}\r
-{% declare %}\r
-    show_tags_in_a_cloud = settings.SHOW_TAGS_IN_A_CLOUD\r
-{% enddeclare %}\r
-\r
-<div class="boxC">\r
-       <h3>{% trans "Recent tags" %}</h3>\r
-       <div class="body">\r
-         <div class="tags" id="recent-tags">\r
-        {% for tag in tags %}\r
-            <a rel="tag"{% if show_tags_in_a_cloud %} style="font-size: {% get_tag_font_size tag %}px;"{% endif %} class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>\r
-        {% endfor %}\r
-        </div>\r
-        <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} </a> </div>\r
-    </div>\r
+{% load i18n extra_tags %}
+{% declare %}
+    show_tags_in_a_cloud = settings.SHOW_TAGS_IN_A_CLOUD
+{% enddeclare %}
+
+<div class="boxC">
+       <h3>{% trans "Recent tags" %}</h3>
+       <div class="body">
+         <div class="tags" id="recent-tags">
+        {% for tag in tags %}
+            <a rel="tag"{% if show_tags_in_a_cloud %} style="font-size: {% get_tag_font_size tag %}px;"{% endif %} class="tag-link-{{ tag.name }}" title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url "tag_questions" tag.name|urlencode %}">{{ tag.name }}</a>
+        {% endfor %}
+        </div>
+        <div class="more"><a href="{% url "tags" %}">{% trans "popular tags" %} </a> </div>
+    </div>
 </div>
\ No newline at end of file
index d3d98cc27ac925ea2e1fccde5dbbf0bb721dc598..343fdd7a0e99962b3f693ff68ca1c87a72a96ea2 100644 (file)
@@ -1,5 +1,3 @@
-{% load markup %}
-
 {% if show %}
 {% if wrap %}<div id="{{ blockid }}" class="boxC">
     <div class="body">{% endif %}
index eff93ae64585fa7226e65e0d6808941e20cad7d0..26819ffc714caecb69e34d9cdd908fee8d3cb42a 100644 (file)
@@ -1,12 +1,11 @@
 {% extends "base_content.html" %}
-{% load i18n %}
-{% load markup %}
+{% load i18n extra_filters %}
 {% block title %}{% spaceless %}{{ title }}{% endspaceless %}{% endblock %}
 
 {% block content %}
 <div class="headNormal">{{ title }}</div>
 <div class="content">
-{{ content|markdown:"settingsparser" }}
+{{ content|static_content:"markdown" }}
 </div>
 {% endblock %}
 
index 49ec02f7ec10ed365824d255d222bee0afadc7df..535ea1817c39b787403f335768d1a8f32b65c3ef 100644 (file)
@@ -1,43 +1,43 @@
-{% spaceless %}\r
-{% load i18n extra_tags %}\r
-<h3 class="subtitle">{% trans "Follow this question" %}</h3>\r
-<strong>{% trans "By Email" %}:</strong>\r
-{% if request.user.is_authenticated %}\r
-    <div class="subscription-status">\r
-        {% if subscription %}\r
-            {% if subscription.auto_subscription %}\r
-                <p>{% trans "You were automatically subscribed to this question." %}</p>\r
-            {% else %}\r
-                <p>{% trans "You are subscribed to this question." %}</p>\r
-            {% endif %}\r
-        {% else %}\r
-            <p>{% trans "You are not subscribed to this question." %}</p>\r
-        {% endif %}\r
-    </div>\r
-    <p><a class="ajax-command sidebar_button subscription_switch" href="{% url subscribe_simple id=question.id %}">\r
-        {% if subscription %}\r
-            {% trans "unsubscribe me" %}\r
-        {% else %}\r
-            {% trans "subscribe me" %}\r
-        {% endif %}\r
-    </a></p>\r
-    <p>\r
-        {% blocktrans with request.user.get_user_subscriptions_url as subscriptions_url %}\r
-            (you can adjust your notification settings on your <a href="{{ subscriptions_url }}">profile</a>)\r
-        {% endblocktrans %}\r
-    </p>\r
-{% else %}\r
-    <p>{% trans "Once you sign in you will be able to subscribe for any updates here" %}</p>\r
-{% endif %}\r
-<strong>{% trans "By RSS" %}:</strong>\r
-<p>\r
-    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"\r
-        href="{{ question.get_absolute_url }}?type=rss" title="{% trans "subscribe to answers" %}"></a>\r
-    {% trans "Answers" %}\r
-</p>\r
-<p>\r
-    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"\r
-        href="{{ question.get_absolute_url }}?type=rss&comments=yes" title="{% trans "subscribe to comments and answers" %}"></a>\r
-    {% trans "Answers and Comments" %}\r
-</p>\r
-{% endspaceless %}\r
+{% spaceless %}
+{% load i18n extra_tags %}
+<h3 class="subtitle">{% trans "Follow this question" %}</h3>
+<strong>{% trans "By Email" %}:</strong>
+{% if request.user.is_authenticated %}
+    <div class="subscription-status">
+        {% if subscription %}
+            {% if subscription.auto_subscription %}
+                <p>{% trans "You were automatically subscribed to this question." %}</p>
+            {% else %}
+                <p>{% trans "You are subscribed to this question." %}</p>
+            {% endif %}
+        {% else %}
+            <p>{% trans "You are not subscribed to this question." %}</p>
+        {% endif %}
+    </div>
+    <p><a class="ajax-command sidebar_button subscription_switch" href="{% url "subscribe_simple" id=question.id %}">
+        {% if subscription %}
+            {% trans "unsubscribe me" %}
+        {% else %}
+            {% trans "subscribe me" %}
+        {% endif %}
+    </a></p>
+    <p>
+        {% blocktrans with request.user.get_user_subscriptions_url as subscriptions_url %}
+            (you can adjust your notification settings on your <a href="{{ subscriptions_url }}">profile</a>)
+        {% endblocktrans %}
+    </p>
+{% else %}
+    <p>{% trans "Once you sign in you will be able to subscribe for any updates here" %}</p>
+{% endif %}
+<strong>{% trans "By RSS" %}:</strong>
+<p>
+    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"
+        href="{{ question.get_absolute_url }}?type=rss" title="{% trans "subscribe to answers" %}"></a>
+    {% trans "Answers" %}
+</p>
+<p>
+    <a class="feed-icon" style="background-image:url('{% media "media/images/feed-icon-small.png" %}');"
+        href="{{ question.get_absolute_url }}?type=rss&comments=yes" title="{% trans "subscribe to comments and answers" %}"></a>
+    {% trans "Answers and Comments" %}
+</p>
+{% endspaceless %}
index 56062c554e6c3d85580d5673c23d13eb5d3afae9..0524e44dc51217dc714042b3961572089a342af5 100644 (file)
@@ -42,7 +42,7 @@
 <ul class="tagsList tags">
 {% for tag in tags.paginator.page %}
    <li>
-    <a class="tag-link-{{ tag }}" href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
+    <a class="tag-link-{{ tag }}" href="{% url "tag_questions" tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
         {{ tag }}
     </a>&nbsp;
     <span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
index 0b6a9142d859da60441008c5b48fe89f72afe876..1f3b14a28006978d33fe6404ad73dd802390250b 100644 (file)
@@ -1,12 +1,12 @@
-{% load extra_tags %}\r
-{% load humanize %}\r
-{% load extra_tags %}\r
-\r
-<div class="action_container">\r
-    <div class="action_body">\r
-        {{ describe }}\r
-    </div>\r
-    <div class="action_date" style="text-align: right;">\r
-        {% diff_date action.action_date  %}\r
-    </div>\r
+{% load extra_tags %}
+{% load humanize %}
+{% load extra_tags %}
+
+<div class="action_container">
+    <div class="action_body">
+        {{ describe }}
+    </div>
+    <div class="action_date" style="text-align: right;">
+        {% diff_date action.action_date  %}
+    </div>
 </div>
\ No newline at end of file
index ce54c773e6633b551b7f7414a34ff0e97e4a4843..c7892160442efe424bc7802a3ae5013714e2d4e2 100644 (file)
-{% extends "base_content.html" %}\r
-<!-- user_edit.html -->\r
-{% load extra_tags %}\r
-{% load humanize %}\r
-{% load i18n %}\r
-{% block title %}{% spaceless %}{% trans "Edit user profile" %}{% endspaceless %}{% endblock %}\r
-{% block forejs %}\r
-        <script type="text/javascript">google.load("jquery", "1.4.2");google.load("jqueryui", "1.8.1");</script>\r
-\r
-        <link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/latest/themes/base/jquery-ui.css" type="text/css" media="all" />\r
-        <link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />\r
-\r
-        <script type="text/javascript">\r
-            $().ready(function(){\r
-                $("#id_birthday").datepicker({\r
-                    changeMonth: true,\r
-                    changeYear: true,\r
-                    dateFormat: 'yy-mm-dd',\r
-                    minDate: null,\r
-                    maxDate: '0M 0D',\r
-                    yearRange: '1920:2010'\r
-                });\r
-\r
-                $("#nav_profile").attr('className',"on");\r
-                $("#cancel").bind('click', function(){history.go(-1);})\r
-            });     \r
-        </script>\r
-        {% block userjs %}\r
-        {% endblock %}\r
-{% endblock %}\r
-{% block content %}\r
-<div id="main-bar" class="headNormal">\r
-    {{ user.username }} - {% trans "edit profile" %}\r
-</div>\r
-<div id="main-body" style="width:100%;padding-top:10px">\r
-    <form name="" action="{% url edit_user user.id user.username|slugify %}" method="post">\r
-        {% csrf_token %}\r
-        <div id="left" style="float:left;width:180px">\r
-            {% if user.email %}\r
-            {% gravatar user 128 %}\r
-            {% else %}\r
-            <img src="{% media  "/media/images/nophoto.png" %}">\r
-            {% endif %}\r
-            <div style="padding:20px 0 0 20px;font-weight:bold;font-size:150%">\r
-                <a href="http://www.gravatar.com/" target="_blank" \r
-                                       title="gravatar {% trans "image associated with your email address" %}">{% trans "gravatar" %}</a>\r
-            </div>\r
-        </div>\r
-        \r
-        <div id="askform" style="float:right;width:750px;text-align:left;">\r
-            <h2>{% trans "Registered user" %}</h2>\r
-            <table class="user-details">\r
-                <tr>\r
-                    <th width="100px"></th>\r
-                    <th></th>\r
-                </tr>\r
-                <tr style="height:35px">\r
-                       <td>{% trans "Screen Name" %}:</td>\r
-                       <td>\r
-                       {% if form.username %}\r
-                           {{ form.username }} <span class="form-error"></span> {{ form.username.errors }}\r
-                       {% else %}\r
-                           {{ user.username }}\r
-                       {% endif %}\r
-                       </td>\r
-                   </tr>\r
-                \r
-                   <tr style="height:35px">\r
-                       <td>{{ form.email.label_tag }}:</td>\r
-                       <td>{{ form.email }} <span class="form-error"></span> {{ form.email.errors }} </td>\r
-                   </tr>\r
-                <tr style="height:35px">\r
-                       <td></td>\r
-                       <td class="title-desc">{{ form.email.help_text }}</td>\r
-                   </tr>\r
-                <tr style="height:35px">\r
-                       <td>{{ form.realname.label_tag }}:</td>\r
-                       <td>{{ form.realname }} <span class="form-error"></span> {{ form.realname.errors }} </td>\r
-                   </tr>\r
-                <tr style="height:35px">\r
-                       <td>{{ form.website.label_tag }}:</td>\r
-                       <td>{{ form.website }} <span class="form-error"></span> {{ form.website.errors }} </td>\r
-                   </tr>\r
-                <tr style="height:35px">\r
-                       <td>{{ form.city.label_tag }}:</td>\r
-                       <td>{{ form.city }} <span class="form-error"></span> {{ form.city.errors }} </td>\r
-                   </tr>\r
-                <tr style="height:35px">\r
-                       <td>{{ form.birthday.label_tag }}:</td>\r
-                       <td>{{ form.birthday }} <span class="form-error"></span> {{ form.birthday.errors }} </td>\r
-                   </tr>\r
-                <tr>\r
-                       <td style="vertical-align:top">{{ form.about.label_tag }}:</td>\r
-                       <td>{{ form.about }} <span class="form-error"></span> {{ form.about.errors }} </td>\r
-                   </tr>\r
-                   \r
-            </table>\r
-            <div style="margin:30px 0 60px 0">\r
-                <input type="submit" value="{% trans "Update" %}" class="submit" >\r
-                <input id="cancel" type="button" value="{% trans "Cancel" %}" class="submit" >\r
-          \r
-            </div>\r
-        </div>\r
-    </form>\r
-    \r
-</div>\r
-{% endblock %}\r
-<!-- end user_edit.html -->\r
+{% extends "base_content.html" %}
+<!-- user_edit.html -->
+{% load extra_tags %}
+{% load humanize %}
+{% load i18n %}
+{% block title %}{% spaceless %}{% trans "Edit user profile" %}{% endspaceless %}{% endblock %}
+{% block forejs %}
+        <script type="text/javascript">google.load("jquery", "1.4.2");google.load("jqueryui", "1.8.1");</script>
+
+        <link rel="stylesheet" href="http://jquery-ui.googlecode.com/svn/tags/latest/themes/base/jquery-ui.css" type="text/css" media="all" />
+        <link rel="stylesheet" href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" type="text/css" media="all" />
+
+        <script type="text/javascript">
+            $().ready(function(){
+                $("#id_birthday").datepicker({
+                    changeMonth: true,
+                    changeYear: true,
+                    dateFormat: 'yy-mm-dd',
+                    minDate: null,
+                    maxDate: '0M 0D',
+                    yearRange: '1920:2010'
+                });
+
+                $("#nav_profile").attr('className',"on");
+                $("#cancel").bind('click', function(){history.go(-1);})
+            });
+        </script>
+        {% block userjs %}
+        {% endblock %}
+{% endblock %}
+{% block content %}
+<div id="main-bar" class="headNormal">
+    {{ user.username }} - {% trans "edit profile" %}
+</div>
+<div id="main-body" style="width:100%;padding-top:10px">
+    <form name="" action="{% url "edit_user" user.id user.username|slugify %}" method="post">
+        {% csrf_token %}
+        <div id="left" style="float:left;width:180px">
+            {% if user.email %}
+            {% gravatar user 128 %}
+            {% else %}
+            <img src="{% media  "/media/images/nophoto.png" %}">
+            {% endif %}
+            <div style="padding:20px 0 0 20px;font-weight:bold;font-size:150%">
+                <a href="http://www.gravatar.com/" target="_blank" 
+                    title="gravatar {% trans "image associated with your email address" %}">{% trans "gravatar" %}</a>
+            </div>
+        </div>
+
+        <div id="askform" style="float:right;width:750px;text-align:left;">
+            <h2>{% trans "Registered user" %}</h2>
+            <table class="user-details">
+                <tr>
+                    <th width="100px"></th>
+                    <th></th>
+                </tr>
+                <tr style="height:35px">
+                       <td>{% trans "Screen Name" %}:</td>
+                       <td>
+                       {% if form.username %}
+                           {{ form.username }} <span class="form-error"></span> {{ form.username.errors }}
+                       {% else %}
+                           {{ user.username }}
+                       {% endif %}
+                       </td>
+                   </tr>
+                
+                   <tr style="height:35px">
+                       <td>{{ form.email.label_tag }}:</td>
+                       <td>{{ form.email }} <span class="form-error"></span> {{ form.email.errors }} </td>
+                   </tr>
+                <tr style="height:35px">
+                       <td></td>
+                       <td class="title-desc">{{ form.email.help_text }}</td>
+                   </tr>
+                <tr style="height:35px">
+                       <td>{{ form.realname.label_tag }}:</td>
+                       <td>{{ form.realname }} <span class="form-error"></span> {{ form.realname.errors }} </td>
+                   </tr>
+                <tr style="height:35px">
+                       <td>{{ form.website.label_tag }}:</td>
+                       <td>{{ form.website }} <span class="form-error"></span> {{ form.website.errors }} </td>
+                   </tr>
+                <tr style="height:35px">
+                       <td>{{ form.city.label_tag }}:</td>
+                       <td>{{ form.city }} <span class="form-error"></span> {{ form.city.errors }} </td>
+                   </tr>
+                <tr style="height:35px">
+                       <td>{{ form.birthday.label_tag }}:</td>
+                       <td>{{ form.birthday }} <span class="form-error"></span> {{ form.birthday.errors }} </td>
+                   </tr>
+                <tr>
+                       <td style="vertical-align:top">{{ form.about.label_tag }}:</td>
+                       <td>{{ form.about }} <span class="form-error"></span> {{ form.about.errors }} </td>
+                   </tr>
+       
+            </table>
+            <div style="margin:30px 0 60px 0">
+                <input type="submit" value="{% trans "Update" %}" class="submit" >
+                <input id="cancel" type="button" value="{% trans "Cancel" %}" class="submit" >
+
+            </div>
+        </div>
+    </form>
+
+</div>
+{% endblock %}
+<!-- end user_edit.html -->
index a99691cd56a29af6071870c02de9dfb799c9a788..c7d50e51683d77b9e9ec3b9a85336c9d26e000ed 100644 (file)
@@ -4,7 +4,6 @@
 {% load humanize %}
 {% load smart_if %}
 {% load i18n %}
-{% load markup %}
 {% load user_tags %}
 
 <div id="subheader" class="headUser{% if view_user.is_suspended %} suspended-user{% endif %}">
@@ -95,7 +94,7 @@
                         {% if not view_user.email_isvalid %}
                             ({% trans "not validated" %})
                             {% ifequal request.user view_user %}
-                                </td></tr><tr><td></td><td><a href="{% url send_validation_email %}">{% trans "Send me a validation link." %}</a>
+                                </td></tr><tr><td></td><td><a href="{% url "send_validation_email" %}">{% trans "Send me a validation link." %}</a>
                             {% endifequal %}
                         {% endif %}
                     </td>
 
                 <tr>
                     <td colspan="2" style="text-align:right">
-                        <a href="{% url user_report user.pk %}" class="ajax-command withprompt">
+                        <a href="{% url "user_report" user.pk %}" class="ajax-command withprompt">
                         Report user
                         </a>
                     </td>
             {% if not view_user.is_suspended %}
             <div class="user-about">
             {% if view_user.about %}
-                {{view_user.about|markdown}}
+                {{view_user.about|static_content:"markdown-safe"}}
             {% endif %}
             </div>
             {% endif %}
index 24d213d06cb72e9dfaa44759107c7830bbf5187e..1a9e57bfd5c879b95280efdb85b4baec27999476 100644 (file)
@@ -1,8 +1,8 @@
-{% load i18n smart_if ui_registry %}\r
-\r
-<div id="user-menu-container" class="context-menu">\r
-    <span id="user-menu" class="context-menu-trigger">{% trans "User tools" %} &#9660;</span>\r
-    <ul id="user-menu-dropdown" class="context-menu-dropdown">\r
-        {% loadregistry user_menu %}{% endloadregistry %}\r
-    </ul>\r
-</div>\r
+{% load i18n smart_if ui_registry %}
+
+<div id="user-menu-container" class="context-menu">
+    <span id="user-menu" class="context-menu-trigger">{% trans "User tools" %} &#9660;</span>
+    <ul id="user-menu-dropdown" class="context-menu-dropdown">
+        {% loadregistry user_menu %}{% endloadregistry %}
+    </ul>
+</div>
index e8aebf3519d3223f761217a86af621f374c91eca..dbea26c44fe2074f617a0ec5a325d34898149085 100644 (file)
@@ -1,33 +1,33 @@
-{% load i18n extra_filters %}{% spaceless %}\r
-\r
-{% if not user.is_suspended %}\r
-    {% ifequal format "full" %}\r
-\r
-    {% else %}\r
-        <a href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>\r
-        <span class="score" title="{{ user.reputation }} {% trans "reputation" %}">{{ user.reputation|decorated_int:"" }}</span>\r
-        {% ifequal format "badges" %}\r
-            {% if user.gold %}\r
-            <span title="{{ user.gold }} {% trans "badges" %}">\r
-                <span class="badge1">&#9679;</span>\r
-                <span class="badgecount">{{ user.gold }}</span>\r
-            </span>\r
-            {% endif %}\r
-            {% if user.silver %}\r
-            <span title="{{ user.silver }} {% trans "badges" %}">\r
-                <span class="silver">&#9679;</span>\r
-                <span class="badgecount">{{ user.silver }}</span>\r
-            </span>\r
-            {% endif %}\r
-            {% if user.bronze %}\r
-            <span title="{{ user.bronze }} {% trans "badges" %}">\r
-                <span class="bronze">&#9679;</span>\r
-                <span class="badgecount">{{ user.bronze }}</span>\r
-            </span>\r
-            {% endif %}\r
-        {% endifequal %}\r
-    {% endifequal %}\r
-{% else %}\r
-    <a class="suspended-user" href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>{% trans "(suspended)" %}\r
-{% endif %}\r
-{% endspaceless %}\r
+{% load i18n extra_filters %}{% spaceless %}
+
+{% if not user.is_suspended %}
+    {% ifequal format "full" %}
+
+    {% else %}
+        <a href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>
+        <span class="score" title="{{ user.reputation }} {% trans "reputation" %}">{{ user.reputation|decorated_int:"" }}</span>
+        {% ifequal format "badges" %}
+            {% if user.gold %}
+            <span title="{{ user.gold }} {% trans "badges" %}">
+                <span class="badge1">&#9679;</span>
+                <span class="badgecount">{{ user.gold }}</span>
+            </span>
+            {% endif %}
+            {% if user.silver %}
+            <span title="{{ user.silver }} {% trans "badges" %}">
+                <span class="silver">&#9679;</span>
+                <span class="badgecount">{{ user.silver }}</span>
+            </span>
+            {% endif %}
+            {% if user.bronze %}
+            <span title="{{ user.bronze }} {% trans "badges" %}">
+                <span class="bronze">&#9679;</span>
+                <span class="badgecount">{{ user.bronze }}</span>
+            </span>
+            {% endif %}
+        {% endifequal %}
+    {% endifequal %}
+{% else %}
+    <a class="suspended-user" href="{{ user.get_absolute_url }}">{{ user.decorated_name }}</a>{% trans "(suspended)" %}
+{% endif %}
+{% endspaceless %}
index 358771dd59b912bc373ec93951daf41f07413dc8..bcc2f52bd4588800fb376d987818be900b24f68c 100644 (file)
                         <a rel="tag" 
                             class="tag-link-{{ tag.name }}"
                                                        title="{% blocktrans with tag.name as tag_name %}see other questions with {{view_user}}'s contributions tagged '{{ tag_name }}' {% endblocktrans %}"
-                                                       href="{% url tag_questions tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
+                                                       href="{% url "tag_questions" tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
                         <span class="tag-number">&#215; {{ tag.user_tag_usage_count|intcomma }}</span><br/>
                             {% if forloop.counter|divisibleby:"10" %}
                                 </td>
                     <td style="line-height:35px; padding-right: 20px;">
                         {% for award, count in awards %}
                             {% spaceless %}
-                            <a href="{% url badges %}{{award.id}}/{{award.name|slugify}}" title="{{ award.description }}" class="medal">
+                            <a href="{% url "badges" %}{{award.id}}/{{award.name|slugify}}" title="{{ award.description }}" class="medal">
                                 <span class="badge{{ award.type }}">&#9679;</span>&nbsp;{{ award.name }}
                             </a>
                             {% ifnotequal count 1 %}
index a0d921e2f77cc8358bcf7b7d05b6d1eb6d9e3eca..54a68ac119981237a283d202575beee03e9e391f 100644 (file)
@@ -6,9 +6,9 @@
         {% trans "Manage your current subscriptions" %}
         <span style="font-size:11px">
             {% if auto %}
-                <a href='{% url user_subscriptions id=view_user.id slug=view_user.username|slugify %}?auto=False&tab=manage'>{% trans "don't show auto-subscribe" %}</a>
+                <a href='{% url "user_subscriptions" id=view_user.id slug=view_user.username|slugify %}?auto=False&tab=manage'>{% trans "don't show auto-subscribe" %}</a>
             {% else %}
-                <a href='{% url user_subscriptions id=view_user.id slug=view_user.username|slugify %}?auto=True&tab=manage'>{% trans "show auto-subscribe" %}</a>
+                <a href='{% url "user_subscriptions" id=view_user.id slug=view_user.username|slugify %}?auto=True&tab=manage'>{% trans "show auto-subscribe" %}</a>
             {% endif %}
         </span>
     </h2>
index 7675db3fde47b3a6e061f3aee472abeaf11443b9..dc9db08e72d649eaf8b50e0f9703f6febaf13491 100644 (file)
-{% load i18n %}\r
-{% load extra_tags %}\r
-{% load humanize %}\r
-\r
-<h2>{% trans "Notifications and subscription settings" %}</h2>\r
-<p class="message">\r
-    {% blocktrans %}\r
-    Here you can decide which types of notifications you wish to receive, and their frequency.<br />\r
-    {% endblocktrans %}\r
-</p>\r
-<div class='inline-block'>\r
-<form method="POST">\r
-    {% csrf_token %}\r
-    {{ form.errors }}\r
-    <table class="form-as-table">\r
-        <tr>\r
-            <td colspan="2">\r
-                <strong>{% trans "Notify me when:" %}</strong>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>{% trans "A new member joins" %}</td>\r
-            <td>{{ form.member_joins }}</td>\r
-        </tr>\r
-        <tr>\r
-            <td>{% trans "A new question is posted" %}</td>\r
-            <td>{{ form.new_question }}</td>\r
-        </tr>\r
-        <tr>\r
-            <td>{% trans "A new question matching my interesting tags is posted" %}</td>\r
-            <td>{{ form.new_question_watched_tags }}</td>\r
-        </tr>\r
-        <tr>\r
-            <td>{% trans "There's an update on one of my subscriptions" %}</td>\r
-            <td >{{ form.subscribed_questions }}</td>\r
-        </tr>\r
-    </table>\r
-    <p>&nbsp;</p>\r
-    <table class="form-as-table check-table">\r
-        <tr>\r
-            <td colspan="3">\r
-                <strong>{% trans "Auto subscribe me to:" %}</strong>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                {{ form.questions_viewed }}{% trans "Questions I view" %}\r
-            </td>\r
-            <td>\r
-                {{ form.all_questions_watched_tags }}{% trans "All questions matching my interesting tags" %}\r
-            </td>\r
-            <td>\r
-                {{ form.all_questions }}{% trans "All questions" %}\r
-            </td>\r
-        </tr>\r
-    </table>\r
-    <p>&nbsp;</p>\r
-    <table class="form-as-table check-table">\r
-        <tr>\r
-            <td colspan="2">\r
-                <strong>{% trans "On my subscriptions, notify me when:" %}</strong>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                {{ form.notify_answers }}{% trans "An answer is posted" %}\r
-            </td>\r
-            <td>\r
-                {{ form.notify_comments_own_post }}{% trans "A comment on one of my posts is posted" %}\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                {{ form.notify_comments }}{% trans "A comment is posted" %}\r
-            </td>\r
-            <td>\r
-                {{ form.notify_accepted }}{% trans "An answer is accepted" %}\r
-            </td>\r
-        </tr>\r
-    </table>\r
-    <p>&nbsp;</p>\r
-    <table class="form-as-table check-table">\r
-        <tr>\r
-            <td>\r
-                <strong>{% trans "Daily Digest:" %}</strong>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                {{ form.send_digest }}{% trans "Send me the daily digest with information about the site activity" %}\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                <strong>{% trans "Notify When I'm Discussed:" %}</strong>\r
-            </td>\r
-        </tr>\r
-        <tr>\r
-            <td>\r
-                {{ form.notify_reply_to_comments }}{% trans "Notify me when someone replies to one of my comments on any post using the <pre>@username</pre> notation" %}\r
-            </td>\r
-        </tr>\r
-    </table>\r
-    <div class="submit-row">\r
-        <input type="submit" class="submit" name="save" value="{% trans "Update" %}"/>\r
-    </div>\r
-</form>\r
-</div>\r
+{% load i18n %}
+{% load extra_tags %}
+{% load humanize %}
+
+<h2>{% trans "Notifications and subscription settings" %}</h2>
+<p class="message">
+    {% blocktrans %}
+    Here you can decide which types of notifications you wish to receive, and their frequency.<br />
+    {% endblocktrans %}
+</p>
+<div class='inline-block'>
+<form method="POST">
+    {% csrf_token %}
+    {{ form.errors }}
+    <table class="form-as-table">
+        <tr>
+            <td colspan="2">
+                <strong>{% trans "Notify me when:" %}</strong>
+            </td>
+        </tr>
+        <tr>
+            <td>{% trans "A new member joins" %}</td>
+            <td>{{ form.member_joins }}</td>
+        </tr>
+        <tr>
+            <td>{% trans "A new question is posted" %}</td>
+            <td>{{ form.new_question }}</td>
+        </tr>
+        <tr>
+            <td>{% trans "A new question matching my interesting tags is posted" %}</td>
+            <td>{{ form.new_question_watched_tags }}</td>
+        </tr>
+        <tr>
+            <td>{% trans "There's an update on one of my subscriptions" %}</td>
+            <td >{{ form.subscribed_questions }}</td>
+        </tr>
+    </table>
+    <p>&nbsp;</p>
+    <table class="form-as-table check-table">
+        <tr>
+            <td colspan="3">
+                <strong>{% trans "Auto subscribe me to:" %}</strong>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                {{ form.questions_viewed }}{% trans "Questions I view" %}
+            </td>
+            <td>
+                {{ form.all_questions_watched_tags }}{% trans "All questions matching my interesting tags" %}
+            </td>
+            <td>
+                {{ form.all_questions }}{% trans "All questions" %}
+            </td>
+        </tr>
+    </table>
+    <p>&nbsp;</p>
+    <table class="form-as-table check-table">
+        <tr>
+            <td colspan="2">
+                <strong>{% trans "On my subscriptions, notify me when:" %}</strong>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                {{ form.notify_answers }}{% trans "An answer is posted" %}
+            </td>
+            <td>
+                {{ form.notify_comments_own_post }}{% trans "A comment on one of my posts is posted" %}
+            </td>
+        </tr>
+        <tr>
+            <td>
+                {{ form.notify_comments }}{% trans "A comment is posted" %}
+            </td>
+            <td>
+                {{ form.notify_accepted }}{% trans "An answer is accepted" %}
+            </td>
+        </tr>
+    </table>
+    <p>&nbsp;</p>
+    <table class="form-as-table check-table">
+        <tr>
+            <td>
+                <strong>{% trans "Daily Digest:" %}</strong>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                {{ form.send_digest }}{% trans "Send me the daily digest with information about the site activity" %}
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <strong>{% trans "Notify When I'm Discussed:" %}</strong>
+            </td>
+        </tr>
+        <tr>
+            <td>
+                {{ form.notify_reply_to_comments }}{% trans "Notify me when someone replies to one of my comments on any post using the <pre>@username</pre> notation" %}
+            </td>
+        </tr>
+    </table>
+    <div class="submit-row">
+        <input type="submit" class="submit" name="save" value="{% trans "Update" %}"/>
+    </div>
+</form>
+</div>
index 56a0b8b634c75969412bcaf378551fd7150302f3..de87a645260ee3ac8a56d51baac95829330d9f87 100644 (file)
@@ -1,7 +1,7 @@
-import re\r
-\r
-splitter = re.compile(r'\s*=\s*')\r
-matcher = re.compile(r'^.+=.+$')\r
-\r
-def argument_parser(arguments):\r
+import re
+
+splitter = re.compile(r'\s*=\s*')
+matcher = re.compile(r'^.+=.+$')
+
+def argument_parser(arguments):
     return dict(splitter.split(s) for s in arguments if matcher.match(s))
\ No newline at end of file
index 8dea68c9c0d4c3c944c526450ba4fcafb73064e5..01e550187414c2065c751cef49dfbf479a1605c2 100644 (file)
@@ -57,7 +57,9 @@ def contained_in(item, container):
 def static_content(content, render_mode):
     if render_mode == 'markdown':
         return mark_safe(markdown.markdown(unicode(content), ["settingsparser"]))
+    elif render_mode == 'markdown-safe':
+        return mark_safe(markdown.markdown(unicode(content), safe_mode=True))
     elif render_mode == "html":
         return mark_safe(unicode(content))
     else:
-        return unicode(content)
\ No newline at end of file
+        return unicode(content)
index 1acb96993cb312500f6ffe16d977e4709d1c6c1d..02260079f19b13d1099eed8714bac7a33396b610 100644 (file)
@@ -13,7 +13,6 @@ from django.utils import dateformat
 from forum.models import Question, Answer, QuestionRevision, AnswerRevision, NodeRevision
 from django.utils.translation import ugettext as _
 from django.utils.translation import ungettext
-from django.utils import simplejson
 from forum import settings
 from django.template.defaulttags import url as default_url
 from forum import skins
index 2f70fa2c62fa2b31dde5137646dde20bfcd7f232..ea8309982915e06e698ce697f58e1815e2b43cb0 100644 (file)
@@ -1,39 +1,39 @@
-from django import template\r
-from forum.models import Tag, Award\r
-from forum import settings\r
-\r
-from extra_filters import static_content\r
-\r
-register = template.Library()\r
-\r
-@register.inclusion_tag('sidebar/markdown_help.html')\r
-def markdown_help():\r
-    return {}\r
-\r
-@register.inclusion_tag('sidebar/recent_awards.html')\r
-def recent_awards():\r
-    return {'awards': Award.objects.order_by('-awarded_at')[:settings.RECENT_AWARD_SIZE]}\r
-\r
-@register.inclusion_tag('sidebar/user_blocks.html')\r
-def sidebar_upper():\r
-    return {\r
-        'show': settings.SIDEBAR_UPPER_SHOW,\r
-        'content': static_content(settings.SIDEBAR_UPPER_TEXT, settings.SIDEBAR_UPPER_RENDER_MODE),\r
-        'wrap': not settings.SIDEBAR_UPPER_DONT_WRAP,\r
-        'blockid': 'sidebar-upper'\r
-    }\r
-\r
-@register.inclusion_tag('sidebar/user_blocks.html')\r
-def sidebar_lower():\r
-    return {\r
-        'show': settings.SIDEBAR_LOWER_SHOW,\r
-        'content': static_content(settings.SIDEBAR_LOWER_TEXT, settings.SIDEBAR_LOWER_RENDER_MODE),\r
-        'wrap': not settings.SIDEBAR_LOWER_DONT_WRAP,\r
-        'blockid': 'sidebar-lower'\r
-    }\r
-\r
-@register.inclusion_tag('sidebar/recent_tags.html')\r
-def recent_tags():\r
-    return {'tags': Tag.active.order_by('-id')[:settings.RECENT_TAGS_SIZE]}\r
-\r
+from django import template
+from forum.models import Tag, Award
+from forum import settings
+
+from extra_filters import static_content
+
+register = template.Library()
+
+@register.inclusion_tag('sidebar/markdown_help.html')
+def markdown_help():
+    return {}
+
+@register.inclusion_tag('sidebar/recent_awards.html')
+def recent_awards():
+    return {'awards': Award.objects.order_by('-awarded_at')[:settings.RECENT_AWARD_SIZE]}
+
+@register.inclusion_tag('sidebar/user_blocks.html')
+def sidebar_upper():
+    return {
+        'show': settings.SIDEBAR_UPPER_SHOW,
+        'content': static_content(settings.SIDEBAR_UPPER_TEXT, settings.SIDEBAR_UPPER_RENDER_MODE),
+        'wrap': not settings.SIDEBAR_UPPER_DONT_WRAP,
+        'blockid': 'sidebar-upper'
+    }
+
+@register.inclusion_tag('sidebar/user_blocks.html')
+def sidebar_lower():
+    return {
+        'show': settings.SIDEBAR_LOWER_SHOW,
+        'content': static_content(settings.SIDEBAR_LOWER_TEXT, settings.SIDEBAR_LOWER_RENDER_MODE),
+        'wrap': not settings.SIDEBAR_LOWER_DONT_WRAP,
+        'blockid': 'sidebar-lower'
+    }
+
+@register.inclusion_tag('sidebar/recent_tags.html')
+def recent_tags():
+    return {'tags': Tag.active.order_by('-id')[:settings.RECENT_TAGS_SIZE]}
+
     
\ No newline at end of file
index be54232f8e44e35a1921ca1fb8e099bef60196c5..ff63ec84350ed3c5929dab371ca0352db0987350 100644 (file)
-from datetime import datetime, timedelta\r
-import re\r
-\r
-from forum.models import Question, Action\r
-from django.template import Template, Context\r
-from django.utils.translation import ungettext, ugettext as _\r
-from django.utils.html import strip_tags\r
-from django.utils.encoding import smart_unicode\r
-from django.utils.safestring import mark_safe\r
-from django.conf import settings as django_settings\r
-from django.core.urlresolvers import reverse\r
-from django import template\r
-from forum.actions import *\r
-from forum import settings\r
-\r
-register = template.Library()\r
-\r
-@register.inclusion_tag('node/vote_buttons.html')\r
-def vote_buttons(post, user):\r
-    context = dict(post=post, user_vote='none')\r
-\r
-    if user.is_authenticated():\r
-        context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]\r
-\r
-    return context\r
-\r
-@register.inclusion_tag('node/accept_button.html')\r
-def accept_button(answer, user):\r
-    if not settings.DISABLE_ACCEPTING_FEATURE:\r
-        return {\r
-            'can_accept': user.is_authenticated() and user.can_accept_answer(answer),\r
-            'answer': answer,\r
-            'user': user\r
-        }\r
-    else:\r
-        return ''\r
-\r
-@register.inclusion_tag('node/wiki_symbol.html')\r
-def wiki_symbol(user, post):\r
-    context = {\r
-        'is_wiki': post.nis.wiki,\r
-        'post_type': post.friendly_name\r
-    }\r
-\r
-    if post.nis.wiki:\r
-        if user.can_edit_post(post):\r
-            context['can_edit'] = True\r
-            context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})\r
-        context['by'] = post.nstate.wiki.by.username\r
-        context['at'] = post.nstate.wiki.at\r
-\r
-    return context\r
-\r
-@register.inclusion_tag('node/favorite_mark.html')\r
-def favorite_mark(question, user):\r
-    try:\r
-        FavoriteAction.objects.get(canceled=False, node=question, user=user)\r
-        favorited = True\r
-    except:\r
-        favorited = False\r
-\r
-    return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}\r
-\r
-@register.simple_tag\r
-def post_classes(post):\r
-    classes = []\r
-\r
-    if post.nis.deleted:\r
-        classes.append('deleted')\r
-\r
-    if post.node_type == "answer":\r
-        if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:\r
-            classes.append('accepted-answer')\r
-\r
-        if post.author == post.question.author:\r
-            classes.append('answered-by-owner')\r
-\r
-    return " ".join(classes)\r
-\r
-def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):\r
-    classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \\r
-        (copy and " copy" or " ")\r
-\r
-    for extra_class in extra_classes:\r
-        classes += " %s" % extra_class\r
-\r
-    return {'text': text, 'url': url, 'classes': classes, 'title': title}\r
-\r
-\r
-moderation_enabled = False\r
-for m in django_settings.MODULE_LIST:\r
-    if m.__name__.endswith('moderation'):\r
-        moderation_enabled = True\r
-\r
-@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")\r
-def post_controls(post, user):\r
-    controls = []\r
-    menu = []\r
-    post_type = post.node_type\r
-\r
-    # We show the link tool if the post is an Answer. It is visible to Guests too.\r
-    if post_type == "answer":\r
-        # Answer permanent link tool\r
-        controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),\r
-                                     title=_("answer permanent link"), command=True, withprompt=True, copy=True))\r
-\r
-        # Users should be able to award points for an answer. Users cannot award their own answers\r
-        if user != post.author and user.is_authenticated() and user.reputation > 1:\r
-            controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,\r
-                                         'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),\r
-                                         command=True, withprompt=True))\r
-\r
-    # The other controls are visible only to authenticated users.\r
-    if user.is_authenticated():\r
-        try:\r
-            edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})\r
-            if user.can_edit_post(post):\r
-                controls.append(post_control(_('edit'), edit_url))\r
-            elif post_type == 'question' and user.can_retag_questions():\r
-                controls.append(post_control(_('retag'), edit_url))\r
-        except:\r
-            pass\r
-\r
-        if post_type == 'question':\r
-            if post.nis.closed and user.can_reopen_question(post):\r
-                controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))\r
-            elif not post.nis.closed and user.can_close_question(post):\r
-                controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))\r
-\r
-        if user.can_flag_offensive(post):\r
-            label = _('report')\r
-            \r
-            if user.can_view_offensive_flags(post):\r
-                label =  "%s (%d)" % (label, post.flag_count)\r
-\r
-\r
-            report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),\r
-                    command=True, withprompt=True,\r
-                    title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))\r
-\r
-            # Depending on the setting choose where to attach the control\r
-            if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":\r
-                menu.append(report_control)\r
-            else:\r
-                controls.append(report_control)\r
-\r
-        if user.can_delete_post(post):\r
-            if post.nis.deleted:\r
-                controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),\r
-                        command=True, confirm=True))\r
-            else:\r
-                controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),\r
-                        command=True, confirm=True))\r
-\r
-        if user.can_delete_post(post):\r
-            menu.append(post_control(_('see revisions'),\r
-                        reverse('revisions',\r
-                        kwargs={'id': post.id}),\r
-                        command=False, confirm=False))\r
-\r
-        if settings.WIKI_ON:\r
-            if (not post.nis.wiki) and user.can_wikify(post):\r
-                menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
-                            command=True, confirm=True))\r
-\r
-            elif post.nis.wiki and user.can_cancel_wiki(post):\r
-                menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),\r
-                            command=True, confirm=True))\r
-\r
-        if post.node_type == "answer" and user.can_convert_to_comment(post):\r
-            menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),\r
-                        command=True, withprompt=True))\r
-        \r
-        if post.node_type == "answer" and user.can_convert_to_question(post):\r
-            menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),\r
-                        command=False, confirm=True))\r
-\r
-        if user.is_superuser or user.is_staff:\r
-            plain_text = strip_tags(post.html)\r
-\r
-            char_count = len(plain_text)\r
-            fullStr = plain_text + " "\r
-            left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)\r
-            cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)\r
-            splitString = cleanedStr.split(" ")\r
-            word_count = len(splitString) - 1\r
-\r
-            metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),\r
-                                        word_count, ungettext('word', 'words', word_count)))\r
-\r
-            menu.append(post_control(metrics, "#", command=False, withprompt=False))\r
-\r
-    return {'controls': controls, 'menu': menu, 'post': post, 'user': user}\r
-\r
-def _comments(post, user):\r
-    all_comments = post.comments.filter_state(deleted=False)\\r
-                                .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')\r
-\r
-    if len(all_comments) <= 5:\r
-        top_scorers = all_comments\r
-    else:\r
-        top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]\r
-\r
-    comments = []\r
-    showing = 0\r
-    for c in all_comments:\r
-        context = {\r
-            'can_delete': user.can_delete_comment(c),\r
-            'can_like': user.can_like_comment(c),\r
-            'can_edit': user.can_edit_comment(c),\r
-            'can_convert': user.can_convert_comment_to_answer(c)\r
-        }\r
-\r
-        if c in top_scorers or c.is_reply_to(user):\r
-            context['top_scorer'] = True\r
-            showing += 1\r
-        \r
-        if context['can_like']:\r
-            context['likes'] = VoteAction.get_for(user, c) == 1\r
-\r
-        context['user'] = c.user\r
-        context['comment'] = c.comment\r
-        context.update(dict(c.__dict__))\r
-        comments.append(context)\r
-\r
-    # Generate canned comments\r
-    canned_comments = []\r
-    for comment in settings.CANNED_COMMENTS:\r
-        t = Template(smart_unicode(comment))\r
-        c = Context({\r
-            'post' : post,\r
-            'settings' : settings,\r
-        })\r
-        canned_comments.append(t.render(c))\r
-\r
-    total = len(all_comments)\r
-    return {\r
-        'comments': comments,\r
-        'canned_comments': canned_comments,\r
-        'post': post,\r
-        'can_comment': user.can_comment(post),\r
-        'max_length': settings.FORM_MAX_COMMENT_BODY,\r
-        'min_length': settings.FORM_MIN_COMMENT_BODY,\r
-        'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,\r
-        'showing': showing,\r
-        'total': total,\r
-        'more_comments_count' : int(total - showing),\r
-        'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,\r
-        'user': user,\r
-    }\r
-\r
-@register.inclusion_tag('node/comments.html')\r
-def comments(post, user):\r
-    return _comments(post, user)\r
-\r
-@register.inclusion_tag("node/contributors_info.html", takes_context=True)\r
-def contributors_info(context, node, verb=None):\r
-    return {\r
-        'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (\r
-                    (node.node_type == "answer") and _("answered") or _("posted"))),\r
-        'node': node,\r
-        'context' : context\r
-    }\r
-\r
-@register.inclusion_tag("node/reviser_info.html")\r
-def reviser_info(revision):\r
-    return {'revision': revision}\r
+from datetime import datetime, timedelta
+import re
+
+from forum.models import Question, Action
+from django.template import Template, Context
+from django.utils.translation import ungettext, ugettext as _
+from django.utils.html import strip_tags
+from django.utils.encoding import smart_unicode
+from django.utils.safestring import mark_safe
+from django.conf import settings as django_settings
+from django.core.urlresolvers import reverse
+from django import template
+from forum.actions import *
+from forum import settings
+
+register = template.Library()
+
+@register.inclusion_tag('node/vote_buttons.html')
+def vote_buttons(post, user):
+    context = dict(post=post, user_vote='none')
+
+    if user.is_authenticated():
+        context['user_vote'] = {1: 'up', -1: 'down', None: 'none'}[VoteAction.get_for(user, post)]
+
+    return context
+
+@register.inclusion_tag('node/accept_button.html')
+def accept_button(answer, user):
+    if not settings.DISABLE_ACCEPTING_FEATURE:
+        return {
+            'can_accept': user.is_authenticated() and user.can_accept_answer(answer),
+            'answer': answer,
+            'user': user
+        }
+    else:
+        return ''
+
+@register.inclusion_tag('node/wiki_symbol.html')
+def wiki_symbol(user, post):
+    context = {
+        'is_wiki': post.nis.wiki,
+        'post_type': post.friendly_name
+    }
+
+    if post.nis.wiki:
+        if user.can_edit_post(post):
+            context['can_edit'] = True
+            context['edit_url'] = reverse('edit_' + post.node_type, kwargs={'id': post.id})
+        context['by'] = post.nstate.wiki.by.username
+        context['at'] = post.nstate.wiki.at
+
+    return context
+
+@register.inclusion_tag('node/favorite_mark.html')
+def favorite_mark(question, user):
+    try:
+        FavoriteAction.objects.get(canceled=False, node=question, user=user)
+        favorited = True
+    except:
+        favorited = False
+
+    return {'favorited': favorited, 'favorite_count': question.favorite_count, 'question': question}
+
+@register.simple_tag
+def post_classes(post):
+    classes = []
+
+    if post.nis.deleted:
+        classes.append('deleted')
+
+    if post.node_type == "answer":
+        if (not settings.DISABLE_ACCEPTING_FEATURE) and post.nis.accepted:
+            classes.append('accepted-answer')
+
+        if post.author == post.question.author:
+            classes.append('answered-by-owner')
+
+    return " ".join(classes)
+
+def post_control(text, url, command=False, withprompt=False, confirm=False, title="", copy=False, extra_classes=[]):
+    classes = (command and "ajax-command" or " ") + (withprompt and " withprompt" or " ") + (confirm and " confirm" or " ") + \
+        (copy and " copy" or " ")
+
+    for extra_class in extra_classes:
+        classes += " %s" % extra_class
+
+    return {'text': text, 'url': url, 'classes': classes, 'title': title}
+
+
+moderation_enabled = False
+for m in django_settings.MODULE_LIST:
+    if m.__name__.endswith('moderation'):
+        moderation_enabled = True
+
+@register.inclusion_tag('node/post_controls.html' if not moderation_enabled else "modules/moderation/node/post_controls.html")
+def post_controls(post, user):
+    controls = []
+    menu = []
+    post_type = post.node_type
+
+    # We show the link tool if the post is an Answer. It is visible to Guests too.
+    if post_type == "answer":
+        # Answer permanent link tool
+        controls.append(post_control(_('permanent link'), reverse('answer_permanent_link', kwargs={'id' : post.id,}),
+                                     title=_("answer permanent link"), command=True, withprompt=True, copy=True))
+
+        # Users should be able to award points for an answer. Users cannot award their own answers
+        if user != post.author and user.is_authenticated() and user.reputation > 1:
+            controls.append(post_control(_("award points"), reverse('award_points', kwargs={'user_id' : post.author.id,
+                                         'answer_id' : post.id}), title=_("award points to %s") % smart_unicode(post.author.username),
+                                         command=True, withprompt=True))
+
+    # The other controls are visible only to authenticated users.
+    if user.is_authenticated():
+        try:
+            edit_url = reverse('edit_' + post_type, kwargs={'id': post.id})
+            if user.can_edit_post(post):
+                controls.append(post_control(_('edit'), edit_url))
+            elif post_type == 'question' and user.can_retag_questions():
+                controls.append(post_control(_('retag'), edit_url))
+        except:
+            pass
+
+        if post_type == 'question':
+            if post.nis.closed and user.can_reopen_question(post):
+                controls.append(post_control(_('reopen'), reverse('reopen', kwargs={'id': post.id}), command=True))
+            elif not post.nis.closed and user.can_close_question(post):
+                controls.append(post_control(_('close'), reverse('close', kwargs={'id': post.id}), command=True, withprompt=True))
+
+        if user.can_flag_offensive(post):
+            label = _('report')
+            
+            if user.can_view_offensive_flags(post):
+                label =  "%s (%d)" % (label, post.flag_count)
+
+
+            report_control = post_control(label, reverse('flag_post', kwargs={'id': post.id}),
+                    command=True, withprompt=True,
+                    title=_("report as offensive (i.e containing spam, advertising, malicious text, etc.)"))
+
+            # Depending on the setting choose where to attach the control
+            if settings.REPORT_OFFENSIVE_CONTROL_POSITION.value == "more":
+                menu.append(report_control)
+            else:
+                controls.append(report_control)
+
+        if user.can_delete_post(post):
+            if post.nis.deleted:
+                controls.append(post_control(_('undelete'), reverse('delete_post', kwargs={'id': post.id}),
+                        command=True, confirm=True))
+            else:
+                controls.append(post_control(_('delete'), reverse('delete_post', kwargs={'id': post.id}),
+                        command=True, confirm=True))
+
+        if user.can_delete_post(post):
+            menu.append(post_control(_('see revisions'),
+                        reverse('revisions',
+                        kwargs={'id': post.id}),
+                        command=False, confirm=False))
+
+        if settings.WIKI_ON:
+            if (not post.nis.wiki) and user.can_wikify(post):
+                menu.append(post_control(_('mark as community wiki'), reverse('wikify', kwargs={'id': post.id}),
+                            command=True, confirm=True))
+
+            elif post.nis.wiki and user.can_cancel_wiki(post):
+                menu.append(post_control(_('cancel community wiki'), reverse('wikify', kwargs={'id': post.id}),
+                            command=True, confirm=True))
+
+        if post.node_type == "answer" and user.can_convert_to_comment(post):
+            menu.append(post_control(_('convert to comment'), reverse('convert_to_comment', kwargs={'id': post.id}),
+                        command=True, withprompt=True))
+        
+        if post.node_type == "answer" and user.can_convert_to_question(post):
+            menu.append(post_control(_('convert to question'), reverse('convert_to_question', kwargs={'id': post.id}),
+                        command=False, confirm=True))
+
+        if user.is_superuser or user.is_staff:
+            plain_text = strip_tags(post.html)
+
+            char_count = len(plain_text)
+            fullStr = plain_text + " "
+            left_trimmedStr = re.sub(re.compile(r"^[^\w]+", re.IGNORECASE), "", fullStr)
+            cleanedStr = re.sub(re.compile(r"[^\w]+", re.IGNORECASE), " ", left_trimmedStr)
+            splitString = cleanedStr.split(" ")
+            word_count = len(splitString) - 1
+
+            metrics = mark_safe("<b>%s %s / %s %s</b>" % (char_count, ungettext('character', 'characters', char_count),
+                                        word_count, ungettext('word', 'words', word_count)))
+
+            menu.append(post_control(metrics, "#", command=False, withprompt=False))
+
+    return {'controls': controls, 'menu': menu, 'post': post, 'user': user}
+
+def _comments(post, user):
+    all_comments = post.comments.filter_state(deleted=False)\
+                                .order_by('-added_at' if settings.SHOW_LATEST_COMMENTS_FIRST else 'added_at')
+
+    if len(all_comments) <= 5:
+        top_scorers = all_comments
+    else:
+        top_scorers = sorted(all_comments, lambda c1, c2: cmp(c2.score, c1.score))[0:5]
+
+    comments = []
+    showing = 0
+    for c in all_comments:
+        context = {
+            'can_delete': user.can_delete_comment(c),
+            'can_like': user.can_like_comment(c),
+            'can_edit': user.can_edit_comment(c),
+            'can_convert': user.can_convert_comment_to_answer(c)
+        }
+
+        if c in top_scorers or c.is_reply_to(user):
+            context['top_scorer'] = True
+            showing += 1
+        
+        if context['can_like']:
+            context['likes'] = VoteAction.get_for(user, c) == 1
+
+        context['user'] = c.user
+        context['comment'] = c.comment
+        context.update(dict(c.__dict__))
+        comments.append(context)
+
+    # Generate canned comments
+    canned_comments = []
+    for comment in settings.CANNED_COMMENTS:
+        t = Template(smart_unicode(comment))
+        c = Context({
+            'post' : post,
+            'settings' : settings,
+        })
+        canned_comments.append(t.render(c))
+
+    total = len(all_comments)
+    return {
+        'comments': comments,
+        'canned_comments': canned_comments,
+        'post': post,
+        'can_comment': user.can_comment(post),
+        'max_length': settings.FORM_MAX_COMMENT_BODY,
+        'min_length': settings.FORM_MIN_COMMENT_BODY,
+        'show_gravatar': settings.FORM_GRAVATAR_IN_COMMENTS,
+        'showing': showing,
+        'total': total,
+        'more_comments_count' : int(total - showing),
+        'show_latest_comments_first' : settings.SHOW_LATEST_COMMENTS_FIRST,
+        'user': user,
+    }
+
+@register.inclusion_tag('node/comments.html')
+def comments(post, user):
+    return _comments(post, user)
+
+@register.inclusion_tag("node/contributors_info.html", takes_context=True)
+def contributors_info(context, node, verb=None):
+    return {
+        'node_verb': verb and verb or ((node.node_type == "question") and _("asked") or (
+                    (node.node_type == "answer") and _("answered") or _("posted"))),
+        'node': node,
+        'context' : context
+    }
+
+@register.inclusion_tag("node/reviser_info.html")
+def reviser_info(revision):
+    return {'revision': revision}
index 2f2aef9cf8c58948a57c0922ec68ee40a5b04344..2447cd11e2f2f9a59cf49e39672213fb554f0cfd 100644 (file)
@@ -1,81 +1,81 @@
-from django import template\r
-from django.utils.translation import ugettext as _\r
-from django.utils.safestring import mark_safe\r
-from forum.models import Tag, MarkedTag\r
-from forum.templatetags import argument_parser\r
-from forum import settings\r
-\r
-register = template.Library()\r
-\r
-class QuestionItemNode(template.Node):\r
-    template = template.loader.get_template('question_list/item.html')\r
-\r
-    def __init__(self, question, options):\r
-        self.question = template.Variable(question)\r
-        self.options = options\r
-\r
-    def render(self, context):\r
-        return self.template.render(template.Context({\r
-            'question': self.question.resolve(context),\r
-            'question_summary': self.options.get('question_summary', 'no' ) == 'yes',\r
-            'favorite_count': self.options.get('favorite_count', 'no') == 'yes',\r
-            'signature_type': self.options.get('signature_type', 'lite'),\r
-        }))\r
-\r
-class SubscriptionItemNode(template.Node):\r
-    template = template.loader.get_template('question_list/subscription_item.html')\r
-\r
-    def __init__(self, subscription, question, options):\r
-        self.question = template.Variable(question)\r
-        self.subscription = template.Variable(subscription)\r
-        self.options = options\r
-\r
-    def render(self, context):\r
-        return self.template.render(template.Context({\r
-            'question': self.question.resolve(context),\r
-            'subscription': self.subscription.resolve(context),\r
-            'signature_type': self.options.get('signature_type', 'lite'),\r
-        }))\r
-\r
-@register.tag\r
-def question_list_item(parser, token):\r
-    tokens = token.split_contents()[1:]\r
-    return QuestionItemNode(tokens[0], argument_parser(tokens[1:]))\r
-\r
-@register.tag\r
-def subscription_list_item(parser, token):\r
-    tokens = token.split_contents()[1:]\r
-    return SubscriptionItemNode(tokens[0], tokens[1], argument_parser(tokens[2:]))\r
-\r
-@register.inclusion_tag('question_list/sort_tabs.html')\r
-def question_sort_tabs(sort_context):\r
-    return sort_context\r
-\r
-@register.inclusion_tag('question_list/related_tags.html')\r
-def question_list_related_tags(questions):\r
-    if len(questions):\r
-        tags = Tag.objects.filter(nodes__id__in=[q.id for q in questions]).distinct()\r
-\r
-        if settings.LIMIT_RELATED_TAGS:\r
-            tags = tags[:settings.LIMIT_RELATED_TAGS]\r
-\r
-        return {'tags': tags}\r
-    else:\r
-        return {'tags': False}\r
-\r
-@register.inclusion_tag('question_list/tag_selector.html', takes_context=True)\r
-def tag_selector(context):\r
-    request = context['request']\r
-    show_interesting_tags = settings.SHOW_INTERESTING_TAGS_BOX\r
-\r
-    if request.user.is_authenticated():\r
-        pt = MarkedTag.objects.filter(user=request.user)\r
-        return {\r
-            'request' : request,\r
-            "interesting_tag_names": pt.filter(reason='good').values_list('tag__name', flat=True),\r
-            'ignored_tag_names': pt.filter(reason='bad').values_list('tag__name', flat=True),\r
-            'user_authenticated': True,\r
-            'show_interesting_tags' : show_interesting_tags,\r
-        }\r
-    else:\r
-        return { 'request' : request, 'user_authenticated': False, 'show_interesting_tags' : show_interesting_tags }\r
+from django import template
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+from forum.models import Tag, MarkedTag
+from forum.templatetags import argument_parser
+from forum import settings
+
+register = template.Library()
+
+class QuestionItemNode(template.Node):
+    template = template.loader.get_template('question_list/item.html')
+
+    def __init__(self, question, options):
+        self.question = template.Variable(question)
+        self.options = options
+
+    def render(self, context):
+        return self.template.render(template.Context({
+            'question': self.question.resolve(context),
+            'question_summary': self.options.get('question_summary', 'no' ) == 'yes',
+            'favorite_count': self.options.get('favorite_count', 'no') == 'yes',
+            'signature_type': self.options.get('signature_type', 'lite'),
+        }))
+
+class SubscriptionItemNode(template.Node):
+    template = template.loader.get_template('question_list/subscription_item.html')
+
+    def __init__(self, subscription, question, options):
+        self.question = template.Variable(question)
+        self.subscription = template.Variable(subscription)
+        self.options = options
+
+    def render(self, context):
+        return self.template.render(template.Context({
+            'question': self.question.resolve(context),
+            'subscription': self.subscription.resolve(context),
+            'signature_type': self.options.get('signature_type', 'lite'),
+        }))
+
+@register.tag
+def question_list_item(parser, token):
+    tokens = token.split_contents()[1:]
+    return QuestionItemNode(tokens[0], argument_parser(tokens[1:]))
+
+@register.tag
+def subscription_list_item(parser, token):
+    tokens = token.split_contents()[1:]
+    return SubscriptionItemNode(tokens[0], tokens[1], argument_parser(tokens[2:]))
+
+@register.inclusion_tag('question_list/sort_tabs.html')
+def question_sort_tabs(sort_context):
+    return sort_context
+
+@register.inclusion_tag('question_list/related_tags.html')
+def question_list_related_tags(questions):
+    if len(questions):
+        tags = Tag.objects.filter(nodes__id__in=[q.id for q in questions]).distinct()
+
+        if settings.LIMIT_RELATED_TAGS:
+            tags = tags[:settings.LIMIT_RELATED_TAGS]
+
+        return {'tags': tags}
+    else:
+        return {'tags': False}
+
+@register.inclusion_tag('question_list/tag_selector.html', takes_context=True)
+def tag_selector(context):
+    request = context['request']
+    show_interesting_tags = settings.SHOW_INTERESTING_TAGS_BOX
+
+    if request.user.is_authenticated():
+        pt = MarkedTag.objects.filter(user=request.user)
+        return {
+            'request' : request,
+            "interesting_tag_names": pt.filter(reason='good').values_list('tag__name', flat=True),
+            'ignored_tag_names': pt.filter(reason='bad').values_list('tag__name', flat=True),
+            'user_authenticated': True,
+            'show_interesting_tags' : show_interesting_tags,
+        }
+    else:
+        return { 'request' : request, 'user_authenticated': False, 'show_interesting_tags' : show_interesting_tags }
index 2bc4385f8f0cf35379e8304d156361d8811ec97d..d16153dd322b4b9e1fab8ccdfda1a3faf2e3a9cb 100644 (file)
@@ -1,74 +1,74 @@
-from django import template\r
-from django.utils.translation import ugettext as _\r
-from django.utils.safestring import mark_safe\r
-import logging\r
-\r
-register = template.Library()\r
-\r
-class UserSignatureNode(template.Node):\r
-    template = template.loader.get_template('users/signature.html')\r
-\r
-    def __init__(self, user, format):\r
-        self.user = template.Variable(user)\r
-        self.format = template.Variable(format)\r
-\r
-    def render(self, context):\r
-        return self.template.render(template.Context({\r
-        'user': self.user.resolve(context),\r
-        'format': self.format.resolve(context)\r
-        }))\r
-\r
-@register.tag\r
-def user_signature(parser, token):\r
-    try:\r
-        tag_name, user, format = token.split_contents()\r
-    except ValueError:\r
-        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
-    return UserSignatureNode(user, format)\r
-\r
-\r
-class ActivityNode(template.Node):\r
-    template = template.loader.get_template('users/activity.html')\r
-\r
-    def __init__(self, activity, viewer):\r
-        self.activity = template.Variable(activity)\r
-        self.viewer = template.Variable(viewer)\r
-\r
-    def render(self, context):\r
-        try:\r
-            action = self.activity.resolve(context).leaf\r
-            viewer = self.viewer.resolve(context)\r
-            describe = mark_safe(action.describe(viewer))\r
-            return self.template.render(template.Context(dict(action=action, describe=describe)))\r
-        except Exception, e:\r
-            import traceback\r
-            msg = "Error in action describe: \n %s" % (\r
-                traceback.format_exc()\r
-            )\r
-            logging.error(msg)\r
-\r
-@register.tag\r
-def activity_item(parser, token):\r
-    try:\r
-        tag_name, activity, viewer = token.split_contents()\r
-    except ValueError:\r
-        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
-    return ActivityNode(activity, viewer)\r
-\r
-\r
-@register.tag\r
-def flagged_item(parser, token):\r
-    try:\r
-        tag_name, post, viewer = token.split_contents()\r
-    except ValueError:\r
-        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]\r
-\r
-    return ActivityNode(post, viewer)\r
-\r
-\r
-@register.inclusion_tag('users/menu.html')\r
-def user_menu(viewer, user):\r
-    return dict(viewer=viewer, user=user)\r
-\r
+from django import template
+from django.utils.translation import ugettext as _
+from django.utils.safestring import mark_safe
+import logging
+
+register = template.Library()
+
+class UserSignatureNode(template.Node):
+    template = template.loader.get_template('users/signature.html')
+
+    def __init__(self, user, format):
+        self.user = template.Variable(user)
+        self.format = template.Variable(format)
+
+    def render(self, context):
+        return self.template.render(template.Context({
+        'user': self.user.resolve(context),
+        'format': self.format.resolve(context)
+        }))
+
+@register.tag
+def user_signature(parser, token):
+    try:
+        tag_name, user, format = token.split_contents()
+    except ValueError:
+        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+    return UserSignatureNode(user, format)
+
+
+class ActivityNode(template.Node):
+    template = template.loader.get_template('users/activity.html')
+
+    def __init__(self, activity, viewer):
+        self.activity = template.Variable(activity)
+        self.viewer = template.Variable(viewer)
+
+    def render(self, context):
+        try:
+            action = self.activity.resolve(context).leaf
+            viewer = self.viewer.resolve(context)
+            describe = mark_safe(action.describe(viewer))
+            return self.template.render(template.Context(dict(action=action, describe=describe)))
+        except Exception, e:
+            import traceback
+            msg = "Error in action describe: \n %s" % (
+                traceback.format_exc()
+            )
+            logging.error(msg)
+
+@register.tag
+def activity_item(parser, token):
+    try:
+        tag_name, activity, viewer = token.split_contents()
+    except ValueError:
+        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+    return ActivityNode(activity, viewer)
+
+
+@register.tag
+def flagged_item(parser, token):
+    try:
+        tag_name, post, viewer = token.split_contents()
+    except ValueError:
+        raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+
+    return ActivityNode(post, viewer)
+
+
+@register.inclusion_tag('users/menu.html')
+def user_menu(viewer, user):
+    return dict(viewer=viewer, user=user)
+
index 380d6b36fda33b771aea5cacfb19ce438a4a2a4e..22b8fab280b8fdf623d2f6b78a27c9779788c971 100644 (file)
@@ -2,7 +2,7 @@ import startup
 
 import os.path
 from forum import settings
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
 from django.conf import settings as djsettings
 from django.contrib import admin
 from forum import views as app
@@ -18,11 +18,6 @@ sitemaps = {
 
 APP_PATH = os.path.dirname(__file__)
 
-try:
-    admin_url = url(r'^%s(.*)' % _('nimda/'), admin.site.root)
-except AttributeError:
-    admin_url = url(r'^%s(.*)' % _('nimda/'), admin.site.urls)
-
 # Choose the user urls pattern
 if bool(settings.INCLUDE_ID_IN_USER_URLS.value):
     core_user_urls_prefix = r'^%s(?P<id>\d+)/(?P<slug>.*)'
@@ -30,7 +25,8 @@ else:
     core_user_urls_prefix = r'^%s(?P<slug>.*)'
 
 core_urls = (
-    url(r'^$', app.readers.index, name='index'), admin_url,
+    url(r'^$', app.readers.index, name='index'),
+    url(r'^%s(.*)' % _('nimda/'), admin.site.urls),
                         
     url(r'^sitemap.xml$', 'forum.sitemap.index', {'sitemaps': sitemaps}),
     url(r'^sitemap-(?P<section>.+)-(?P<page>\d+)\.xml$', 'forum.sitemap.sitemap', {'sitemaps': sitemaps}, name="sitemap_section_page"),
@@ -85,7 +81,7 @@ core_urls = (
     url(r'^%s(?P<id>\d+)/' % _('convert_to_question/'), app.writers.convert_to_question,name='convert_to_question'),
     url(r'^%s(?P<id>\d+)/' % _('wikify/'), app.commands.wikify, name='wikify'),
     
-    url(r'^%s(?P<id>\d+)/(?P<slug>[\w-]*)$' % _('question/'), 'django.views.generic.simple.redirect_to', {'url': '/questions/%(id)s/%(slug)s'}),
+    url(r'^%s(?P<id>\d+)/(?P<slug>[\w-]*)$' % _('question/'), 'django.shortcuts.redirect', {'url': '/questions/%(id)s/%(slug)s'}),
     url(r'^%s(?P<id>\d+)/?$' % _('questions/'), app.readers.question, name='question'),
     url(r'^%s(?P<id>\d+)/(?P<slug>.*)/(?P<answer>\d+)$' % _('questions/'), app.readers.question),
     url(r'^%s(?P<id>\d+)/(?P<slug>.*)$' % _('questions/'), app.readers.question, name='question'),
index 5f7b857c043cbb46eefc300a551603a6317c590c..b0681371bdffd2df0b6b9c75f1cee55f2f78a03c 100644 (file)
@@ -6,50 +6,11 @@ Time-stamp: <2008-07-19 23:16:19 carljm context_processors.py>
 """
 from django.utils.encoding import StrAndUnicode
 
-from forum.user_messages import get_and_delete_messages
+from django.contrib.messages.api import get_messages
 
 def user_messages (request):
     """
     Returns session messages for the current session.
 
     """
-    messages = request.user.get_and_delete_messages()
-    #if request.user.is_authenticated():
-    #else:
-    #    messages = LazyMessages(request)
-    #import inspect
-    #print inspect.stack()[1]
-    #print messages
-    return { 'user_messages': messages }
-
-class LazyMessages (StrAndUnicode):
-    """
-    Lazy message container, so messages aren't actually retrieved from
-    session and deleted until the template asks for them.
-
-    """
-    def __init__(self, request):
-        self.request = request
-
-    def __iter__(self):
-        return iter(self.messages)
-
-    def __len__(self):
-        return len(self.messages)
-
-    def __nonzero__(self):
-        return bool(self.messages)
-
-    def __unicode__(self):
-        return unicode(self.messages)
-
-    def __getitem__(self, *args, **kwargs):
-        return self.messages.__getitem__(*args, **kwargs)
-
-    def _get_messages(self):
-        if hasattr(self, '_messages'):
-            return self._messages
-        self._messages = get_and_delete_messages(self.request)
-        return self._messages
-    messages = property(_get_messages)
-    
+    return { 'user_messages': get_messages(request) }
index e4e7acb324c8d6ee0c3edb6ddad30cc37b1cd3a9..6cc2d5bd9848852bf22c551ed519ddb7657c29d6 100644 (file)
@@ -1,13 +1,13 @@
+import json
 from django.http import HttpResponse, HttpResponseForbidden, Http404
-from django.utils import simplejson
 
 def ajax_login_required(view_func):
     def wrap(request,*args,**kwargs):
         if request.user.is_authenticated():
             return view_func(request,*args,**kwargs)
         else:
-            json = simplejson.dumps({'login_required':True})
-            return HttpResponseForbidden(json,mimetype='application/json')
+            json = json.dumps({'login_required':True})
+            return HttpResponseForbidden(json, mimetype='application/json')
     return wrap
 
 def ajax_method(view_func):
@@ -19,7 +19,7 @@ def ajax_method(view_func):
             retval.mimetype = 'application/json'
             return retval
         else:
-            json = simplejson.dumps(retval)
-            return HttpResponse(json,mimetype='application/json')
+            json = json.dumps(retval)
+            return HttpResponse(json, mimetype='application/json')
     return wrap
             
index 256a2d8ce2b2e67857523cd94c93d66c059d92a9..88253e12e60c8ea92d8cc5a064bdc426f5d54ea2 100644 (file)
@@ -1,5 +1,4 @@
 """Utilities for working with HTML."""
-#import html5lib
 from html5lib import sanitizer, serializer, tokenizer, treebuilders, treewalkers, HTMLParser
 from urllib import quote_plus
 from django.utils.html import strip_tags
index 3b517712e6191369d76ff9645996d75a554971e2..c666610e4063b74b1aade98ff9ec02546b96b2ee 100644 (file)
-# Copyright (c) 2001 Chris Withers\r
-#\r
-# This Software is released under the MIT License:\r
-# http://www.opensource.org/licenses/mit-license.html\r
-# See license.txt for more details.\r
-#\r
-# $Id: html2text.py,v 1.7 2002/12/17 16:56:17 fresh Exp $\r
-\r
-import sgmllib\r
-from string import lower, replace, split, join\r
-\r
-class HTML2Text(sgmllib.SGMLParser):\r
-\r
-    from htmlentitydefs import entitydefs # replace entitydefs from sgmllib\r
-\r
-    def __init__(self, ignore_tags=(), indent_width=4, page_width=80):\r
-        sgmllib.SGMLParser.__init__(self)\r
-        self.result = ""\r
-        self.indent = 0\r
-        self.ol_number = 0\r
-        self.page_width=page_width\r
-        self.inde_width=indent_width\r
-        self.lines=[]\r
-        self.line=[]\r
-        self.ignore_tags = ignore_tags\r
-\r
-    def add_text(self,text):\r
-        # convert text into words\r
-        words = split(replace(text,'\n',' '))\r
-        self.line.extend(words)\r
-\r
-    def add_break(self):\r
-        self.lines.append((self.indent,self.line))\r
-        self.line=[]\r
-\r
-    def generate(self):\r
-        # join lines with indents\r
-        indent_width = self.inde_width\r
-        page_width = self.page_width\r
-        out_paras=[]\r
-        for indent,line in self.lines+[(self.indent,self.line)]:\r
-\r
-            i=indent*indent_width\r
-            indent_string = i*' '\r
-            line_width = page_width-i\r
-\r
-            out_para=''\r
-            out_line=[]\r
-            len_out_line=0\r
-            for word in line:\r
-                len_word = len(word)\r
-                if len_out_line+len_word<line_width:\r
-                    out_line.append(word)\r
-                    len_out_line = len_out_line + len_word\r
-                else:\r
-                    out_para = out_para + indent_string + join(out_line, ' ') + '\n'\r
-                    out_line=[word]\r
-                    len_out_line=len_word\r
-\r
-            out_para = out_para + indent_string + join(out_line, ' ')\r
-            out_paras.append(out_para)\r
-\r
-        self.result = join(out_paras,'\n\n')\r
-\r
-\r
-    def mod_indent(self,i):\r
-        self.indent = self.indent + i\r
-        if self.indent < 0:\r
-            self.indent = 0\r
-\r
-    def handle_data(self, data):\r
-        if data:\r
-            self.add_text(data)\r
-\r
-    def unknown_starttag(self, tag, attrs):\r
-        """ Convert HTML to something meaningful in plain text """\r
-        tag = lower(tag)\r
-\r
-        if tag not in self.ignore_tags:\r
-            if tag[0]=='h' or tag in ['br','pre','p','hr']:\r
-                # insert a blank line\r
-                self.add_break()\r
-\r
-            elif tag =='img':\r
-                # newline, text, newline\r
-                src = ''\r
-\r
-                for k, v in attrs:\r
-                    if lower(k) == 'src':\r
-                        src = v\r
-\r
-                self.add_break()\r
-                self.add_text('Image: ' + src)\r
-\r
-            elif tag =='li':\r
-                self.add_break()\r
-                if self.ol_number:\r
-                    # num - text\r
-                    self.add_text(str(self.ol_number) + ' - ')\r
-                    self.ol_number = self.ol_number + 1\r
-                else:\r
-                    # - text\r
-                    self.add_text('- ')\r
-\r
-            elif tag in ['dd','dt']:\r
-                self.add_break()\r
-                # increase indent\r
-                self.mod_indent(+1)\r
-\r
-            elif tag in ['ul','dl','ol']:\r
-                # blank line\r
-                # increase indent\r
-                self.mod_indent(+1)\r
-                if tag=='ol':\r
-                    self.ol_number = 1\r
-\r
-    def unknown_endtag(self, tag):\r
-        """ Convert HTML to something meaningful in plain text """\r
-        tag = lower(tag)\r
-\r
-        if tag not in self.ignore_tags:\r
-            if tag[0]=='h' or tag in ['pre']:\r
-                # newline, text, newline\r
-                self.add_break()\r
-\r
-            elif tag =='li':\r
-                self.add_break()\r
-\r
-            elif tag in ['dd','dt']:\r
-                self.add_break()\r
-                # descrease indent\r
-                self.mod_indent(-1)\r
-\r
-            elif tag in ['ul','dl','ol']:\r
-                # blank line\r
-                self.add_break()\r
-                # decrease indent\r
-                self.mod_indent(-1)\r
-                self.ol_number = 0\r
-\r
+# Copyright (c) 2001 Chris Withers
+#
+# This Software is released under the MIT License:
+# http://www.opensource.org/licenses/mit-license.html
+# See license.txt for more details.
+#
+# $Id: html2text.py,v 1.7 2002/12/17 16:56:17 fresh Exp $
+
+import sgmllib
+from string import lower, replace, split, join
+
+class HTML2Text(sgmllib.SGMLParser):
+
+    from htmlentitydefs import entitydefs # replace entitydefs from sgmllib
+
+    def __init__(self, ignore_tags=(), indent_width=4, page_width=80):
+        sgmllib.SGMLParser.__init__(self)
+        self.result = ""
+        self.indent = 0
+        self.ol_number = 0
+        self.page_width=page_width
+        self.inde_width=indent_width
+        self.lines=[]
+        self.line=[]
+        self.ignore_tags = ignore_tags
+
+    def add_text(self,text):
+        # convert text into words
+        words = split(replace(text,'\n',' '))
+        self.line.extend(words)
+
+    def add_break(self):
+        self.lines.append((self.indent,self.line))
+        self.line=[]
+
+    def generate(self):
+        # join lines with indents
+        indent_width = self.inde_width
+        page_width = self.page_width
+        out_paras=[]
+        for indent,line in self.lines+[(self.indent,self.line)]:
+
+            i=indent*indent_width
+            indent_string = i*' '
+            line_width = page_width-i
+
+            out_para=''
+            out_line=[]
+            len_out_line=0
+            for word in line:
+                len_word = len(word)
+                if len_out_line+len_word<line_width:
+                    out_line.append(word)
+                    len_out_line = len_out_line + len_word
+                else:
+                    out_para = out_para + indent_string + join(out_line, ' ') + '\n'
+                    out_line=[word]
+                    len_out_line=len_word
+
+            out_para = out_para + indent_string + join(out_line, ' ')
+            out_paras.append(out_para)
+
+        self.result = join(out_paras,'\n\n')
+
+
+    def mod_indent(self,i):
+        self.indent = self.indent + i
+        if self.indent < 0:
+            self.indent = 0
+
+    def handle_data(self, data):
+        if data:
+            self.add_text(data)
+
+    def unknown_starttag(self, tag, attrs):
+        """ Convert HTML to something meaningful in plain text """
+        tag = lower(tag)
+
+        if tag not in self.ignore_tags:
+            if tag[0]=='h' or tag in ['br','pre','p','hr']:
+                # insert a blank line
+                self.add_break()
+
+            elif tag =='img':
+                # newline, text, newline
+                src = ''
+
+                for k, v in attrs:
+                    if lower(k) == 'src':
+                        src = v
+
+                self.add_break()
+                self.add_text('Image: ' + src)
+
+            elif tag =='li':
+                self.add_break()
+                if self.ol_number:
+                    # num - text
+                    self.add_text(str(self.ol_number) + ' - ')
+                    self.ol_number = self.ol_number + 1
+                else:
+                    # - text
+                    self.add_text('- ')
+
+            elif tag in ['dd','dt']:
+                self.add_break()
+                # increase indent
+                self.mod_indent(+1)
+
+            elif tag in ['ul','dl','ol']:
+                # blank line
+                # increase indent
+                self.mod_indent(+1)
+                if tag=='ol':
+                    self.ol_number = 1
+
+    def unknown_endtag(self, tag):
+        """ Convert HTML to something meaningful in plain text """
+        tag = lower(tag)
+
+        if tag not in self.ignore_tags:
+            if tag[0]=='h' or tag in ['pre']:
+                # newline, text, newline
+                self.add_break()
+
+            elif tag =='li':
+                self.add_break()
+
+            elif tag in ['dd','dt']:
+                self.add_break()
+                # descrease indent
+                self.mod_indent(-1)
+
+            elif tag in ['ul','dl','ol']:
+                # blank line
+                self.add_break()
+                # decrease indent
+                self.mod_indent(-1)
+                self.ol_number = 0
+
index da9dc67cdc326bd4b7124b84d76657f60fdbdd27..a834b711a98e83285fbffffe75ecb542e9c9a110 100644 (file)
@@ -1,4 +1,5 @@
 from datetime import datetime, timedelta
+import json
 import time
 
 from django.views.decorators.csrf import csrf_exempt
@@ -7,9 +8,10 @@ from django.core.urlresolvers import reverse
 from django.http import HttpResponseRedirect, HttpResponse, Http404
 from django.template import RequestContext
 from django.utils.translation import ugettext as _
-from django.utils import simplejson
 from django.db import models
 
+from django.contrib import messages
+
 from forum.http_responses import HttpResponseUnauthorized
 from forum.settings.base import Setting
 from forum.forms import MaintenanceModeForm, PageForm, CreateUserForm
@@ -119,7 +121,7 @@ def statistics(request):
             'added_at', flat=True)
 
     last_month_n_questions = Question.objects.filter_state(deleted=False).filter(added_at__lt=last_month).count()
-    qgraph_data = simplejson.dumps([
+    qgraph_data = json.dumps([
     (time.mktime(d.timetuple()) * 1000, i + last_month_n_questions)
     for i, d in enumerate(last_month_questions)
     ])
@@ -129,7 +131,7 @@ def statistics(request):
 
     last_month_n_users = User.objects.filter(date_joined__lt=last_month).count()
 
-    ugraph_data = simplejson.dumps([
+    ugraph_data = json.dumps([
     (time.mktime(d.timetuple()) * 1000, i + last_month_n_users)
     for i, d in enumerate(last_month_users)
     ])
@@ -181,7 +183,7 @@ def settings_set(request, set_name):
 
                 if not 'reset' in request.POST:
                     form.save()
-                    request.user.message_set.create(message=_("'%s' settings saved succesfully") % set_name)
+                    messages.info(request, _("'%s' settings saved succesfully") % set_name)
 
                     if set_name in ('minrep', 'badges', 'repgain'):
                         settings.SETTINGS_PACK.set_value("custom")
@@ -288,7 +290,7 @@ def go_bootstrap(request):
 
     settings.SETTINGS_PACK.set_value("bootstrap")
 
-    request.user.message_set.create(message=_('Bootstrap mode enabled'))
+    messages.info(request, _('Bootstrap mode enabled'))
     return HttpResponseRedirect(reverse('admin_index'))
 
 @super_user_required
@@ -302,7 +304,7 @@ def go_defaults(request):
 
     settings.SETTINGS_PACK.set_value("default")
 
-    request.user.message_set.create(message=_('All values reverted to defaults'))
+    messages.info(request, ('All values reverted to defaults'))
     return HttpResponseRedirect(reverse('admin_index'))
 
 
@@ -318,7 +320,7 @@ def recalculate_denormalized(request):
         u.reputation = u.reputes.aggregate(reputation=models.Sum('value'))['reputation']
         u.save()
 
-    request.user.message_set.create(message=_('All values recalculated'))
+    messages.info(request, _('All values recalculated'))
     return HttpResponseRedirect(reverse('admin_index'))
 
 @admin_page
@@ -337,12 +339,12 @@ def maintenance(request):
                 else:
                     message = _('Settings adjusted')
 
-                request.user.message_set.create(message=message)
+                messages.info(request, message)
 
                 return HttpResponseRedirect(reverse('admin_maintenance'))
         elif 'open' in request.POST:
             settings.MAINTAINANCE_MODE.set_value(None)
-            request.user.message_set.create(message=_("Your site is now running normally"))
+            messages.info(request, _("Your site is now running normally"))
             return HttpResponseRedirect(reverse('admin_maintenance'))
     else:
         form = MaintenanceModeForm(initial={'ips': request.META['REMOTE_ADDR'],
@@ -427,7 +429,7 @@ def create_user(request):
             user_.save()
             UserJoinsAction(user=user_).save()
 
-            request.user.message_set.create(message=_("New user created sucessfully. %s.") % html.hyperlink(
+            messages.info(request, _("New user created sucessfully. %s.") % html.hyperlink(
                     user_.get_profile_url(), _("See %s profile") % user_.username, target="_blank"))
 
             return HttpResponseRedirect(reverse("admin_tools", kwargs={'name': 'createuser'}))
@@ -507,7 +509,7 @@ def node_management(request):
 
                     message = _("All selected nodes deleted")
 
-                request.user.message_set.create(message=message)
+                messages.info(request, message)
 
                 params = pagination.generate_uri(request.GET, ('page',))
                 
@@ -590,4 +592,4 @@ def test_email_settings(request):
         'osqaadmin/test_email_settings.html',
         { 'user': user, },
         RequestContext(request)
-    )
\ No newline at end of file
+    )
index 9511be91b0616102da9d068e8f09eb1b0bdc2643..01f62105e167792ca358a1d992808fe31c77f7d1 100644 (file)
@@ -14,6 +14,8 @@ from django.utils.translation import ugettext as _
 from django.utils.encoding import smart_unicode
 from django.contrib.auth import login, logout
 
+from django.contrib import messages
+
 from writers import manage_pending_data
 
 from forum.actions import EmailValidationAction
@@ -132,8 +134,7 @@ def process_provider_signin(request, provider):
                 except:
                     uassoc = AuthKeyUserAssociation(user=request.user, key=assoc_key, provider=provider)
                     uassoc.save()
-                    request.user.message_set.create(
-                            message=_('The new credentials are now associated with your account'))
+                    messages.info(request, _('The new credentials are now associated with your account'))
                     return HttpResponseRedirect(reverse('user_authsettings', args=[request.user.id]))
 
             return HttpResponseRedirect(reverse('auth_signin'))
@@ -251,7 +252,7 @@ def request_temp_login(request):
 
                 send_template_email([u], "auth/temp_login_email.html", {'temp_login_code': hash})
 
-                request.user.message_set.create(message=_("An email has been sent with your temporary login key"))
+                messages.info(request, _("An email has been sent with your temporary login key"))
 
             return HttpResponseRedirect(reverse('index'))
     else:
@@ -297,7 +298,7 @@ def send_validation_email(request):
             'additional_get_params' : additional_get_params
         })
 
-        request.user.message_set.create(message=_("A message with an email validation link was just sent to your address."))
+        messages.info(request, _("A message with an email validation link was just sent to your address."))
         return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
 
         
@@ -332,11 +333,11 @@ def auth_settings(request, id):
             user_.save()
 
             if is_new_pass:
-                request.user.message_set.create(message=_("New password set"))
+                messages.info(request, _("New password set"))
                 if not request.user.is_superuser:
                     form = ChangePasswordForm(user=user_)
             else:
-                request.user.message_set.create(message=_("Your password was changed"))
+                messages.info(request, _("Your password was changed"))
 
             return HttpResponseRedirect(reverse('user_authsettings', kwargs={'id': user_.id}))
     else:
@@ -372,7 +373,7 @@ def remove_external_provider(request, id):
     if not (request.user.is_superuser or request.user == association.user):
         return HttpResponseUnauthorized(request)
 
-    request.user.message_set.create(message=_("You removed the association with %s") % association.provider)
+    messages.info(request, _("You removed the association with %s") % association.provider)
     association.delete()
     return HttpResponseRedirect(reverse('user_authsettings', kwargs={'id': association.user.id}))
 
@@ -389,7 +390,7 @@ def login_and_forward(request, user, forward=None, message=None):
     if message is None:
         message = _("Welcome back %s, you are now logged in") % smart_unicode(user.username)
 
-    request.user.message_set.create(message=message)
+    messages.info(request, message)
 
     if not forward:
         forward = request.session.get(ON_SIGNIN_SESSION_ATTR, reverse('index'))
@@ -401,7 +402,7 @@ def login_and_forward(request, user, forward=None, message=None):
         if submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.HOLD_PENDING_POSTS_MINUTES)):
             del request.session[PENDING_SUBMISSION_SESSION_ATTR]
         elif submission_time < datetime.datetime.now() - datetime.timedelta(minutes=int(settings.WARN_PENDING_POSTS_MINUTES)):
-            user.message_set.create(message=(_("You have a %s pending submission.") % pending_data['data_name']) + " %s, %s, %s" % (
+            messages.info(request, (_("You have a %s pending submission.") % pending_data['data_name']) + " %s, %s, %s" % (
                 html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('save')}), _("save it")),
                 html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('review')}), _("review")),
                 html.hyperlink(reverse('manage_pending_data', kwargs={'action': _('cancel')}), _("cancel"))
@@ -432,7 +433,7 @@ def forward_suspended_user(request, user, show_private_msg=True):
     if suspension:
         message += (":<br />" + suspension.extra.get(msg_type, ''))
 
-    request.user.message_set.create(message)
+    messages.info(request, message)
     return HttpResponseRedirect(reverse('index'))
 
 @decorate.withfn(login_required)
index 5271eec69d014aaf0591120096aa40ab67a29a1f..62d864f80383314eeeb8b1da8a002adb3fb9a910 100644 (file)
@@ -1,18 +1,20 @@
 # -*- coding: utf-8 -*-
 
 import datetime
+import json
 import logging
 
 from urllib import urlencode
 
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.urlresolvers import reverse
-from django.utils import simplejson
 from django.utils.encoding import smart_unicode
 from django.utils.translation import ungettext, ugettext as _
 from django.http import HttpResponse, HttpResponseRedirect, Http404
 from django.shortcuts import get_object_or_404, render_to_response
 
+from django.contrib import messages
+
 from forum.models import *
 from forum.utils.decorators import ajax_login_required
 from forum.actions import *
@@ -353,7 +355,7 @@ def accept_answer(request, id):
             """)
 
             # Notify the user with a message that an answer has been accepted
-            request.user.message_set.create(message=msg)
+            messages.info(request, msg)
 
             # Redirect URL should include additional get parameters that might have been attached
             redirect_url = answer.parent.get_absolute_url() + "?accepted_answer=true&%s" % smart_unicode(urlencode(request.GET))
@@ -545,7 +547,7 @@ def mark_tag(request, tag=None, **kwargs):#tagging system
                 pass
         else:
             ts.update(reason=reason)
-    return HttpResponse(simplejson.dumps(''), mimetype="application/json")
+    return HttpResponse(json.dumps(''), mimetype="application/json")
 
 def matching_tags(request):
     if len(request.GET['q']) == 0:
@@ -577,7 +579,7 @@ def related_questions(request):
         if can_rank and isinstance(can_rank, basestring):
             questions = questions.order_by(can_rank)
 
-        return HttpResponse(simplejson.dumps(
+        return HttpResponse(json.dumps(
                 [dict(title=q.title, url=q.get_absolute_url(), score=q.score, summary=q.summary)
                  for q in questions.filter_state(deleted=False)[0:10]]), mimetype="application/json")
     else:
@@ -638,3 +640,4 @@ def award_points(request, user_id, answer_id):
         AwardPointsAction(user=request.user, node=answer, extra=extra).save(data=dict(value=points, affected=awarded_user))
 
         return { 'message' : _("You have awarded %(awarded_user)s with %(points)d points") % {'awarded_user' : awarded_user, 'points' : points} }
+
index 9cb8cbd4ca08d622f0a3edb9f8cd18e1a4eae629..3bede665ddaf966b54829039accc29d1afb4ec6f 100644 (file)
@@ -1,84 +1,83 @@
-# -*- coding: utf-8 -*-\r
-\r
-import logging\r
-\r
-from datetime import datetime\r
-\r
-from django.http import HttpResponse, HttpResponseRedirect\r
-from django.utils import simplejson\r
-from django.shortcuts import render_to_response\r
-from django.core.urlresolvers import reverse\r
-from django.template import RequestContext\r
-from django.utils.translation import ugettext as _\r
-\r
-from forum.modules import ui, decorate\r
-from forum.settings import ONLINE_USERS\r
-\r
-def login_required(func, request, *args, **kwargs):\r
-    if not request.user.is_authenticated():\r
-        return HttpResponseRedirect(reverse('auth_signin'))\r
-    else:\r
-        return func(request, *args, **kwargs)\r
-\r
-def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):\r
-    def decorator(func):        \r
-        def decorated(context, request, *args, **kwargs):\r
-            if request.user.is_authenticated():\r
-                ONLINE_USERS[request.user] = datetime.now()\r
-\r
-            if isinstance(context, HttpResponse):\r
-                return context\r
-\r
-            if tab is not None:\r
-                context['tab'] = tab\r
-\r
-            return render_to_response(context.pop('template', template), context,\r
-                                      context_instance=RequestContext(request))\r
-\r
-        if tabbed and tab and tab_title:\r
-            ui.register(ui.PAGE_TOP_TABS,\r
-                        ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight))\r
-            \r
-        return decorate.result.withfn(decorated, needs_params=True)(func)\r
-\r
-    return decorator\r
-\r
-class CommandException(Exception):\r
-    pass\r
-\r
-class RefreshPageCommand(HttpResponse):\r
-    def __init__(self):\r
-        super(RefreshPageCommand, self).__init__(\r
-                content=simplejson.dumps({'commands': {'refresh_page': []}, 'success': True}),\r
-                mimetype="application/json")\r
-\r
-def command(func, request, *args, **kwargs):\r
-    try:\r
-        response = func(request, *args, **kwargs)\r
-\r
-        if isinstance(response, HttpResponse):\r
-            return response\r
-\r
-        response['success'] = True\r
-    except Exception, e:\r
-        import traceback\r
-        #traceback.print_exc()\r
-\r
-        if isinstance(e, CommandException):\r
-            response = {\r
-            'success': False,\r
-            'error_message': e.message\r
-            }\r
-        else:\r
-            logging.error("%s: %s" % (func.__name__, str(e)))\r
-            logging.error(traceback.format_exc())\r
-            response = {\r
-            'success': False,\r
-            'error_message': _("We're sorry, but an unknown error ocurred.<br />Please try again in a while.")\r
-            }\r
-\r
-    if request.is_ajax():\r
-        return HttpResponse(simplejson.dumps(response), mimetype="application/json")\r
-    else:\r
-        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))\r
-\r
+# -*- coding: utf-8 -*-
+import json
+import logging
+
+from datetime import datetime
+
+from django.http import HttpResponse, HttpResponseRedirect
+from django.shortcuts import render_to_response
+from django.core.urlresolvers import reverse
+from django.template import RequestContext
+from django.utils.translation import ugettext as _
+
+from forum.modules import ui, decorate
+from forum.settings import ONLINE_USERS
+
+def login_required(func, request, *args, **kwargs):
+    if not request.user.is_authenticated():
+        return HttpResponseRedirect(reverse('auth_signin'))
+    else:
+        return func(request, *args, **kwargs)
+
+def render(template=None, tab=None, tab_title='', weight=500, tabbed=True):
+    def decorator(func):        
+        def decorated(context, request, *args, **kwargs):
+            if request.user.is_authenticated():
+                ONLINE_USERS[request.user] = datetime.now()
+
+            if isinstance(context, HttpResponse):
+                return context
+
+            if tab is not None:
+                context['tab'] = tab
+
+            return render_to_response(context.pop('template', template), context,
+                                      context_instance=RequestContext(request))
+
+        if tabbed and tab and tab_title:
+            ui.register(ui.PAGE_TOP_TABS,
+                        ui.PageTab(tab, tab_title, lambda: reverse(func.__name__), weight=weight))
+            
+        return decorate.result.withfn(decorated, needs_params=True)(func)
+
+    return decorator
+
+class CommandException(Exception):
+    pass
+
+class RefreshPageCommand(HttpResponse):
+    def __init__(self):
+        super(RefreshPageCommand, self).__init__(
+                content=json.dumps({'commands': {'refresh_page': []}, 'success': True}),
+                mimetype="application/json")
+
+def command(func, request, *args, **kwargs):
+    try:
+        response = func(request, *args, **kwargs)
+
+        if isinstance(response, HttpResponse):
+            return response
+
+        response['success'] = True
+    except Exception, e:
+        import traceback
+        #traceback.print_exc()
+
+        if isinstance(e, CommandException):
+            response = {
+            'success': False,
+            'error_message': e.message
+            }
+        else:
+            logging.error("%s: %s" % (func.__name__, str(e)))
+            logging.error(traceback.format_exc())
+            response = {
+            'success': False,
+            'error_message': _("We're sorry, but an unknown error ocurred.<br />Please try again in a while.")
+            }
+
+    if request.is_ajax():
+        return HttpResponse(json.dumps(response), mimetype="application/json")
+    else:
+        return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
+
index c9548e58d46e34d6af9780503e59de1577b70797..e7d151588a8402a6e0c2b73c19cf03b9005e91c0 100644 (file)
@@ -9,13 +9,14 @@ from django.views.decorators.cache import cache_page
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
 
+from django.contrib import messages
+
 from forum import settings
 from forum.views.decorators import login_required
 from forum.forms import FeedbackForm
 from forum.modules import decorate
 from forum.forms import get_next_url
 from forum.models import Badge, Award, User, Page
-from forum.badges.base import BadgesMeta
 from forum.http_responses import HttpResponseNotFound, HttpResponseIntServerError
 from forum.utils.mail import send_template_email
 from forum.templatetags.extra_filters import or_preview
@@ -36,7 +37,7 @@ def static(request, title, content):
 def media(request, skin, path):
     response = serve(request, "%s/media/%s" % (skin, path),
                  document_root=os.path.join(os.path.dirname(os.path.dirname(__file__)), 'skins').replace('\\', '/'))
-    content_type = response['Content-Type']
+    content_type = response.get('Content-Type', '')
     if ('charset=' not in content_type):
         if (content_type.startswith('text') or content_type=='application/x-javascript'):
             content_type += '; charset=utf-8'
@@ -68,7 +69,7 @@ def feedback(request):
             send_template_email(recipients, "notifications/feedback.html", context)
 
             msg = _('Thanks for the feedback!')
-            request.user.message_set.create(message=msg)
+            messages.info(request, msg)
             return HttpResponseRedirect(get_next_url(request))
     else:
         form = FeedbackForm(request.user, initial={'next':get_next_url(request)})
@@ -88,6 +89,7 @@ def logout(request):
 
 @decorators.render('badges.html', 'badges', _('badges'), weight=300)
 def badges(request):
+    from forum.badges.base import BadgesMeta
     badges = sorted([Badge.objects.get(id=id) for id in BadgesMeta.by_id.keys()], lambda b1, b2: cmp(b1.name, b2.name))
 
     if request.user.is_authenticated():
index 669eaf3006a849aefdaf84d40e3adf72d6089742..a8b94e92e200bec718b5f77aec4a07a4b2d1cb1f 100644 (file)
@@ -8,6 +8,7 @@ from django.core.paginator import Paginator, EmptyPage, InvalidPage
 from django.template import RequestContext
 from django import template
 from django.utils.html import *
+from django.utils.http import urlquote
 from django.db.models import Q, Count
 from django.utils.translation import ugettext as _
 from django.core.urlresolvers import reverse
index dc865a236ed3e8824903419c78b88fdb609ce9ba..c6fae00e31a08d96615d6ed828c73fe239d16272 100644 (file)
-from forum.models import User\r
-from django.db.models import Q, Count\r
-from django.core.paginator import Paginator, EmptyPage, InvalidPage\r
-from django.template.defaultfilters import slugify\r
-from django.contrib.contenttypes.models import ContentType\r
-from django.core.urlresolvers import reverse\r
-from django.shortcuts import render_to_response, get_object_or_404\r
-from django.template import RequestContext\r
-from django.http import HttpResponse, HttpResponseRedirect, Http404\r
-from forum.http_responses import HttpResponseUnauthorized\r
-from django.utils.translation import ugettext as _\r
-from django.utils.http import urlquote_plus\r
-from django.utils.html import strip_tags\r
-from django.utils.encoding import smart_unicode\r
-from django.utils import simplejson\r
-from django.core.urlresolvers import reverse, NoReverseMatch\r
-from forum.forms import *\r
-from forum.utils.html import sanitize_html\r
-from forum.modules import decorate, ReturnImediatelyException\r
-from datetime import datetime, date\r
-from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction, ReportAction\r
-from forum.modules import ui\r
-from forum.utils import pagination\r
-from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext\r
-from forum.settings import ONLINE_USERS\r
\r
-import time\r
-import datetime\r
-import decorators\r
-\r
-class UserReputationSort(pagination.SimpleSort):\r
-    def apply(self, objects):\r
-        return objects.order_by('-is_active', self.order_by)\r
-\r
-class UserListPaginatorContext(pagination.PaginatorContext):\r
-    def __init__(self, pagesizes=(20, 35, 60), default_pagesize=35):\r
-        super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(\r
-            (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),\r
-            (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),\r
-            (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),\r
-            (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),\r
-        ), pagesizes=pagesizes, default_pagesize=default_pagesize)\r
-\r
-class SubscriptionListPaginatorContext(pagination.PaginatorContext):\r
-    def __init__(self):\r
-        super (SubscriptionListPaginatorContext, self).__init__('SUBSCRIPTION_LIST', pagesizes=(5, 10, 20), default_pagesize=20)\r
-\r
-class UserAnswersPaginatorContext(pagination.PaginatorContext):\r
-    def __init__(self):\r
-        super (UserAnswersPaginatorContext, self).__init__('USER_ANSWER_LIST', sort_methods=(\r
-            (_('oldest'), pagination.SimpleSort(_('oldest answers'), 'added_at', _("oldest answers will be shown first"))),\r
-            (_('newest'), pagination.SimpleSort(_('newest answers'), '-added_at', _("newest answers will be shown first"))),\r
-            (_('votes'), pagination.SimpleSort(_('popular answers'), '-score', _("most voted answers will be shown first"))),\r
-        ), default_sort=_('votes'), pagesizes=(5, 10, 20), default_pagesize=20, prefix=_('answers'))\r
-\r
-USERS_PAGE_SIZE = 35# refactor - move to some constants file\r
-\r
-@decorators.render('users/users.html', 'users', _('users'), weight=200)\r
-def users(request):\r
-    suser = request.REQUEST.get('q', "")\r
-    users = User.objects.all()\r
-\r
-    if suser != "":\r
-        users = users.filter(username__icontains=suser)\r
-\r
-    return pagination.paginated(request, ('users', UserListPaginatorContext()), {\r
-        "users" : users,\r
-        "suser" : suser,\r
-    })\r
-\r
-\r
-@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200, tabbed=False)\r
-def online_users(request):\r
-    suser = request.REQUEST.get('q', "")\r
-\r
-    sort = ""\r
-    if request.GET.get("sort", None):\r
-        try:\r
-            sort = int(request.GET["sort"])\r
-        except ValueError:\r
-            logging.error('Found invalid sort "%s", loading %s, refered by %s' % (\r
-                request.GET.get("sort", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
-            ))\r
-            raise Http404()\r
-\r
-    page = 0\r
-    if request.GET.get("page", None):\r
-        try:\r
-            page = int(request.GET["page"])\r
-        except ValueError:\r
-            logging.error('Found invalid page "%s", loading %s, refered by %s' % (\r
-                request.GET.get("page", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
-            ))\r
-            raise Http404()\r
-\r
-    pagesize = 10\r
-    if request.GET.get("pagesize", None):\r
-        try:\r
-            pagesize = int(request.GET["pagesize"])\r
-        except ValueError:\r
-            logging.error('Found invalid pagesize "%s", loading %s, refered by %s' % (\r
-                request.GET.get("pagesize", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')\r
-            ))\r
-            raise Http404()\r
-\r
-\r
-    users = None\r
-    if sort == "reputation":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.reputation)\r
-    elif sort == "newest" :\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
-    elif sort == "last":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.last)\r
-    elif sort == "name":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.name)\r
-    elif sort == "oldest":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.oldest)\r
-    elif sort == "newest":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)\r
-    elif sort == "votes":\r
-        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.votes)\r
-    else:\r
-        users = sorted(ONLINE_USERS.iteritems(), key=lambda x: x[1])\r
-\r
-    return render_to_response('users/online_users.html', {\r
-        "users" : users,\r
-        "suser" : suser,\r
-        "sort" : sort,\r
-        "page" : page,\r
-        "pageSize" : pagesize,\r
-    })\r
-\r
-\r
-def edit_user(request, id, slug):\r
-    user = get_object_or_404(User, id=id)\r
-    if not (request.user.is_superuser or request.user == user):\r
-        return HttpResponseUnauthorized(request)\r
-    if request.method == "POST":\r
-        form = EditUserForm(user, request.POST)\r
-        if form.is_valid():\r
-            new_email = sanitize_html(form.cleaned_data['email'])\r
-\r
-            if new_email != user.email:\r
-                user.email = new_email\r
-                user.email_isvalid = False\r
-\r
-                try:\r
-                    hash = ValidationHash.objects.get(user=request.user, type='email')\r
-                    hash.delete()\r
-                except:\r
-                    pass\r
-\r
-            if settings.EDITABLE_SCREEN_NAME:\r
-                user.username = sanitize_html(form.cleaned_data['username'])\r
-            user.real_name = sanitize_html(form.cleaned_data['realname'])\r
-            user.website = sanitize_html(form.cleaned_data['website'])\r
-            user.location = sanitize_html(form.cleaned_data['city'])\r
-            user.date_of_birth = form.cleaned_data['birthday']\r
-            if user.date_of_birth == "None":\r
-                user.date_of_birth = datetime(1900, 1, 1, 0, 0)\r
-            user.about = sanitize_html(form.cleaned_data['about'])\r
-\r
-            user.save()\r
-            EditProfileAction(user=user, ip=request.META['REMOTE_ADDR']).save()\r
-\r
-            request.user.message_set.create(message=_("Profile updated."))\r
-            return HttpResponseRedirect(user.get_profile_url())\r
-    else:\r
-        form = EditUserForm(user)\r
-    return render_to_response('users/edit.html', {\r
-    'user': user,\r
-    'form' : form,\r
-    'gravatar_faq_url' : reverse('faq') + '#gravatar',\r
-    }, context_instance=RequestContext(request))\r
-\r
-\r
-@decorate.withfn(decorators.command)\r
-def user_powers(request, id, action, status):\r
-    if not request.user.is_superuser:\r
-        raise decorators.CommandException(_("Only superusers are allowed to alter other users permissions."))\r
-\r
-    if (action == 'remove' and 'status' == 'super') and not request.user.is_siteowner():\r
-        raise decorators.CommandException(_("Only the site owner can remove the super user status from other user."))\r
-\r
-    user = get_object_or_404(User, id=id)\r
-    new_state = action == 'grant'\r
-\r
-    if status == 'super':\r
-        user.is_superuser = new_state\r
-    elif status == 'staff':\r
-        user.is_staff = new_state\r
-    else:\r
-        raise Http404()\r
-\r
-    user.save()\r
-    return decorators.RefreshPageCommand()\r
-\r
-\r
-@decorate.withfn(decorators.command)\r
-def award_points(request, id):\r
-    if not request.POST:\r
-        return render_to_response('users/karma_bonus.html')\r
-\r
-    if not request.user.is_superuser:\r
-        raise decorators.CommandException(_("Only superusers are allowed to award reputation points"))\r
-\r
-    try:\r
-        points = int(request.POST['points'])\r
-    except:\r
-        raise decorators.CommandException(_("Invalid number of points to award."))\r
-\r
-    user = get_object_or_404(User, id=id)\r
-\r
-    extra = dict(message=request.POST.get('message', ''), awarding_user=request.user.id, value=points)\r
-\r
-    BonusRepAction(user=request.user, extra=extra).save(data=dict(value=points, affected=user))\r
-\r
-    return {'commands': {\r
-            'update_profile_karma': [user.reputation]\r
-        }}\r
-    \r
-\r
-@decorate.withfn(decorators.command)\r
-def suspend(request, id):\r
-    user = get_object_or_404(User, id=id)\r
-\r
-    if not request.user.is_superuser:\r
-        raise decorators.CommandException(_("Only superusers can suspend other users"))\r
-\r
-    if not request.POST.get('bantype', None):\r
-        if user.is_suspended():\r
-            suspension = user.suspension\r
-            suspension.cancel(user=request.user, ip=request.META['REMOTE_ADDR'])\r
-            return decorators.RefreshPageCommand()\r
-        else:\r
-            return render_to_response('users/suspend_user.html')\r
-\r
-    data = {\r
-        'bantype': request.POST.get('bantype', 'Indefinitely').strip(),\r
-        'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),\r
-        'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),\r
-        'suspended': user\r
-    }\r
-\r
-    if data['bantype'] == 'forxdays':\r
-        try:\r
-            data['forxdays'] = int(request.POST['forxdays'])\r
-        except:\r
-            raise decorators.CommandException(_('Invalid numeric argument for the number of days.'))\r
-\r
-    SuspendAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)\r
-\r
-    return decorators.RefreshPageCommand()\r
-\r
-@decorate.withfn(decorators.command)\r
-def report_user(request, id):\r
-    user = get_object_or_404(User, id=id)\r
-\r
-    if not request.POST.get('publicmsg', None):\r
-        return render_to_response('users/report_user.html')\r
-\r
-    data = {\r
-        'publicmsg': request.POST.get('publicmsg', _('N/A')),\r
-        'reported': user\r
-    }\r
-\r
-    ReportAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)\r
-\r
-\r
-    return decorators.RefreshPageCommand()\r
-\r
-\r
-\r
-def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):\r
-    def decorator(fn):\r
-        def params(request, id=None, slug=None):\r
-            # Get the user object by id if the id parameter has been passed\r
-            if id is not None:\r
-                user = get_object_or_404(User, id=id)\r
-            # ...or by slug if the slug has been given\r
-            elif slug is not None:\r
-                try:\r
-                    user = User.objects.get(username__iexact=slug)\r
-                except User.DoesNotExist:\r
-                    raise Http404\r
-\r
-            if private and not (user == request.user or request.user.is_superuser):\r
-                raise ReturnImediatelyException(HttpResponseUnauthorized(request))\r
-\r
-            if render_to and (not render_to(user)):\r
-                raise ReturnImediatelyException(HttpResponseRedirect(user.get_profile_url()))\r
-\r
-            return [request, user], { 'slug' : slug, }\r
-\r
-        decorated = decorate.params.withfn(params)(fn)\r
-\r
-        def result(context_or_response, request, user, **kwargs):\r
-            rev_page_title = smart_unicode(user.username) + " - " + tab_description\r
-\r
-            # Check whether the return type of the decorated function is a context or Http Response\r
-            if isinstance(context_or_response, HttpResponse):\r
-                response = context_or_response\r
-\r
-                # If it is a response -- show it\r
-                return response\r
-            else:\r
-                # ...if it is a context move forward, update it and render it to response\r
-                context = context_or_response\r
-\r
-            context.update({\r
-                "tab": "users",\r
-                "active_tab" : tab_name,\r
-                "tab_description" : tab_description,\r
-                "page_title" : rev_page_title,\r
-                "can_view_private": (user == request.user) or request.user.is_superuser\r
-            })\r
-            return render_to_response(template, context, context_instance=RequestContext(request))\r
-\r
-        decorated = decorate.result.withfn(result, needs_params=True)(decorated)\r
-\r
-        if tabbed:\r
-            def url_getter(vu):\r
-                try:\r
-                    return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(smart_unicode(vu.username))})\r
-                except NoReverseMatch:\r
-                    try:\r
-                        return reverse(fn.__name__, kwargs={'id': vu.id})\r
-                    except NoReverseMatch:\r
-                        return reverse(fn.__name__, kwargs={'slug': slugify(smart_unicode(vu.username))})\r
-\r
-            ui.register(ui.PROFILE_TABS, ui.ProfileTab(\r
-                tab_name, tab_title, tab_description,url_getter, private, render_to, weight\r
-            ))\r
-\r
-        return decorated\r
-    return decorator\r
-\r
-\r
-@user_view('users/stats.html', 'stats', _('overview'), _('user overview'))\r
-def user_profile(request, user, **kwargs):\r
-    questions = Question.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
-    answers = Answer.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')\r
-\r
-    # Check whether the passed slug matches the one for the user object\r
-    slug = kwargs['slug']\r
-    if slug != slugify(smart_unicode(user.username)):\r
-        return HttpResponseRedirect(user.get_absolute_url())\r
-\r
-    up_votes = user.vote_up_count\r
-    down_votes = user.vote_down_count\r
-    votes_today = user.get_vote_count_today()\r
-    votes_total = user.can_vote_count_today()\r
-\r
-    user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \\r
-        .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')\r
-\r
-    awards = [(Badge.objects.get(id=b['id']), b['count']) for b in\r
-              Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]\r
-\r
-    return pagination.paginated(request, (\r
-    ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), default_pagesize=15)),\r
-    ('answers', UserAnswersPaginatorContext())), {\r
-    "view_user" : user,\r
-    "questions" : questions,\r
-    "answers" : answers,\r
-    "up_votes" : up_votes,\r
-    "down_votes" : down_votes,\r
-    "total_votes": up_votes + down_votes,\r
-    "votes_today_left": votes_total-votes_today,\r
-    "votes_total_per_day": votes_total,\r
-    "user_tags" : user_tags[:50],\r
-    "awards": awards,\r
-    "total_awards" : len(awards),\r
-    })\r
-    \r
-@user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))\r
-def user_recent(request, user, **kwargs):\r
-    activities = user.actions.exclude(\r
-            action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(\r
-            '-action_date')[:USERS_PAGE_SIZE]\r
-\r
-    return {"view_user" : user, "activities" : activities}\r
-\r
-\r
-@user_view('users/reputation.html', 'reputation', _('reputation history'), _('graph of user karma'))\r
-def user_reputation(request, user, **kwargs):\r
-    rep = list(user.reputes.order_by('date'))\r
-    values = [r.value for r in rep]\r
-    redux = lambda x, y: x+y\r
-\r
-    graph_data = simplejson.dumps([\r
-    (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i+1], 0))\r
-    for i in range(len(values))\r
-    ])\r
-\r
-    rep = user.reputes.filter(action__canceled=False).order_by('-date')[0:20]\r
-\r
-    return {"view_user": user, "reputation": rep, "graph_data": graph_data}\r
-\r
-@user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)\r
-def user_votes(request, user, **kwargs):\r
-    votes = user.votes.exclude(node__state_string__contains="(deleted").filter(\r
-            node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]\r
-\r
-    return {"view_user" : user, "votes" : votes}\r
-\r
-@user_view('users/questions.html', 'favorites', _('favorites'), _('questions that user selected as his/her favorite'))\r
-def user_favorites(request, user, **kwargs):\r
-    favorites = FavoriteAction.objects.filter(canceled=False, user=user)\r
-\r
-    return {"favorites" : favorites, "view_user" : user}\r
-\r
-@user_view('users/subscriptions.html', 'subscriptions', _('subscription'), _('subscriptions'), True, tabbed=False)\r
-def user_subscriptions(request, user, **kwargs):\r
-    return _user_subscriptions(request, user, **kwargs)\r
-\r
-def _user_subscriptions(request, user, **kwargs):\r
-    enabled = True\r
-\r
-    tab = request.GET.get('tab', "settings")\r
-\r
-    # Manage tab\r
-    if tab == 'manage':\r
-        manage_open = True\r
-\r
-        auto = request.GET.get('auto', 'True')\r
-        if auto == 'True':\r
-            show_auto = True\r
-            subscriptions = QuestionSubscription.objects.filter(user=user).order_by('-last_view')\r
-        else:\r
-            show_auto = False\r
-            subscriptions = QuestionSubscription.objects.filter(user=user, auto_subscription=False).order_by('-last_view')\r
-\r
-        return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {\r
-            'subscriptions':subscriptions,\r
-            'view_user':user,\r
-            "auto":show_auto,\r
-            'manage_open':manage_open,\r
-        })\r
-    # Settings Tab and everything else\r
-    else:\r
-        manage_open = False\r
-        if request.method == 'POST':\r
-            manage_open = False\r
-            form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)\r
-\r
-            if form.is_valid():\r
-                form.save()\r
-                message = _('New subscription settings are now saved')\r
-\r
-                user.subscription_settings.enable_notifications = enabled\r
-                user.subscription_settings.save()\r
-\r
-                request.user.message_set.create(message=message)\r
-        else:\r
-            form = SubscriptionSettingsForm(instance=user.subscription_settings)\r
-\r
-        return {\r
-            'view_user':user,\r
-            'notificatons_on': enabled,\r
-            'form':form,\r
-            'manage_open':manage_open,\r
-        }\r
-\r
-@user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)\r
-def user_preferences(request, user, **kwargs):\r
-    if request.POST:\r
-        form = UserPreferencesForm(request.POST)\r
-\r
-        if form.is_valid():\r
-            user.prop.preferences = form.cleaned_data\r
-            request.user.message_set.create(message=_('New preferences saved'))\r
-\r
-    else:\r
-        preferences = user.prop.preferences\r
-\r
-        if preferences:\r
-            form = UserPreferencesForm(initial=preferences)\r
-        else:\r
-            form = UserPreferencesForm()\r
-            \r
-    return {'view_user': user, 'form': form}\r
-\r
-\r
+from forum.models import User
+from django.db.models import Q, Count
+from django.core.paginator import Paginator, EmptyPage, InvalidPage
+from django.template.defaultfilters import slugify
+from django.contrib.contenttypes.models import ContentType
+from django.core.urlresolvers import reverse
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from django.http import HttpResponse, HttpResponseRedirect, Http404
+from forum.http_responses import HttpResponseUnauthorized
+from django.utils.translation import ugettext as _
+from django.utils.http import urlquote_plus
+from django.utils.html import strip_tags
+from django.utils.encoding import smart_unicode
+from django.core.urlresolvers import reverse, NoReverseMatch
+from forum.forms import *
+from forum.utils.html import sanitize_html
+from forum.modules import decorate, ReturnImediatelyException
+from datetime import datetime, date
+from forum.actions import EditProfileAction, FavoriteAction, BonusRepAction, SuspendAction, ReportAction
+from forum.modules import ui
+from forum.utils import pagination
+from forum.views.readers import QuestionListPaginatorContext, AnswerPaginatorContext
+from forum.settings import ONLINE_USERS
+
+from django.contrib import messages
+
+import json 
+import time
+import datetime
+import decorators
+
+class UserReputationSort(pagination.SimpleSort):
+    def apply(self, objects):
+        return objects.order_by('-is_active', self.order_by)
+
+class UserListPaginatorContext(pagination.PaginatorContext):
+    def __init__(self, pagesizes=(20, 35, 60), default_pagesize=35):
+        super (UserListPaginatorContext, self).__init__('USERS_LIST', sort_methods=(
+            (_('reputation'), UserReputationSort(_('reputation'), '-reputation', _("sorted by reputation"))),
+            (_('newest'), pagination.SimpleSort(_('recent'), '-date_joined', _("newest members"))),
+            (_('last'), pagination.SimpleSort(_('oldest'), 'date_joined', _("oldest members"))),
+            (_('name'), pagination.SimpleSort(_('by username'), 'username', _("sorted by username"))),
+        ), pagesizes=pagesizes, default_pagesize=default_pagesize)
+
+class SubscriptionListPaginatorContext(pagination.PaginatorContext):
+    def __init__(self):
+        super (SubscriptionListPaginatorContext, self).__init__('SUBSCRIPTION_LIST', pagesizes=(5, 10, 20), default_pagesize=20)
+
+class UserAnswersPaginatorContext(pagination.PaginatorContext):
+    def __init__(self):
+        super (UserAnswersPaginatorContext, self).__init__('USER_ANSWER_LIST', sort_methods=(
+            (_('oldest'), pagination.SimpleSort(_('oldest answers'), 'added_at', _("oldest answers will be shown first"))),
+            (_('newest'), pagination.SimpleSort(_('newest answers'), '-added_at', _("newest answers will be shown first"))),
+            (_('votes'), pagination.SimpleSort(_('popular answers'), '-score', _("most voted answers will be shown first"))),
+        ), default_sort=_('votes'), pagesizes=(5, 10, 20), default_pagesize=20, prefix=_('answers'))
+
+USERS_PAGE_SIZE = 35# refactor - move to some constants file
+
+@decorators.render('users/users.html', 'users', _('users'), weight=200)
+def users(request):
+    suser = request.REQUEST.get('q', "")
+    users = User.objects.all()
+
+    if suser != "":
+        users = users.filter(username__icontains=suser)
+
+    return pagination.paginated(request, ('users', UserListPaginatorContext()), {
+        "users" : users,
+        "suser" : suser,
+    })
+
+
+@decorators.render('users/online_users.html', 'online_users', _('Online Users'), weight=200, tabbed=False)
+def online_users(request):
+    suser = request.REQUEST.get('q', "")
+
+    sort = ""
+    if request.GET.get("sort", None):
+        try:
+            sort = int(request.GET["sort"])
+        except ValueError:
+            logging.error('Found invalid sort "%s", loading %s, refered by %s' % (
+                request.GET.get("sort", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+            ))
+            raise Http404()
+
+    page = 0
+    if request.GET.get("page", None):
+        try:
+            page = int(request.GET["page"])
+        except ValueError:
+            logging.error('Found invalid page "%s", loading %s, refered by %s' % (
+                request.GET.get("page", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+            ))
+            raise Http404()
+
+    pagesize = 10
+    if request.GET.get("pagesize", None):
+        try:
+            pagesize = int(request.GET["pagesize"])
+        except ValueError:
+            logging.error('Found invalid pagesize "%s", loading %s, refered by %s' % (
+                request.GET.get("pagesize", ''), request.path, request.META.get('HTTP_REFERER', 'UNKNOWN')
+            ))
+            raise Http404()
+
+
+    users = None
+    if sort == "reputation":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.reputation)
+    elif sort == "newest" :
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)
+    elif sort == "last":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.last)
+    elif sort == "name":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.name)
+    elif sort == "oldest":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.oldest)
+    elif sort == "newest":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.newest)
+    elif sort == "votes":
+        users = sorted(ONLINE_USERS.sets.keys(), key=lambda user: user.votes)
+    else:
+        users = sorted(ONLINE_USERS.iteritems(), key=lambda x: x[1])
+
+    return render_to_response('users/online_users.html', {
+        "users" : users,
+        "suser" : suser,
+        "sort" : sort,
+        "page" : page,
+        "pageSize" : pagesize,
+    })
+
+
+def edit_user(request, id, slug):
+    user = get_object_or_404(User, id=id)
+    if not (request.user.is_superuser or request.user == user):
+        return HttpResponseUnauthorized(request)
+    if request.method == "POST":
+        form = EditUserForm(user, request.POST)
+        if form.is_valid():
+            new_email = sanitize_html(form.cleaned_data['email'])
+
+            if new_email != user.email:
+                user.email = new_email
+                user.email_isvalid = False
+
+                try:
+                    hash = ValidationHash.objects.get(user=request.user, type='email')
+                    hash.delete()
+                except:
+                    pass
+
+            if settings.EDITABLE_SCREEN_NAME:
+                user.username = sanitize_html(form.cleaned_data['username'])
+            user.real_name = sanitize_html(form.cleaned_data['realname'])
+            user.website = sanitize_html(form.cleaned_data['website'])
+            user.location = sanitize_html(form.cleaned_data['city'])
+            user.date_of_birth = form.cleaned_data['birthday']
+            if user.date_of_birth == "None":
+                user.date_of_birth = datetime(1900, 1, 1, 0, 0)
+            user.about = sanitize_html(form.cleaned_data['about'])
+
+            user.save()
+            EditProfileAction(user=user, ip=request.META['REMOTE_ADDR']).save()
+
+            messages.info(request, _("Profile updated."))
+            return HttpResponseRedirect(user.get_profile_url())
+    else:
+        form = EditUserForm(user)
+    return render_to_response('users/edit.html', {
+    'user': user,
+    'form' : form,
+    'gravatar_faq_url' : reverse('faq') + '#gravatar',
+    }, context_instance=RequestContext(request))
+
+
+@decorate.withfn(decorators.command)
+def user_powers(request, id, action, status):
+    if not request.user.is_superuser:
+        raise decorators.CommandException(_("Only superusers are allowed to alter other users permissions."))
+
+    if (action == 'remove' and 'status' == 'super') and not request.user.is_siteowner():
+        raise decorators.CommandException(_("Only the site owner can remove the super user status from other user."))
+
+    user = get_object_or_404(User, id=id)
+    new_state = action == 'grant'
+
+    if status == 'super':
+        user.is_superuser = new_state
+    elif status == 'staff':
+        user.is_staff = new_state
+    else:
+        raise Http404()
+
+    user.save()
+    return decorators.RefreshPageCommand()
+
+
+@decorate.withfn(decorators.command)
+def award_points(request, id):
+    if not request.POST:
+        return render_to_response('users/karma_bonus.html')
+
+    if not request.user.is_superuser:
+        raise decorators.CommandException(_("Only superusers are allowed to award reputation points"))
+
+    try:
+        points = int(request.POST['points'])
+    except:
+        raise decorators.CommandException(_("Invalid number of points to award."))
+
+    user = get_object_or_404(User, id=id)
+
+    extra = dict(message=request.POST.get('message', ''), awarding_user=request.user.id, value=points)
+
+    BonusRepAction(user=request.user, extra=extra).save(data=dict(value=points, affected=user))
+
+    return {'commands': {
+            'update_profile_karma': [user.reputation]
+        }}
+    
+
+@decorate.withfn(decorators.command)
+def suspend(request, id):
+    user = get_object_or_404(User, id=id)
+
+    if not request.user.is_superuser:
+        raise decorators.CommandException(_("Only superusers can suspend other users"))
+
+    if not request.POST.get('bantype', None):
+        if user.is_suspended():
+            suspension = user.suspension
+            suspension.cancel(user=request.user, ip=request.META['REMOTE_ADDR'])
+            return decorators.RefreshPageCommand()
+        else:
+            return render_to_response('users/suspend_user.html')
+
+    data = {
+        'bantype': request.POST.get('bantype', 'Indefinitely').strip(),
+        'publicmsg': request.POST.get('publicmsg', _('Bad behaviour')),
+        'privatemsg': request.POST.get('privatemsg', None) or request.POST.get('publicmsg', ''),
+        'suspended': user
+    }
+
+    if data['bantype'] == 'forxdays':
+        try:
+            data['forxdays'] = int(request.POST['forxdays'])
+        except:
+            raise decorators.CommandException(_('Invalid numeric argument for the number of days.'))
+
+    SuspendAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)
+
+    return decorators.RefreshPageCommand()
+
+@decorate.withfn(decorators.command)
+def report_user(request, id):
+    user = get_object_or_404(User, id=id)
+
+    if not request.POST.get('publicmsg', None):
+        return render_to_response('users/report_user.html')
+
+    data = {
+        'publicmsg': request.POST.get('publicmsg', _('N/A')),
+        'reported': user
+    }
+
+    ReportAction(user=request.user, ip=request.META['REMOTE_ADDR']).save(data=data)
+
+
+    return decorators.RefreshPageCommand()
+
+
+
+def user_view(template, tab_name, tab_title, tab_description, private=False, tabbed=True, render_to=None, weight=500):
+    def decorator(fn):
+        def params(request, id=None, slug=None):
+            # Get the user object by id if the id parameter has been passed
+            if id is not None:
+                user = get_object_or_404(User, id=id)
+            # ...or by slug if the slug has been given
+            elif slug is not None:
+                try:
+                    user = User.objects.get(username__iexact=slug)
+                except User.DoesNotExist:
+                    raise Http404
+
+            if private and not (user == request.user or request.user.is_superuser):
+                raise ReturnImediatelyException(HttpResponseUnauthorized(request))
+
+            if render_to and (not render_to(user)):
+                raise ReturnImediatelyException(HttpResponseRedirect(user.get_profile_url()))
+
+            return [request, user], { 'slug' : slug, }
+
+        decorated = decorate.params.withfn(params)(fn)
+
+        def result(context_or_response, request, user, **kwargs):
+            rev_page_title = smart_unicode(user.username) + " - " + tab_description
+
+            # Check whether the return type of the decorated function is a context or Http Response
+            if isinstance(context_or_response, HttpResponse):
+                response = context_or_response
+
+                # If it is a response -- show it
+                return response
+            else:
+                # ...if it is a context move forward, update it and render it to response
+                context = context_or_response
+
+            context.update({
+                "tab": "users",
+                "active_tab" : tab_name,
+                "tab_description" : tab_description,
+                "page_title" : rev_page_title,
+                "can_view_private": (user == request.user) or request.user.is_superuser
+            })
+            return render_to_response(template, context, context_instance=RequestContext(request))
+
+        decorated = decorate.result.withfn(result, needs_params=True)(decorated)
+
+        if tabbed:
+            def url_getter(vu):
+                try:
+                    return reverse(fn.__name__, kwargs={'id': vu.id, 'slug': slugify(smart_unicode(vu.username))})
+                except NoReverseMatch:
+                    try:
+                        return reverse(fn.__name__, kwargs={'id': vu.id})
+                    except NoReverseMatch:
+                        return reverse(fn.__name__, kwargs={'slug': slugify(smart_unicode(vu.username))})
+
+            ui.register(ui.PROFILE_TABS, ui.ProfileTab(
+                tab_name, tab_title, tab_description,url_getter, private, render_to, weight
+            ))
+
+        return decorated
+    return decorator
+
+
+@user_view('users/stats.html', 'stats', _('overview'), _('user overview'))
+def user_profile(request, user, **kwargs):
+    questions = Question.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')
+    answers = Answer.objects.filter_state(deleted=False).filter(author=user).order_by('-added_at')
+
+    # Check whether the passed slug matches the one for the user object
+    slug = kwargs['slug']
+    if slug != slugify(smart_unicode(user.username)):
+        return HttpResponseRedirect(user.get_absolute_url())
+
+    up_votes = user.vote_up_count
+    down_votes = user.vote_down_count
+    votes_today = user.get_vote_count_today()
+    votes_total = user.can_vote_count_today()
+
+    user_tags = Tag.objects.filter(Q(nodes__author=user) | Q(nodes__children__author=user)) \
+        .annotate(user_tag_usage_count=Count('name')).order_by('-user_tag_usage_count')
+
+    awards = [(Badge.objects.get(id=b['id']), b['count']) for b in
+              Badge.objects.filter(awards__user=user).values('id').annotate(count=Count('cls')).order_by('-count')]
+
+    return pagination.paginated(request, (
+    ('questions', QuestionListPaginatorContext('USER_QUESTION_LIST', _('questions'), default_pagesize=15)),
+    ('answers', UserAnswersPaginatorContext())), {
+    "view_user" : user,
+    "questions" : questions,
+    "answers" : answers,
+    "up_votes" : up_votes,
+    "down_votes" : down_votes,
+    "total_votes": up_votes + down_votes,
+    "votes_today_left": votes_total-votes_today,
+    "votes_total_per_day": votes_total,
+    "user_tags" : user_tags[:50],
+    "awards": awards,
+    "total_awards" : len(awards),
+    })
+    
+@user_view('users/recent.html', 'recent', _('recent activity'), _('recent user activity'))
+def user_recent(request, user, **kwargs):
+    activities = user.actions.exclude(
+            action_type__in=("voteup", "votedown", "voteupcomment", "flag", "newpage", "editpage")).order_by(
+            '-action_date')[:USERS_PAGE_SIZE]
+
+    return {"view_user" : user, "activities" : activities}
+
+
+@user_view('users/reputation.html', 'reputation', _('reputation history'), _('graph of user karma'))
+def user_reputation(request, user, **kwargs):
+    rep = list(user.reputes.order_by('date'))
+    values = [r.value for r in rep]
+    redux = lambda x, y: x+y
+
+    graph_data = json.dumps([
+    (time.mktime(rep[i].date.timetuple()) * 1000, reduce(redux, values[:i+1], 0))
+    for i in range(len(values))
+    ])
+
+    rep = user.reputes.filter(action__canceled=False).order_by('-date')[0:20]
+
+    return {"view_user": user, "reputation": rep, "graph_data": graph_data}
+
+@user_view('users/votes.html', 'votes', _('votes'), _('user vote record'), True)
+def user_votes(request, user, **kwargs):
+    votes = user.votes.exclude(node__state_string__contains="(deleted").filter(
+            node__node_type__in=("question", "answer")).order_by('-voted_at')[:USERS_PAGE_SIZE]
+
+    return {"view_user" : user, "votes" : votes}
+
+@user_view('users/questions.html', 'favorites', _('favorites'), _('questions that user selected as his/her favorite'))
+def user_favorites(request, user, **kwargs):
+    favorites = FavoriteAction.objects.filter(canceled=False, user=user)
+
+    return {"favorites" : favorites, "view_user" : user}
+
+@user_view('users/subscriptions.html', 'subscriptions', _('subscription'), _('subscriptions'), True, tabbed=False)
+def user_subscriptions(request, user, **kwargs):
+    return _user_subscriptions(request, user, **kwargs)
+
+def _user_subscriptions(request, user, **kwargs):
+    enabled = True
+
+    tab = request.GET.get('tab', "settings")
+
+    # Manage tab
+    if tab == 'manage':
+        manage_open = True
+
+        auto = request.GET.get('auto', 'True')
+        if auto == 'True':
+            show_auto = True
+            subscriptions = QuestionSubscription.objects.filter(user=user).order_by('-last_view')
+        else:
+            show_auto = False
+            subscriptions = QuestionSubscription.objects.filter(user=user, auto_subscription=False).order_by('-last_view')
+
+        return pagination.paginated(request, ('subscriptions', SubscriptionListPaginatorContext()), {
+            'subscriptions':subscriptions,
+            'view_user':user,
+            "auto":show_auto,
+            'manage_open':manage_open,
+        })
+    # Settings Tab and everything else
+    else:
+        manage_open = False
+        if request.method == 'POST':
+            manage_open = False
+            form = SubscriptionSettingsForm(data=request.POST, instance=user.subscription_settings)
+
+            if form.is_valid():
+                form.save()
+                message = _('New subscription settings are now saved')
+
+                user.subscription_settings.enable_notifications = enabled
+                user.subscription_settings.save()
+
+                messages.info(request, message)
+        else:
+            form = SubscriptionSettingsForm(instance=user.subscription_settings)
+
+        return {
+            'view_user':user,
+            'notificatons_on': enabled,
+            'form':form,
+            'manage_open':manage_open,
+        }
+
+@user_view('users/preferences.html', 'preferences', _('preferences'), _('preferences'), True, tabbed=False)
+def user_preferences(request, user, **kwargs):
+    if request.POST:
+        form = UserPreferencesForm(request.POST)
+
+        if form.is_valid():
+            user.prop.preferences = form.cleaned_data
+            messages.info(request, _('New preferences saved'))
+
+    else:
+        preferences = user.prop.preferences
+
+        if preferences:
+            form = UserPreferencesForm(initial=preferences)
+        else:
+            form = UserPreferencesForm()
+            
+    return {'view_user': user, 'form': form}
+
+
index 8c7980af09da8cbaee9523c6e253fb5d2bdb4de7..304032c52d33f4f992a89c38b305ba15f0474e17 100644 (file)
@@ -12,6 +12,8 @@ from django.http import HttpResponseRedirect, HttpResponse, Http404
 from django.utils.html import *
 from django.utils.translation import ugettext as _
 
+from django.contrib import messages
+
 from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction, RetagAction, AnswerToQuestionAction, CommentToQuestionAction
 from forum.forms import *
 from forum.models import *
@@ -95,7 +97,7 @@ def ask(request):
                     }
 
                     if request.user.is_authenticated():
-                        request.user.message_set.create(message=_("Your question is pending until you %s.") % html.hyperlink(
+                        messages.info(request, _("Your question is pending until you %s.") % html.hyperlink(
                             reverse('send_validation_email'), _("validate your email")
                         ))
                         return HttpResponseRedirect(reverse('index'))
@@ -270,7 +272,7 @@ def answer(request, id):
             }
 
             if request.user.is_authenticated():
-                request.user.message_set.create(message=_("Your answer is pending until you %s.") % html.hyperlink(
+                messages.info(request, _("Your answer is pending until you %s.") % html.hyperlink(
                     reverse('send_validation_email'), _("validate your email")
                 ))
                 return HttpResponseRedirect(question.get_absolute_url())
index 2107bbbe8f3aa981d8700217f799afd9013e8e3b..c050754add3acb4ba8ba228383257d1e46d1352d 100644 (file)
@@ -1,7 +1,8 @@
+import json
+
 from django.utils.translation import ugettext as _
 from django.http import HttpResponse, HttpResponseRedirect
 from django.template import RequestContext
-from django.utils import simplejson
 from django.utils.encoding import smart_str
 from django.shortcuts import render_to_response
 from forum.modules import decorate
@@ -15,7 +16,6 @@ from forum.models.user import User
 from forum.forms.general import SimpleCaptchaForm
 
 import settings
-import logging
 
 def can_bypass_spam_check(user):
     return user.is_authenticated and (user.is_superuser or user.is_staff or cmp(int(user.reputation), REP_FOR_NO_SPAM_CHECK) > 0)
@@ -51,7 +51,7 @@ def check_spam(param, comment_type):
                     'success': False,
                     'error_message': _("Sorry, but akismet thinks your %s is spam.") % comment_type
                     }
-                    return HttpResponse(simplejson.dumps(response), mimetype="application/json")
+                    return HttpResponse(json.dumps(response), mimetype="application/json")
                 else:
                     captcha_checked = False
                     try:
index 4dc90cadee661a15db07c97fac30bed822f31d64..9053fcfae179db0a1a9af159bab61cb81f98c247 100644 (file)
@@ -94,7 +94,7 @@
                     if (data.errors == false) {
                         if (exporting) {
                             $('#wait_message').html('{% trans "Your backup is ready to be downloaded."%}');
-                            $('#download_link_a').attr('href', '{% url exporter_download %}?file=' + data.state.overall.fname)
+                            $('#download_link_a').attr('href', '{% url "exporter_download" %}?file=' + data.state.overall.fname)
                             $('#download_link').slideDown();
                         } else {
                             $('#wait_message').html('{% trans "All data sucessfully imported."%}')
                 }
              }, 1000);
 
-             $.getJSON('{% url exporter_state %}', callback);
+             $.getJSON('{% url "exporter_state" %}', callback);
         }
 
         check_state();
index e9b35aae691b5776f451a7082e73f327ad903410..1de38514efba53b7e29604211456fdcbc5a7b3f3 100644 (file)
@@ -1,5 +1,4 @@
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
 from django.utils.translation import ugettext as _
 
 from views import state, running, download
index edbeedc083ae80e6977e027099dd0cfb17d61f91..c7b3904dae76a70ab916b94babf884d28f1b2409 100644 (file)
@@ -1,11 +1,11 @@
 from __future__ import with_statement
 
 import os, tarfile, ConfigParser, datetime
+import json
 
 from StringIO import StringIO
 from django.http import HttpResponse, HttpResponseRedirect, Http404
 from django.utils.translation import ugettext as _
-from django.utils import simplejson
 from django.core.cache import cache
 from django.core.urlresolvers import reverse
 from forum.views.admin import admin_tools_page, admin_page
@@ -74,7 +74,7 @@ def running(request, mode):
     })
 
 def state(request):
-    return HttpResponse(simplejson.dumps(cache.get(CACHE_KEY)), mimetype="application/json")
+    return HttpResponse(json.dumps(cache.get(CACHE_KEY)), mimetype="application/json")
 
 @admin_page
 def download(request):
index 8562bad60a2853649239daeb7a5b00a15cd4f40a..b80c47767ff08846e8b49e960e6c675d30bf5871 100644 (file)
@@ -12,14 +12,8 @@ from django.utils.translation import ugettext as _
 
 import settings
 
-try:
-    from json import load as load_json
-except Exception:
-    from django.utils.simplejson import JSONDecoder
+from json import load as load_json
 
-    def load_json(json):
-        decoder = JSONDecoder()
-        return decoder.decode(json.read())
 
 class FacebookAuthConsumer(AuthenticationConsumer):
 
@@ -33,7 +27,7 @@ class FacebookAuthConsumer(AuthenticationConsumer):
         facebook_api_authentication_url = "https://graph.facebook.com/oauth/authorize?" + urlencode(args)
 
         return facebook_api_authentication_url
-    
+
     def process_authentication_request(self, request):
         try:
             args = dict(client_id=settings.FB_API_KEY, redirect_uri="%s%s" % (django_settings.APP_URL, request.path))
index 497533d056dfc894c2c42566aef5f05cc873a731..3b8effaacce92a0c4857756c59430376f0faf011 100644 (file)
@@ -1,3 +1,3 @@
-{% load extra_tags %}\r
-\r
-<a style="position: relative; top: -8px;" href="{% url auth_provider_signin provider="facebook" %}"><img src="{% media '/media/images/openid/facebook.gif' %}" /></a>\r
+{% load extra_tags %}
+
+<a style="position: relative; top: -8px;" href="{% url "auth_provider_signin" provider="facebook" %}"><img src="{% media '/media/images/openid/facebook.gif' %}" /></a>
index e66f3402f13778dbd05e42571ad43a81f96117b3..9f088c5cc3fffa8cd5360eb81baa4cb0d9b2d4a1 100644 (file)
@@ -1,31 +1,31 @@
-{% load i18n %}\r
-\r
-<fieldset id='local_login_fs'>\r
-  <p><span class='big strong'>{% trans 'Enter your local user name and password' %}</span><br/><span class='grey'>({% trans 'or select your external provider above' %})</span></p>\r
-  <table>\r
-    <tr>\r
-        <td>\r
-             <label for="id_username">{% trans 'Login name' %}</label>\r
-        </td>\r
-        <td>\r
-             <input id="id_username" type="text" class="required login" name="username" maxlength="30" />\r
-        </td>\r
-    </tr>\r
-    <tr>\r
-        <td>\r
-              <label for="id_password">{% trans 'Password' %}</label>\r
-        </td>\r
-        <td>\r
-             <input id="id_password" type="password" class="required login" name="password" maxlength="128" />\r
-        </td>\r
-    </tr>\r
-    <tr>\r
-        <td>\r
-            <input id="blogin" name="blogin" type="submit" value="{% trans 'Login' %}" />\r
-        </td>\r
-        <td>\r
-              <a href="{% url auth_local_register %}">{% trans 'Create account' %}</a><span>&nbsp;|&nbsp;</span><a href="{% url auth_request_tempsignin %}">{% trans 'Forgot your password?' %}</a>\r
-        </td>\r
-    </tr>\r
-  </table>\r
-</fieldset>\r
+{% load i18n %}
+
+<fieldset id='local_login_fs'>
+  <p><span class='big strong'>{% trans 'Enter your local user name and password' %}</span><br/><span class='grey'>({% trans 'or select your external provider above' %})</span></p>
+  <table>
+    <tr>
+        <td>
+             <label for="id_username">{% trans 'Login name' %}</label>
+        </td>
+        <td>
+             <input id="id_username" type="text" class="required login" name="username" maxlength="30" />
+        </td>
+    </tr>
+    <tr>
+        <td>
+              <label for="id_password">{% trans 'Password' %}</label>
+        </td>
+        <td>
+             <input id="id_password" type="password" class="required login" name="password" maxlength="128" />
+        </td>
+    </tr>
+    <tr>
+        <td>
+            <input id="blogin" name="blogin" type="submit" value="{% trans 'Login' %}" />
+        </td>
+        <td>
+              <a href="{% url "auth_local_register" %}">{% trans 'Create account' %}</a><span>&nbsp;|&nbsp;</span><a href="{% url "auth_request_tempsignin" %}">{% trans 'Forgot your password?' %}</a>
+        </td>
+    </tr>
+  </table>
+</fieldset>
index aeebc40ac537bc066d1a90fd000a06a85b91d97e..dfd63b46fb9a828d12ba7b83119445c0e130951a 100644 (file)
@@ -1,8 +1,7 @@
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
 from django.utils.translation import ugettext as _
 import views as app
 
 urlpatterns = patterns('',
     url(r'^%s%s%s$' % (_('account/'), _('local/'),  _('register/')), app.register, name='auth_local_register'),
-)
\ No newline at end of file
+)
index 54a6b4f5adfbb7006fd644b1b5310ae72f6b4710..d353de495d87f620a5235f5a0ebeeee08760aa6b 100644 (file)
@@ -1,11 +1,8 @@
+import json
+
 from consumer import OAuthAbstractAuthConsumer
 from forum.authentication.base import ConsumerTemplateContext
 
-try:
-    import json as simplejson
-except ImportError:
-    from django.utils import simplejson
-
 from lib import oauth2
 import settings
 
@@ -24,7 +21,7 @@ class TwitterAuthConsumer(OAuthAbstractAuthConsumer):
         json = self.fetch_data(key, "https://twitter.com/account/verify_credentials.json")
         
         if 'screen_name' in json:
-            creds = simplejson.loads(json)
+            creds = json.loads(json)
 
             return {
                 'username': creds['screen_name']
@@ -38,4 +35,4 @@ class TwitterAuthContext(ConsumerTemplateContext):
     type = 'DIRECT'
     weight = 150
     human_name = 'Twitter'
-    icon = '/media/images/openid/twitter.png'
\ No newline at end of file
+    icon = '/media/images/openid/twitter.png'
index 29a637562f13ec9281b6ef0ad92f65214edafbd3..2605587e3badf942a2289b4b3d96fcac807b029c 100644 (file)
@@ -4,7 +4,6 @@ import re
 
 from django.utils.encoding import smart_unicode
 from django.utils.html import escape
-from django.http import get_host
 
 from forum.authentication.base import AuthenticationConsumer, InvalidAuthentication
 import settings
@@ -165,8 +164,8 @@ def get_url_host(request):
         protocol = 'https'
     else:
         protocol = 'http'
-    host = escape(get_host(request))
+    host = escape(request.get_host())
     return '%s://%s' % (protocol, host)
 
 def get_full_url(request):
-    return get_url_host(request) + request.get_full_path()
\ No newline at end of file
+    return get_url_host(request) + request.get_full_path()
index 8659f5ae9288cb68b9f82f306caeb7b0e801a8d2..23d479bc890d90987afab4b37e333aca1d89ebf6 100644 (file)
@@ -1,20 +1,20 @@
-{% load i18n %}\r
-{% load extra_tags %}\r
-\r
-<fieldset>\r
-    <table>\r
-    <tr>\r
-        <td><p id="provider_name_slot">{% trans 'Enter your OpenId Url' %}</p></td>\r
-    </tr>\r
-    <tr>\r
-        <td>\r
-            <input id="openid_identifier" class="icon_input" name="openid_identifier" type="text"\r
-            style="width: 500px; background: url('{% media provider.icon %}') no-repeat left center" />\r
-        </td>\r
-        <td>\r
-            <input type="submit" name="ssignin" value="{% trans 'Login' %}" />\r
-        </td>\r
-    </tr>\r
-    </table>\r
-</fieldset>\r
-\r
+{% load i18n %}
+{% load extra_tags %}
+
+<fieldset>
+    <table>
+    <tr>
+        <td><p id="provider_name_slot">{% trans 'Enter your OpenId Url' %}</p></td>
+    </tr>
+    <tr>
+        <td>
+            <input id="openid_identifier" class="icon_input" name="openid_identifier" type="text"
+            style="width: 500px; background: url('{% media provider.icon %}') no-repeat left center" />
+        </td>
+        <td>
+            <input type="submit" name="ssignin" value="{% trans 'Login' %}" />
+        </td>
+    </tr>
+    </table>
+</fieldset>
+
index 0706886a55403df6909f9c59445493f1e799748b..ddcac3bccdaa68444ab5f9adf5b9d74e4697ea01 100644 (file)
@@ -1,7 +1,7 @@
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
 from django.http import  HttpResponse
 import settings
 
 urlpatterns = patterns('',
-    (r'^robots.txt$',  lambda r: HttpResponse(settings.ROBOTS_FILE.value)),
+    (r'^robots.txt$',  lambda r: HttpResponse(settings.ROBOTS_FILE.value, content_type='text/plain')),
 )
index 42de46d82e97dd1fa26eacb7810bc3a10c65d7e9..47fe52c071f40c4155ac8a633b61e1ad217e9aed 100644 (file)
@@ -1,28 +1,28 @@
-{% extends "osqaadmin/base.html" %}\r
-\r
-{% load i18n %}\r
-{% load user_tags %}\r
-\r
-{% block subtitle %}\r
-    {% trans "SX Importer" %}\r
-{% endblock %}\r
-{% block description %}\r
-    {% trans "Welcome to Stack Exchange dump importer." %}\r
-{% endblock %}\r
-\r
-{% block admincontent %}\r
-    <form method="post" action="" enctype="multipart/form-data">\r
-    {% csrf_token %}\r
-    <input type="file" name="dump" /><br>\r
-    {% trans "Your user id in stack exchange" %}\r
-    <input type="test" name="owneruid" size="3" value="2" /><br />\r
-\r
-    <input type="checkbox" checked="checked" name="mergesimilar" />\r
-    {% trans "Merge users with same user name and email" %}<br />\r
-\r
-    <input type="submit" value="submit" />\r
-    </form>\r
-    {% for n in names %}\r
-        <p>{{ n }}</p>\r
-    {% endfor %}\r
+{% extends "osqaadmin/base.html" %}
+
+{% load i18n %}
+{% load user_tags %}
+
+{% block subtitle %}
+    {% trans "SX Importer" %}
+{% endblock %}
+{% block description %}
+    {% trans "Welcome to Stack Exchange dump importer." %}
+{% endblock %}
+
+{% block admincontent %}
+    <form method="post" action="" enctype="multipart/form-data">
+    {% csrf_token %}
+    <input type="file" name="dump" /><br>
+    {% trans "Your user id in stack exchange" %}
+    <input type="test" name="owneruid" size="3" value="2" /><br />
+
+    <input type="checkbox" checked="checked" name="mergesimilar" />
+    {% trans "Merge users with same user name and email" %}<br />
+
+    <input type="submit" value="submit" />
+    </form>
+    {% for n in names %}
+        <p>{{ n }}</p>
+    {% endfor %}
 {% endblock %}
\ No newline at end of file
index 85fa636ffe627da635355efd9511655af3c2d013..83d887a934be3f3ae6099f9a7cb4f33cf7f8bef2 100644 (file)
@@ -1,9 +1,8 @@
-from django.conf.urls.defaults import *\r
-from django.views.generic.simple import direct_to_template\r
-from django.utils.translation import ugettext as _\r
-\r
-from views import sximporter\r
-\r
-urlpatterns = patterns('',\r
-    url(r'^%s%s$' % (_('admin/'), _('sximporter/')),  sximporter, name='sximporter'),\r
-)
\ No newline at end of file
+from django.conf.urls import patterns, url, include
+from django.utils.translation import ugettext as _
+
+from views import sximporter
+
+urlpatterns = patterns('',
+    url(r'^%s%s$' % (_('admin/'), _('sximporter/')),  sximporter, name='sximporter'),
+)
index ebaed2133e8c2957c814b991524e646a5202a780..fd597b77f513437ae89449911f37c677a3716c74 100644 (file)
@@ -1,38 +1,38 @@
-from django.shortcuts import render_to_response\r
-from django.template import RequestContext\r
-from forum.http_responses import HttpResponseUnauthorized\r
-from forum.models import User\r
-import importer\r
-from zipfile import ZipFile\r
-import os\r
-\r
-def sximporter(request):\r
-    if (not User.objects.exists()) or (request.user.is_authenticated() and request.user.is_superuser):\r
-        list = []\r
-        if request.method == "POST" and "dump" in request.FILES:\r
-            dump = ZipFile(request.FILES['dump'])\r
-            members = [f for f in dump.namelist() if f.endswith('.xml')]\r
-            extract_to = os.path.join(os.path.dirname(__file__), 'tmp')\r
-\r
-            if not os.path.exists(extract_to):\r
-                os.makedirs(extract_to)\r
-\r
-            for m in members:\r
-                f = open(os.path.join(extract_to, m), 'w')\r
-                f.write(dump.read(m))\r
-                f.close()\r
-\r
-            #dump.extractall(extract_to, members)\r
-            dump.close()\r
-\r
-            options = dict([(k, v) for k, v in request.POST.items()])\r
-            options['authenticated_user'] = (request.user.is_authenticated() and (request.user,) or (None,))[0]\r
-\r
-            importer.sximport(extract_to, options)\r
-\r
-        return render_to_response('modules/sximporter/page.html', {\r
-        'names': list\r
-        }, context_instance=RequestContext(request))\r
-    else:\r
-        return HttpResponseUnauthorized(request)\r
-\r
+from django.shortcuts import render_to_response
+from django.template import RequestContext
+from forum.http_responses import HttpResponseUnauthorized
+from forum.models import User
+import importer
+from zipfile import ZipFile
+import os
+
+def sximporter(request):
+    if (not User.objects.exists()) or (request.user.is_authenticated() and request.user.is_superuser):
+        list = []
+        if request.method == "POST" and "dump" in request.FILES:
+            dump = ZipFile(request.FILES['dump'])
+            members = [f for f in dump.namelist() if f.endswith('.xml')]
+            extract_to = os.path.join(os.path.dirname(__file__), 'tmp')
+
+            if not os.path.exists(extract_to):
+                os.makedirs(extract_to)
+
+            for m in members:
+                f = open(os.path.join(extract_to, m), 'w')
+                f.write(dump.read(m))
+                f.close()
+
+            #dump.extractall(extract_to, members)
+            dump.close()
+
+            options = dict([(k, v) for k, v in request.POST.items()])
+            options['authenticated_user'] = (request.user.is_authenticated() and (request.user,) or (None,))[0]
+
+            importer.sximport(extract_to, options)
+
+        return render_to_response('modules/sximporter/page.html', {
+        'names': list
+        }, context_instance=RequestContext(request))
+    else:
+        return HttpResponseUnauthorized(request)
+
index ce5bc8b23599c23a003df229bdee17b4e398ca29..fe7a003dd836e9660b18a6246ae218cba5edda0c 100644 (file)
@@ -18,9 +18,8 @@ import logging
 from xml.dom.minidom import parse, parseString
 from forum.base import get_database_engine
 from forum.models import Question, Answer, Comment, User
-from forum.settings import APP_URL, SVN_REVISION, APP_TITLE, APP_DESCRIPTION
+from forum.settings import APP_URL, VCS_REVISION, APP_TITLE, APP_DESCRIPTION
 from django import VERSION as DJANGO_VERSION
-from django.utils import simplejson
 from django.utils.html import escape
 from django.utils.encoding import smart_unicode
 from django.conf import settings as django_settings
@@ -82,7 +81,7 @@ def get_admin_emails():
 def check_for_updates():
     # Get the SVN Revision
     try:
-        svn_revision = int(SVN_REVISION.replace('SVN-', ''))
+        svn_revision = int(VCS_REVISION.replace('SVN-', ''))
     except ValueError:
         # Here we'll have to find another way of getting the SVN revision
         svn_revision = 0
index f49d10697696c91c059b23d14572d247411b186b..06d423c7c45d9c31fa367bfbd9bdf53525470417 100644 (file)
@@ -6,7 +6,7 @@ import settings
 from xml.dom.minidom import parse, parseString
 from xml.parsers.expat import ExpatError
 from forum.modules import ui, decorate
-from forum.settings import SVN_REVISION
+from forum.settings import VCS_REVISION
 from django.contrib.auth.middleware import AuthenticationMiddleware
 from django.core.exceptions import ObjectDoesNotExist
 from django.utils.encoding import smart_str
@@ -26,7 +26,7 @@ def process_request(result, self, request):
         for message in messages:
             # Get the SVN Revision
             try:
-                svn_revision = int(SVN_REVISION.replace('SVN-', ''))
+                svn_revision = int(VCS_REVISION.replace('SVN-', ''))
             except ValueError:
                 # Here we'll have to find another way of getting the SVN revision
                 svn_revision = 0
@@ -50,4 +50,4 @@ def process_request(result, self, request):
     except ExpatError:
         pass
 
-    return result
\ No newline at end of file
+    return result
index aed0d016d6fff035804f76e581084442a5fcb644..d07d9e3c6f1222dfc70c12ca9b8f9be2e136fdfc 100644 (file)
@@ -43,7 +43,7 @@ $(function() {
 
 {% block admincontent %}
 
-<a href="{% url updater_check %}" id="check_for_updates" class="button">{% trans "Check for Updates" %}</a>
+<a href="{% url "updater_check" %}" id="check_for_updates" class="button">{% trans "Check for Updates" %}</a>
 <div id="update_check_status"></div>
 
 {% endblock %}
index c3a6c4caf890e473da58c0baf8188078d0b6bfcf..58ad7ac0105fe91b0d3d9688a8ba559d528e75e9 100644 (file)
@@ -1,5 +1,4 @@
-from django.conf.urls.defaults import *
-from django.views.generic.simple import direct_to_template
+from django.conf.urls import patterns, url, include
 from django.utils.translation import ugettext as _
 
 from views import updater_index, updater_check
index f9894f584e6defa2ad62893817cdaabee0e0e20a..f9726f9e67d10a596ac6efaeb114a6c479fa24ca 100644 (file)
--- a/manage.py
+++ b/manage.py
@@ -1,13 +1,10 @@
 #!/usr/bin/env python
-from django.core.management import execute_manager
-try:
-    import settings # Assumed to be in the same directory.
-except ImportError, e:
-    import traceback
-    traceback.print_exc()
-    import sys
-    sys.stderr.write("Error: Can't find the file 'forms.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file forms.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
-    sys.exit(1)
+import os
+import sys
 
 if __name__ == "__main__":
-    execute_manager(settings)
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
+
+    from django.core.management import execute_from_command_line
+
+    execute_from_command_line(sys.argv)
index cd153f4aef101e455ca63fb81d41bd4fe7a528b1..0c0495ab5c8c9503edb6eabc6276f00ad2844ffc 100644 (file)
@@ -4,16 +4,15 @@ import sys
 
 SITE_ID = 1
 
-ADMIN_MEDIA_PREFIX = '/admin_media/'
-SECRET_KEY = '$oo^&_m&qwbib=(_4m_n*zn-d=g#s0he5fx9xonnym#8p6yigm'
+SECRET_KEY = 'a;::qCl1mfh?avagttOJ;8f5Rr54d,9qy7;o15M2cYO75?OQo51u3LnQ;!8N.:,7'
 
 CACHE_MAX_KEY_LENGTH = 235
 
 MIDDLEWARE_CLASSES = [
     'django.middleware.csrf.CsrfViewMiddleware',
-    'django.middleware.csrf.CsrfResponseMiddleware',
     'forum.middleware.django_cookies.CookiePreHandlerMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.common.CommonMiddleware',
     'forum.middleware.extended_user.ExtendedUser',
     'forum.middleware.anon_user.ConnectToSessionMessagesMiddleware',
@@ -28,8 +27,9 @@ MIDDLEWARE_CLASSES = [
 TEMPLATE_CONTEXT_PROCESSORS = [
     'django.core.context_processors.request',
     'forum.context.application_settings',
+    'django.contrib.messages.context_processors.messages',
     'forum.user_messages.context_processors.user_messages',
-    'django.core.context_processors.auth',
+    'django.contrib.auth.context_processors.auth',
 ]
 
 ROOT_URLCONF = 'urls'
@@ -48,25 +48,20 @@ DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
 ALLOW_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
 ALLOW_MAX_FILE_SIZE = 1024 * 1024
 
+SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
+
+MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
+
 # User settings
 from settings_local import *
 
-if DEBUG:
-    TEMPLATE_LOADERS = [
-        'django.template.loaders.filesystem.load_template_source',
-        'django.template.loaders.app_directories.load_template_source',
-        'forum.modules.template_loader.module_templates_loader',
-        'forum.skins.load_template_source',
-    ]
-else:
-    TEMPLATE_LOADERS = [
-        ('django.template.loaders.cached.Loader',(
-            'django.template.loaders.filesystem.load_template_source',
-            'django.template.loaders.app_directories.load_template_source',
-            'forum.modules.template_loader.module_templates_loader',
-            'forum.skins.load_template_source',
-            )),
-    ]
+template_loaders = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+    'forum.modules.template_loader.module_templates_loader',
+    'forum.skins.load_template_source',
+)
+TEMPLATE_LOADERS = list(template_loaders) if DEBUG else [ ('django.template.loaders.cached.Loader', template_loaders) ]
 
 try:
     if len(FORUM_SCRIPT_ALIAS) > 0:
@@ -117,7 +112,7 @@ INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.humanize',
     'django.contrib.sitemaps',
-    'django.contrib.markup',
+    'django.contrib.messages',
     'forum',
 ]
 
index 9ac25a581ec7a19bb2d306509ccbee981e864a27..81c1eaaf7093bc065e4bde3b61eb4eaf09736e13 100644 (file)
@@ -3,14 +3,33 @@ import os.path
 
 SITE_SRC_ROOT = os.path.dirname(__file__)
 LOG_FILENAME = 'django.osqa.log'
-
-#for logging
-import logging
-logging.basicConfig(
-    filename=os.path.join(SITE_SRC_ROOT, 'log', LOG_FILENAME),
-    level=logging.ERROR,
-    format='%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
-)
+LOGGING = {
+    'version': 1,
+    'formatters': {
+        'default': {
+            'format': '%(pathname)s TIME: %(asctime)s MSG: %(filename)s:%(funcName)s:%(lineno)d %(message)s',
+        }
+    },
+    'handlers': {
+        'file': {
+            'level': 'DEBUG',
+            'class': 'logging.FileHandler',
+            'formatter': 'default',
+            'filename': os.path.join(SITE_SRC_ROOT, 'log', LOG_FILENAME),
+        },
+    },
+    'loggers' : {
+        # ensure that all log entries are propagated to root
+        'django': { 'propagate': True },
+        'django.request': { 'propagate': True },
+        'django.security': { 'propagate': True },
+        'py.warnings': { 'propagate': True },
+    },
+    'root': {
+        'handlers': ['file'],
+        'level': 'DEBUG',
+    },
+}
 
 #ADMINS and MANAGERS
 ADMINS = ()
@@ -22,7 +41,7 @@ DEBUG_TOOLBAR_CONFIG = {
 }
 TEMPLATE_DEBUG = DEBUG
 INTERNAL_IPS = ('127.0.0.1',)
-
+ALLOWED_HOSTS = ('yourhostname.com',)
 
 DATABASES = {
     'default': {
@@ -32,6 +51,7 @@ DATABASES = {
         'PASSWORD': '',
         'HOST': '',
         'PORT': '',
+        'CONN_MAX_AGE': 600,
     }
 }
 
diff --git a/urls.py b/urls.py
index fb1fedab00d2624bab6ccb6597ab885702922a8f..e56bc01331e7ad3e6e8e5e252c73a94df0df2411 100644 (file)
--- a/urls.py
+++ b/urls.py
@@ -1,4 +1,4 @@
-from django.conf.urls.defaults import *
+from django.conf.urls import patterns, url, include
 from django.utils.translation import ugettext as _
 from django.conf import settings