summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/conf/forum_data_rules.py11
-rw-r--r--askbot/deps/livesettings/models.py58
-rw-r--r--askbot/deps/livesettings/overrides.py4
-rw-r--r--askbot/doc/source/changelog.rst2
-rw-r--r--askbot/doc/source/management-commands.rst2
-rw-r--r--askbot/exceptions.py5
-rw-r--r--askbot/management/commands/build_livesettings_cache.py12
-rw-r--r--askbot/models/__init__.py33
-rw-r--r--askbot/models/question.py9
-rw-r--r--askbot/setup_templates/settings.py3
-rw-r--r--askbot/setup_templates/settings.py.mustache2
-rw-r--r--askbot/skins/common/media/js/utils.js6
-rw-r--r--askbot/skins/default/media/style/lib_style.less5
-rw-r--r--askbot/skins/default/media/style/style.css155
-rw-r--r--askbot/skins/default/media/style/style.less136
-rw-r--r--askbot/skins/default/templates/macros.html21
-rw-r--r--askbot/skins/default/templates/meta/bottom_scripts.html45
-rw-r--r--askbot/skins/default/templates/meta/html_head_stylesheets.html3
-rw-r--r--askbot/skins/default/templates/question/content.html28
-rw-r--r--askbot/skins/default/templates/question/javascript.html62
-rw-r--r--askbot/skins/default/templates/question/question_card.html6
-rw-r--r--askbot/skins/default/templates/reopen.html4
-rw-r--r--askbot/skins/default/templates/revisions.html17
-rw-r--r--askbot/skins/default/templates/widgets/ask_button.html5
-rw-r--r--askbot/tests/badge_tests.py6
-rw-r--r--askbot/tests/permission_assertion_tests.py6
-rw-r--r--askbot/views/readers.py16
-rw-r--r--askbot/views/users.py3
-rw-r--r--askbot/views/writers.py5
29 files changed, 393 insertions, 277 deletions
diff --git a/askbot/conf/forum_data_rules.py b/askbot/conf/forum_data_rules.py
index a94a5f6c..46a1fe08 100644
--- a/askbot/conf/forum_data_rules.py
+++ b/askbot/conf/forum_data_rules.py
@@ -137,6 +137,17 @@ settings.register(
settings.register(
livesettings.BooleanValue(
FORUM_DATA_RULES,
+ 'LIMIT_ONE_ANSWER_PER_USER',
+ default = True,
+ description = _(
+ 'Limit one answer per question per user'
+ )
+ )
+)
+
+settings.register(
+ livesettings.BooleanValue(
+ FORUM_DATA_RULES,
'TAGS_ARE_REQUIRED',
description = _('Are tags required?'),
default = False,
diff --git a/askbot/deps/livesettings/models.py b/askbot/deps/livesettings/models.py
index 1a57dfc5..71db8acf 100644
--- a/askbot/deps/livesettings/models.py
+++ b/askbot/deps/livesettings/models.py
@@ -25,14 +25,20 @@ def _safe_get_siteid(site):
def find_setting(group, key, site=None):
"""Get a setting or longsetting by group and key, cache and return it."""
-
+
siteid = _safe_get_siteid(site)
setting = None
-
+
use_db, overrides = get_overrides(siteid)
ck = cache_key('Setting', siteid, group, key)
-
- if use_db:
+
+ grp = overrides.get(group, None)
+
+ if grp and key in grp:
+ val = grp[key]
+ setting = ImmutableSetting(key=key, group=group, value=val)
+ log.debug('Returning overridden: %s', setting)
+ elif use_db:
try:
setting = cache_get(ck)
@@ -45,10 +51,10 @@ def find_setting(group, key, site=None):
# maybe it is a "long setting"
try:
setting = LongSetting.objects.get(site__id__exact=siteid, key__exact=key, group__exact=group)
-
+
except LongSetting.DoesNotExist:
pass
-
+
cache_set(ck, value=setting)
else:
@@ -57,13 +63,13 @@ def find_setting(group, key, site=None):
val = grp[key]
setting = ImmutableSetting(key=key, group=group, value=val)
log.debug('Returning overridden: %s', setting)
-
+
if not setting:
raise SettingNotSet(key, cachekey=ck)
return setting
-class SettingNotSet(Exception):
+class SettingNotSet(Exception):
def __init__(self, k, cachekey=None):
self.key = k
self.cachekey = cachekey
@@ -77,22 +83,22 @@ class SettingManager(models.Manager):
class ImmutableSetting(object):
-
+
def __init__(self, group="", key="", value="", site=1):
self.site = site
self.group = group
self.key = key
self.value = value
-
+
def cache_key(self, *args, **kwargs):
return cache_key('OverrideSetting', self.site, self.group, self.key)
-
+
def delete(self):
pass
-
+
def save(self, *args, **kwargs):
pass
-
+
def __repr__(self):
return "ImmutableSetting: %s.%s=%s" % (self.group, self.key, self.value)
@@ -120,11 +126,18 @@ class Setting(models.Model, CachedObjectMixin):
site = self.site
except Site.DoesNotExist:
self.site = Site.objects.get_current()
-
+
super(Setting, self).save(force_insert=force_insert, force_update=force_update)
-
+
self.cache_set()
-
+
+ def cache_set(self, *args, **kwargs):
+ val = kwargs.pop('value', self)
+ key = self.cache_key(*args, **kwargs)
+ #TODO: fix this with Django's > 1.3 CACHE dict setting support
+ length = getattr(settings, 'LIVESETTINGS_CACHE_TIMEOUT', settings.CACHE_TIMEOUT)
+ cache_set(key, value=val, length=length)
+
class Meta:
unique_together = ('site', 'group', 'key')
@@ -149,7 +162,7 @@ class LongSetting(models.Model, CachedObjectMixin):
def cache_key(self, *args, **kwargs):
# note same cache pattern as Setting. This is so we can look up in one check.
- # they can't overlap anyway, so this is moderately safe. At the worst, the
+ # they can't overlap anyway, so this is moderately safe. At the worst, the
# Setting will override a LongSetting.
return cache_key('Setting', self.site, self.group, self.key)
@@ -164,7 +177,14 @@ class LongSetting(models.Model, CachedObjectMixin):
self.site = Site.objects.get_current()
super(LongSetting, self).save(force_insert=force_insert, force_update=force_update)
self.cache_set()
-
+
+ def cache_set(self, *args, **kwargs):
+ val = kwargs.pop('value', self)
+ key = self.cache_key(*args, **kwargs)
+ #TODO: fix this with Django's > 1.3 CACHE dict setting support
+ length = getattr(settings, 'LIVESETTINGS_CACHE_TIMEOUT', settings.CACHE_TIMEOUT)
+ cache_set(key, value=val, length=length)
+
class Meta:
unique_together = ('site', 'group', 'key')
-
+
diff --git a/askbot/deps/livesettings/overrides.py b/askbot/deps/livesettings/overrides.py
index f3dc3355..c2fc09df 100644
--- a/askbot/deps/livesettings/overrides.py
+++ b/askbot/deps/livesettings/overrides.py
@@ -35,7 +35,7 @@ def get_overrides(siteid=-1):
}
}
- In the settings dict above, the "val" entries must exactly match the format
+ In the settings dict above, the "val" entries must exactly match the format
stored in the database for a setting. Do not use a literal True or an integer,
it needs to be the string representation of them.
@@ -45,7 +45,7 @@ def get_overrides(siteid=-1):
if hasattr(djangosettings, 'LIVESETTINGS_OPTIONS'):
if siteid == -1:
siteid = _safe_get_siteid(None)
-
+
opts = djangosettings.LIVESETTINGS_OPTIONS
if opts.has_key(siteid):
opts = opts[siteid]
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index 3d21a907..e33f17e7 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -8,6 +8,8 @@ Development version
* Tag moderation (Evgeny)
* Editable optional three level category selector for the tags (Evgeny)
* Tag editor adding tags as they are typed (Evgeny)
+* Optionally allow limiting one answer per question per person (Evgeny)
+* Added management command `build_livesettings_cache` (Adolfo)
* Welcome email for the case when replying by email is enabled (Evgeny)
* Detection of email signature based on the response to the welcome email (Evgeny)
* Hide "website" and "about" section of the blocked user profiles
diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst
index b96251dc..2755bcf5 100644
--- a/askbot/doc/source/management-commands.rst
+++ b/askbot/doc/source/management-commands.rst
@@ -80,6 +80,8 @@ The bulk of the management commands fall into this group and will probably be th
+---------------------------------+-------------------------------------------------------------+
| `build_thread_summary_cache` | Rebuilds cache for the question summary snippet. |
+---------------------------------+-------------------------------------------------------------+
+| `build_livesettings_cache` | Rebuilds cache for the live settings. |
++---------------------------------+-------------------------------------------------------------+
| `delete_contextless_...` | `delete_contextless_badge_award_activities` |
| | Deletes Activity objects of type badge award where the |
| | related context object is lost. |
diff --git a/askbot/exceptions.py b/askbot/exceptions.py
index d2d5ddf0..12802e7e 100644
--- a/askbot/exceptions.py
+++ b/askbot/exceptions.py
@@ -19,6 +19,11 @@ class InsufficientReputation(exceptions.PermissionDenied):
"""
pass
+class AnswerAlreadyGiven(exceptions.PermissionDenied):
+ """Raised when user attempts to post a second answer
+ to the same question"""
+ pass
+
class DuplicateCommand(exceptions.PermissionDenied):
"""exception class to indicate that something
that can happen only once was attempted for the second time
diff --git a/askbot/management/commands/build_livesettings_cache.py b/askbot/management/commands/build_livesettings_cache.py
new file mode 100644
index 00000000..1898fc6a
--- /dev/null
+++ b/askbot/management/commands/build_livesettings_cache.py
@@ -0,0 +1,12 @@
+from django.core.management.base import NoArgsCommand
+
+class Command(NoArgsCommand):
+ '''Loads livesettings values to cache helping speed up
+ initial load time for the users'''
+
+ def handle_noargs(self, **options):
+ from askbot.conf import settings
+ #Just loads all the settings that way they will be in the cache
+ for key, value in settings._ConfigSettings__instance.items():
+ empty1 = getattr(settings, key)
+ print 'cache pre-loaded'
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 166bf0c8..78aa26c1 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -562,9 +562,16 @@ def user_assert_can_post_question(self):
)
-def user_assert_can_post_answer(self):
+def user_assert_can_post_answer(self, thread = None):
"""same as user_can_post_question
"""
+ limit_answers = askbot_settings.LIMIT_ONE_ANSWER_PER_USER
+ if limit_answers and thread.has_answer_by_user(self):
+ message = _(
+ 'Sorry, you already gave an answer, please edit it instead.'
+ )
+ raise askbot_exceptions.AnswerAlreadyGiven(message)
+
self.assert_can_post_question()
@@ -848,7 +855,9 @@ def user_assert_can_close_question(self, question = None):
def user_assert_can_reopen_question(self, question = None):
assert(question.post_type == 'question')
+ #for some reason rep to reopen own questions != rep to close own q's
owner_min_rep_setting = askbot_settings.MIN_REP_TO_REOPEN_OWN_QUESTIONS
+ min_rep_setting = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS
general_error_message = _(
'Sorry, only administrators, moderators '
@@ -861,15 +870,27 @@ def user_assert_can_reopen_question(self, question = None):
'a minimum reputation of %(min_rep)s is required'
) % {'min_rep': owner_min_rep_setting}
+ blocked_error_message = _(
+ 'Sorry, you cannot reopen questions '
+ 'because your account is blocked'
+ )
+
+ suspended_error_message = _(
+ 'Sorry, you cannot reopen questions '
+ 'because your account is suspended'
+ )
+
_assert_user_can(
user = self,
post = question,
- admin_or_moderator_required = True,
owner_can = True,
suspended_owner_cannot = True,
owner_min_rep_setting = owner_min_rep_setting,
+ min_rep_setting = min_rep_setting,
owner_low_rep_error_message = owner_low_rep_error_message,
- general_error_message = general_error_message
+ general_error_message = general_error_message,
+ blocked_error_message = blocked_error_message,
+ suspended_error_message = suspended_error_message
)
@@ -1725,7 +1746,7 @@ def user_post_answer(
assert(error_message is not None)
raise django_exceptions.PermissionDenied(error_message)
- self.assert_can_post_answer()
+ self.assert_can_post_answer(thread = question.thread)
if getattr(question, 'post_type', '') != 'question':
raise TypeError('question argument must be provided')
@@ -2888,6 +2909,10 @@ def send_instant_notifications_about_activity_in_post(
)
#send email for all recipients
for user in recipients:
+
+ if user.is_blocked():
+ continue
+
reply_address, alt_reply_address = get_reply_to_addresses(user, post)
subject_line, body_text = format_instant_notification_email(
diff --git a/askbot/models/question.py b/askbot/models/question.py
index bc1c45f5..acbfffe0 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -565,6 +565,14 @@ class Thread(models.Model):
output += answer.format_for_email_as_subthread()
return output
+ def get_answers_by_user(self, user):
+ """regardless - deleted or not"""
+ return self.posts.filter(post_type = 'answer', author = user)
+
+ def has_answer_by_user(self, user):
+ #use len to cache the queryset
+ return len(self.get_answers_by_user(user)) > 0
+
def tagname_meta_generator(self):
return u','.join([unicode(tag) for tag in self.get_tag_names()])
@@ -1055,6 +1063,7 @@ class AnonymousQuestion(AnonymousContent):
def publish(self,user):
added_at = datetime.datetime.now()
+ #todo: wrong - use User.post_question() instead
Thread.objects.create_new(
title = self.title,
added_at = added_at,
diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py
index 32af9920..632c4e70 100644
--- a/askbot/setup_templates/settings.py
+++ b/askbot/setup_templates/settings.py
@@ -181,6 +181,8 @@ INSTALLED_APPS = (
CACHE_BACKEND = 'locmem://'
#needed for django-keyedcache
CACHE_TIMEOUT = 6000
+#sets a special timeout for livesettings if you want to make them different
+LIVESETTINGS_CACHE_TIMEOUT = CACHE_TIMEOUT
CACHE_PREFIX = 'askbot' #make this unique
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
#If you use memcache you may want to uncomment the following line to enable memcached based sessions
@@ -229,3 +231,4 @@ CSRF_COOKIE_NAME = 'askbot_csrf'
STATICFILES_DIRS = ( os.path.join(ASKBOT_ROOT, 'skins'),)
RECAPTCHA_USE_SSL = True
+
diff --git a/askbot/setup_templates/settings.py.mustache b/askbot/setup_templates/settings.py.mustache
index 3c3daaa2..18ac214d 100644
--- a/askbot/setup_templates/settings.py.mustache
+++ b/askbot/setup_templates/settings.py.mustache
@@ -180,6 +180,8 @@ INSTALLED_APPS = (
CACHE_BACKEND = 'locmem://'
#needed for django-keyedcache
CACHE_TIMEOUT = 6000
+#sets a special timeout for livesettings if you want to make them different
+LIVESETTINGS_CACHE_TIMEOUT = CACHE_TIMEOUT
CACHE_PREFIX = 'askbot' #make this unique
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
#If you use memcache you may want to uncomment the following line to enable memcached based sessions
diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js
index 43316da7..da0e029b 100644
--- a/askbot/skins/common/media/js/utils.js
+++ b/askbot/skins/common/media/js/utils.js
@@ -1,6 +1,10 @@
//var $, scriptUrl, askbotSkin
+/**
+ * attention - this function needs to be retired
+ * as it cannot accurately give url to the media file
+ */
var mediaUrl = function(resource){
- return askbot['settings']['static_url'] + askbotSkin + '/' + resource;
+ return askbot['settings']['static_url'] + 'default' + '/' + resource;
};
var cleanUrl = function(url){
diff --git a/askbot/skins/default/media/style/lib_style.less b/askbot/skins/default/media/style/lib_style.less
index 63389526..05ab38f5 100644
--- a/askbot/skins/default/media/style/lib_style.less
+++ b/askbot/skins/default/media/style/lib_style.less
@@ -14,13 +14,12 @@
@body-font:Arial; /* "Trebuchet MS", sans-serif;*/
@sort-font:Georgia, serif;
-@main-font:'Yanone Kaffeesatz', Arial, sans-serif;
+@main-font:'Open Sans Condensed', Arial, sans-serif;
@secondary-font:Arial;
/* Buttons */
-.button-style(@w:100px ,@h:20px, @f:14px){
- width:@w;
+.button-style(@h:20px, @f:14px){
height:@h;
font-size:@f;
text-align:center;
diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css
index 348eb6b2..7a695825 100644
--- a/askbot/skins/default/media/style/style.css
+++ b/askbot/skins/default/media/style/style.css
@@ -195,7 +195,7 @@ body.user-messages {
text-align: center;
background-color: #f5dd69;
border-top: #fff 1px solid;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.notify p.notification {
margin-top: 6px;
@@ -222,7 +222,7 @@ body.user-messages {
#header {
margin-top: 0px;
background: #16160f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.content-wrapper {
/* wrapper positioning class */
@@ -275,12 +275,13 @@ body.user-messages {
float: right;
/* for #header.with-logo it is modified */
+ margin-right: 7px;
}
#metaNav a {
color: #e2e2ae;
padding: 0px 0px 0px 35px;
height: 25px;
- line-height: 30px;
+ line-height: 25px;
margin: 5px 0px 0px 10px;
font-size: 18px;
font-weight: 100;
@@ -337,7 +338,7 @@ body.user-messages {
border-bottom: #d3d3c2 1px solid;
border-top: #fcfcfc 1px solid;
margin-bottom: 10px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
#secondaryHeader #homeButton {
border-right: #afaf9e 1px solid;
@@ -359,11 +360,11 @@ body.user-messages {
float: left;
}
#secondaryHeader #scopeWrapper .scope-selector {
- font-size: 21px;
- color: #5a5a4b;
+ font-size: 20px;
+ color: #7a7a6b;
height: 55px;
line-height: 55px;
- margin-left: 24px;
+ margin-left: 16px;
}
#secondaryHeader #scopeWrapper .on {
background: url(../images/scopearrow.png) no-repeat center bottom;
@@ -376,7 +377,7 @@ body.user-messages {
display: inline-block;
background-color: #fff;
- width: 412px;
+ width: 400px;
border: 1px solid #c9c9b5;
float: right;
height: 42px;
@@ -384,21 +385,22 @@ body.user-messages {
}
#searchBar .searchInput,
#searchBar .searchInputCancelable {
- font-size: 30px;
- height: 40px;
+ font-size: 26px;
+ height: 39px;
font-weight: 300;
background: #FFF;
border: 0px;
color: #484848;
padding-left: 10px;
+ padding-top: 1px;
font-family: Arial;
- vertical-align: middle;
+ vertical-align: top;
}
#searchBar .searchInput {
- width: 352px;
+ width: 340px;
}
#searchBar .searchInputCancelable {
- width: 317px;
+ width: 305px;
}
#searchBar .logoutsearch {
width: 337px;
@@ -450,14 +452,13 @@ body.anon #searchBar .searchInputCancelable {
margin-top: 6px;
float: right;
text-transform: uppercase;
- width: 200px;
height: 42px;
- font-size: 23px;
+ font-size: 20px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -478,6 +479,9 @@ body.anon #searchBar .searchInputCancelable {
-webkit-box-shadow: 1px 1px 2px #636363;
-moz-box-shadow: 1px 1px 2px #636363;
box-shadow: 1px 1px 2px #636363;
+ width: 200px;
+ /* to match width of sidebar */
+
}
#askButton:hover {
background-color: #cde5e9;
@@ -522,7 +526,7 @@ body.anon #searchBar .searchInputCancelable {
.box p {
margin-bottom: 4px;
color: #707070;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.box p.info-box-follow-up-links {
text-align: right;
@@ -539,7 +543,7 @@ body.anon #searchBar .searchInputCancelable {
color: #656565;
padding-right: 10px;
margin-bottom: 10px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
width: 190px;
}
.box h3 {
@@ -547,7 +551,7 @@ body.anon #searchBar .searchInputCancelable {
font-size: 18px;
text-align: left;
font-weight: normal;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
padding-left: 0px;
}
.box .contributorback {
@@ -556,12 +560,10 @@ body.anon #searchBar .searchInputCancelable {
.box label {
color: #707070;
font-size: 15px;
- display: block;
- float: right;
+ vertical-align: bottom;
+ display: inline;
text-align: left;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
- width: 80px;
- margin-right: 18px;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.box #displayTagFilterControl label,
.box #emailTagFilterControl label {
@@ -594,7 +596,7 @@ body.anon #searchBar .searchInputCancelable {
.box .inputs #ignoredTagInput,
.box .inputs #subscribedTagInput,
.box .inputs #ab-tag-search {
- width: 156px;
+ width: 152px;
padding-left: 5px;
border: #c9c9b5 1px solid;
height: 25px;
@@ -609,14 +611,13 @@ body.anon #searchBar .searchInputCancelable {
border: 0;
font-weight: bold;
margin-top: -2px;
- width: 30px;
height: 27px;
font-size: 14px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -672,14 +673,13 @@ body.anon #searchBar .searchInputCancelable {
font-weight: normal;
margin-top: 3px;
display: block;
- width: 120px;
height: 34px;
font-size: 21px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -702,6 +702,7 @@ body.anon #searchBar .searchInputCancelable {
box-shadow: 1px 1px 2px #636363;
margin: 0 auto;
padding: 0;
+ width: 130px;
}
.box a.followed:hover,
.box a.follow:hover {
@@ -740,7 +741,7 @@ body.anon #searchBar .searchInputCancelable {
text-align: center;
}
.box .notify-sidebar #question-subscribe-sidebar {
- margin: 7px 0 0 3px;
+ margin: 0 0 0 3px;
}
.users-page .box label {
display: inline;
@@ -877,20 +878,20 @@ body.anon #searchBar .searchInputCancelable {
/* ----- Headline, containing number of questions and tags selected, check main_page/headline.html ----- */
#questionCount {
font-weight: bold;
- font-size: 23px;
+ font-size: 20px;
color: #7ea9b3;
width: 200px;
float: left;
- margin-bottom: 8px;
+ margin-bottom: 6px;
padding-top: 6px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
#listSearchTags {
float: left;
margin-top: 3px;
color: #707070;
font-size: 16px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
ul#searchTags {
margin-left: 10px;
@@ -904,7 +905,7 @@ ul#searchTags {
margin: 5px 0 10px 0;
padding: 0px;
float: left;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.search-tips a {
text-decoration: underline;
@@ -918,28 +919,26 @@ ul#searchTags {
padding: 0;
width: 100%;
}
-.main-page #question-list {
- margin-top: 10px;
-}
.short-summary {
position: relative;
filter: inherit;
- padding: 10px;
+ padding: 10px 0 3px 0;
border-bottom: 1px solid #DDDBCE;
margin-bottom: 1px;
overflow: hidden;
- width: 710px;
+ width: 733px;
float: left;
- background: url(../images/summary-background.png) repeat-x;
+ /*background: url(../images/summary-background.png) repeat-x;*/
+
}
.short-summary h2 {
- font-size: 24px;
+ font-size: 20px;
font-weight: normal;
line-height: 26px;
padding-left: 0;
- margin-bottom: 6px;
+ margin-bottom: 7px;
display: block;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.short-summary a {
color: #464646;
@@ -964,12 +963,12 @@ ul#searchTags {
.short-summary .counts {
float: right;
margin: 4px 0 0 5px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.short-summary .counts .item-count {
padding: 0px 5px 0px 5px;
font-size: 25px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.short-summary .counts .votes div,
.short-summary .counts .views div,
@@ -981,7 +980,7 @@ ul#searchTags {
color: #646464;
}
.short-summary .tags {
- margin-top: 0;
+ margin: 0 0 0 1px;
}
.short-summary .votes,
.short-summary .answers,
@@ -1179,6 +1178,10 @@ ul.tags.marked-tags li,
ul#ab-user-tags li {
width: 160px;
margin: 5px;
+ margin-left: 0;
+}
+.tags-page ul.tags {
+ margin-left: 5px;
}
ul#related-tags li {
margin: 0 5px 8px 0;
@@ -1284,7 +1287,7 @@ ul#related-tags li {
/* ----- Ask and Edit Question Form template----- */
.section-title {
color: #7ea9b3;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
font-weight: bold;
font-size: 24px;
}
@@ -1373,14 +1376,13 @@ ul#related-tags li {
float: left;
font-weight: normal;
margin-top: 3px;
- width: 160px;
height: 34px;
font-size: 21px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -1560,11 +1562,11 @@ ul#related-tags li {
/* ----- Question template ----- */
.question-page h1 {
padding-top: 0px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.question-page h1 a {
color: #464646;
- font-size: 30px;
+ font-size: 26px;
font-weight: normal;
line-height: 1;
}
@@ -1573,12 +1575,12 @@ ul#related-tags li {
clear: both;
padding: 3px 0 0 23px;
font-size: 15px;
- width: 110px;
+ width: 130px;
background-position: center left;
margin-left: 0px !important;
}
.question-page p.rss a {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
vertical-align: top;
}
.question-page .question-content {
@@ -1592,7 +1594,7 @@ ul#related-tags li {
}
.question-page #question-table,
.question-page .answer-table {
- margin: 6px 0 6px 0;
+ margin: 8px 0 6px 0;
border-spacing: 0px;
width: 670px;
padding-right: 10px;
@@ -1743,7 +1745,7 @@ ul#related-tags li {
}
.question-page #questionCount {
float: left;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
line-height: 15px;
}
.question-page .question-img-upvote,
@@ -1792,7 +1794,7 @@ ul#related-tags li {
color: #7ea9b3;
width: 200px;
float: left;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.question-page .comments {
font-size: 12px;
@@ -1855,14 +1857,13 @@ ul#related-tags li {
.question-page .comments button {
line-height: 25px;
margin-bottom: 5px;
- width: 100px;
height: 27px;
font-size: 12px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -2035,8 +2036,8 @@ ul#related-tags li {
float: left;
text-align: center;
padding-top: 2px;
- margin: 10px 10px 0px 3px;
- /* smalls IE fixes */
+ margin: 0px 10px 0px 3px;
+ /* small IE fixes */
*margin: 0;
*height: 210px;
@@ -2046,15 +2047,16 @@ ul#related-tags li {
cursor: pointer;
}
.question-page .vote-number {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
- padding: 0px 0 5px 0;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ padding: 2px 0 5px 0;
font-size: 25px;
font-weight: bold;
color: #777;
}
.question-page .vote-buttons .notify-sidebar {
text-align: left;
- width: 120px;
+ width: 130px;
+ margin-top: 7px;
}
.question-page .vote-buttons .notify-sidebar label {
vertical-align: top;
@@ -2124,7 +2126,7 @@ ul#related-tags li {
margin-top: 10px;
}
.question-page #fmanswer h2 {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
color: #7ea9b3;
font-size: 24px;
}
@@ -2245,14 +2247,13 @@ ul#related-tags li {
.user-profile-page input.submit {
font-weight: normal;
margin: 5px 0px;
- width: 100px;
height: 26px;
font-size: 15px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -2341,14 +2342,13 @@ ul#related-tags li {
#local_login_buttons .submit-b,
#password-fs .submit-b,
#openid-fs .submit-b {
- width: 100px;
height: 24px;
font-size: 15px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -2492,7 +2492,7 @@ a:hover.medal {
}
.user-profile-page h2 {
padding: 10px 0px 10px 0px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
.user-details {
font-size: 13px;
@@ -2517,14 +2517,13 @@ a:hover.medal {
font-weight: bold;
line-height: 26px;
margin-top: -2px;
- width: 100px;
height: 26px;
font-size: 14px;
text-align: center;
text-decoration: none;
cursor: pointer;
color: #4a757f;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
text-shadow: 0px 1px 0px #c6d9dd;
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
@@ -2579,13 +2578,13 @@ a:hover.medal {
display: none;
}
.count {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
font-size: 200%;
font-weight: 700;
color: #777777;
}
.scoreNumber {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
font-size: 35px;
font-weight: 800;
color: #777;
@@ -2696,7 +2695,7 @@ a:hover.medal {
color: #525252;
}
.revision h3 {
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
font-size: 21px;
padding-left: 0px;
}
@@ -2803,7 +2802,7 @@ ins {
padding: 6px 0 0 0;
background: #16160f;
font-size: 16px;
- font-family: 'Yanone Kaffeesatz', Arial, sans-serif;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
}
#ground p {
margin-bottom: 0;
@@ -3375,6 +3374,9 @@ p.signup_p {
padding: 0;
margin-top: -3px;
}
+.user-profile-page ul.tags {
+ margin-left: 5px;
+}
.userList {
font-size: 13px;
}
@@ -3518,7 +3520,6 @@ body.anon.lang-es #searchBar .searchInputCancelable {
margin: 0 5px 3px 0;
}
.group-wiki .follow-toggle.group-join-btn {
- width: 150px;
margin: 4px auto 10px auto;
display: block;
}
diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less
index bfb567bb..916312d8 100644
--- a/askbot/skins/default/media/style/style.less
+++ b/askbot/skins/default/media/style/style.less
@@ -269,12 +269,13 @@ body.user-messages {
#metaNav {/* Top Navigation bar containing links for tags, people and badges, check widgets/header.html */
float: right;/* for #header.with-logo it is modified */
+ margin-right: 7px;
a {
color: #e2e2ae;
padding: 0px 0px 0px 35px;
height: 25px;
- line-height: 30px;
+ line-height: 25px;
margin:5px 0px 0px 10px;
font-size: 18px;
font-weight: 100;
@@ -367,11 +368,11 @@ body.user-messages {
}
.scope-selector{
- font-size:21px;
- color:#5a5a4b;
+ font-size:20px;
+ color:#7a7a6b;
height:55px;
line-height:55px;
- margin-left:24px
+ margin-left:16px
}
.on{
background:url(../images/scopearrow.png) no-repeat center bottom;
@@ -384,32 +385,33 @@ body.user-messages {
}
#searchBar { /* Main search form , check widgets/search_bar.html */
- display:inline-block;
+ display: inline-block;
background-color: #fff;
- width:412px;
+ width: 400px;
border: 1px solid #c9c9b5;
float:right;
height:42px;
margin:6px 0px 0px 15px;
.searchInput, .searchInputCancelable{
- font-size: 30px;
- height: 40px;
+ font-size: 26px;
+ height: 39px;
font-weight:300;
background:#FFF;
border:0px;
color:#484848;
padding-left:10px;
+ padding-top: 1px;
font-family:@body-font;
- vertical-align: middle;
+ vertical-align: top;
}
.searchInput,{
- width: 352px;
+ width: 340px;
}
.searchInputCancelable {
- width: 317px;
+ width: 305px;
}
.logoutsearch {
@@ -471,7 +473,8 @@ body.anon {
margin-top:6px;
float:right;
text-transform:uppercase;
- .button-style(200px, 42px, 23px);
+ .button-style(42px, 20px);
+ width: 200px;/* to match width of sidebar */
}
#askButton:hover{
@@ -545,12 +548,10 @@ body.anon {
label {
color: @info-text;
font-size:15px;
- display: block;
- float: right;
+ vertical-align: bottom;
+ display: inline;
text-align:left;
font-family:@main-font;
- width:80px;
- margin-right:18px;
}
#displayTagFilterControl label,
@@ -586,7 +587,7 @@ body.anon {
#ignoredTagInput,
#subscribedTagInput,
#ab-tag-search {
- width:156px;
+ width:152px;
padding-left:5px;
border:#c9c9b5 1px solid;
height:25px;
@@ -601,7 +602,7 @@ body.anon {
border:0;
font-weight:bold;
margin-top:-2px;
- .button-style(30px, 27px, 14px);
+ .button-style(27px, 14px);
.rounded-corners(4px);
}
#interestingTagAdd:hover,
@@ -626,8 +627,9 @@ body.anon {
font-weight:normal;
margin-top:3px;
display:block;
- .button-style(120px,34px,21px);
+ .button-style(34px,21px);
.center;
+ width: 130px;
}
a.followed:hover, a.follow:hover{
@@ -658,7 +660,7 @@ body.anon {
/* notify by email box */
.notify-sidebar #question-subscribe-sidebar {
- margin: 7px 0 0 3px;
+ margin: 0 0 0 3px;
}
}
@@ -672,7 +674,7 @@ body.anon {
font-size:16px;
border-bottom:#cccccc 1px solid;
font-size:13px;
-
+
strong{
float:right;
padding-right:10px;
@@ -680,16 +682,23 @@ body.anon {
}
.questions-related {
word-wrap: break-word;
-
+
p {
line-height: 20px;
- padding: 4px 0px 4px 0px;
+ padding: 4px 0px 9px 0px;
font-size: 16px;
font-weight:normal;
border-bottom:#cccccc 1px solid;
}
- a{
+ p:first-child {
+ margin-top: -4px;
+ }
+ p:last-child {
+ border: none;
+ }
+ a {
font-size:13px;
+ line-height: 1.3;
}
}
/* tips and markdown help are widgets for ask template */
@@ -812,12 +821,12 @@ body.anon {
#questionCount{
font-weight:bold;
- font-size:23px;
+ font-size:20px;
color:@section-title;
width:200px;
float:left;
- margin-bottom:8px;
- padding-top:6px;
+ margin-bottom:6px;
+ padding-top: 6px;
font-family:@main-font;
}
@@ -860,27 +869,23 @@ ul#searchTags {
width: 100%;
}
-.main-page #question-list {
- margin-top: 10px;
-}
-
.short-summary {
position: relative;
filter: inherit;
- padding: 10px;
+ padding: 10px 0 3px 0;
border-bottom: 1px solid #DDDBCE;
margin-bottom:1px;
overflow: hidden;
- width: 710px;
+ width: 733px;
float: left;
- background: url(../images/summary-background.png) repeat-x;
-
+ /*background: url(../images/summary-background.png) repeat-x;*/
+
h2 {
- font-size: 24px;
+ font-size: 20px;
font-weight:normal;
line-height: 26px;
padding-left: 0;
- margin-bottom:6px;
+ margin-bottom:7px;
display:block;
font-family:@main-font;
}
@@ -934,7 +939,7 @@ ul#searchTags {
}
.tags {
- margin-top: 0;
+ margin: 0 0 0 1px;
}
.votes, .answers, .favorites, .views {
@@ -1427,7 +1432,7 @@ ul#related-tags li {
float: left;
font-weight:normal;
margin-top:3px;
- .button-style(160px,34px,21px);
+ .button-style(34px,21px);
margin-right:7px;
}
@@ -1593,14 +1598,14 @@ ul#related-tags li {
h1{
padding-top:0px;
- font-family:@main-font;
- }
-
- h1 a{
- color:@question-link;
- font-size:30px;
- font-weight:normal;
- line-height:1;
+ font-family:@main-font;
+
+ a {
+ color:@question-link;
+ font-size:26px;
+ font-weight:normal;
+ line-height:1;
+ }
}
p.rss {
@@ -1608,7 +1613,7 @@ ul#related-tags li {
clear:both;
padding: 3px 0 0 23px;
font-size: 15px;
- width:110px;
+ width:130px;
background-position:center left;
margin-left:0px !important;
}
@@ -1617,7 +1622,7 @@ ul#related-tags li {
font-family:@main-font;
vertical-align: top;
}
-
+
.question-content{
float:right;
width:682px;
@@ -1637,7 +1642,7 @@ ul#related-tags li {
#question-table,
.answer-table {
- margin: 6px 0 6px 0;
+ margin: 8px 0 6px 0;
border-spacing: 0px;
width: 670px;
padding-right:10px;
@@ -1781,7 +1786,7 @@ ul#related-tags li {
.tabBar{
width:100%;
}
-
+
#questionCount{
float:left;
font-family:@main-font;
@@ -1816,9 +1821,6 @@ ul#related-tags li {
#fmanswer_button{
margin:8px 0px;
}
- #fmanswer_button.answer-own-question {
- width: 150px;
- }
.question-img-favorite:hover {
background: url(../images/vote-favorite-on.png)
}
@@ -1901,7 +1903,7 @@ ul#related-tags li {
button{
line-height:25px;
margin-bottom:5px;
- .button-style(100px, 27px, 12px);
+ .button-style(27px, 12px);
font-family:@body-font;
font-weight:bold;
}
@@ -1955,9 +1957,9 @@ ul#related-tags li {
margin: -3px 0px 0px -2px;
}
.content {
- margin-bottom: 7px;
+ margin-bottom: 7px;
}
-
+
.comment-votes {
float: left;
width: 37px;
@@ -2063,7 +2065,7 @@ ul#related-tags li {
.vote-number {
font-family: @main-font;
- padding: 0px 0 5px 0;
+ padding: 2px 0 5px 0;
font-size: 25px;
font-weight: bold;
color: #777;
@@ -2071,10 +2073,11 @@ ul#related-tags li {
.vote-buttons .notify-sidebar {
text-align: left;
- width:120px;
- }
- .vote-buttons .notify-sidebar label {
- vertical-align: top;
+ width:130px;
+ margin-top: 7px;
+ label {
+ vertical-align: top;
+ }
}
.tabBar-answer{
@@ -2091,7 +2094,7 @@ ul#related-tags li {
.accepted-answer {
background-color: #f7fecc;
border-bottom-color: #9BD59B;
-
+
.vote-buttons {
width:27px;
margin-right:10px;
@@ -2253,7 +2256,7 @@ ul#related-tags li {
input.submit{
font-weight:normal;
margin:5px 0px;
- .button-style(100px,26px,15px);
+ .button-style(26px,15px);
font-family:@body-font;
}
input.submit:hover{
@@ -2284,7 +2287,7 @@ ul#related-tags li {
width:200px;
}
.submit-b{
- .button-style(100px,24px,15px);
+ .button-style(24px,15px);
font-family:@body-font;
font-weight:bold;
padding-right:10px;
@@ -2442,7 +2445,7 @@ a:hover.medal {
font-weight:bold;
line-height:26px;
margin-top:-2px;
- .button-style(100px,26px,14px);
+ .button-style(26px,14px);
}
.follow-toggle:hover, .submit:hover {
@@ -3514,7 +3517,6 @@ body.anon.lang-es {
margin: 0 5px 3px 0;
}
.follow-toggle.group-join-btn {
- width: 150px;
margin: 4px auto 10px auto;
display: block;
}
diff --git a/askbot/skins/default/templates/macros.html b/askbot/skins/default/templates/macros.html
index 499acf41..4204d362 100644
--- a/askbot/skins/default/templates/macros.html
+++ b/askbot/skins/default/templates/macros.html
@@ -6,23 +6,6 @@
>{% if icon == False %}{% if site_label %}{{ site_label }}{% else %}{{ site }}{% endif %}{% endif %}</a>
{%- endmacro -%}
-{%- macro follow_toggle(follow, name, alias, id) -%}
- {# follow - boolean; name - object type name; alias - e.g. users name; id - object id #}
- <div
- class="follow-toggle follow-user-toggle"
- id="follow-{{ name|escape }}-{{ id }}"
- >
- {% if follow %}
- <div class="follow">{% trans %}follow {{alias}}{% endtrans %}</div>
- {% else %}
- <div class="unfollow">
- <div class="unfollow-red">{% trans %}unfollow {{alias}}{% endtrans %}</div>
- <div class="unfollow-green">{% trans %}following {{alias}}{% endtrans %}</div>
- </div>
- {% endif %}
- </div>
-{%- endmacro -%}
-
{%- macro inbox_post_snippet(response, inbox_section) -%}
<div id="re_{{response.id}}" class="re{% if response.is_new %} new highlight{% else %} seen{% endif %}">
<input type="checkbox" />
@@ -534,8 +517,8 @@ answer {% if answer.accepted() %}accepted-answer{% endif %} {% if answer.author_
{%- macro follow_toggle(follow, name, alias, id) -%}
{# follow - boolean; name - object type name; alias - e.g. users name; id - object id #}
<div
- class="follow-toggle"
- id="follow-{{ name }}-{{ id }}"
+ class="follow-toggle follow-user-toggle"
+ id="follow-{{ name|escape }}-{{ id }}"
>
{% if follow %}
<div class="follow">{% trans %}follow {{alias}}{% endtrans %}</div>
diff --git a/askbot/skins/default/templates/meta/bottom_scripts.html b/askbot/skins/default/templates/meta/bottom_scripts.html
index 093283f8..6c132203 100644
--- a/askbot/skins/default/templates/meta/bottom_scripts.html
+++ b/askbot/skins/default/templates/meta/bottom_scripts.html
@@ -42,33 +42,36 @@
</script>
{% endif %}
<script type="text/javascript">
-{% if active_tab != "tags" and active_tab != "users" %}
$(document).ready(function(){
- if (Modernizr.history) {
- // history management works!
- } else {
- // no history support :(
- //hash = unescape(window.location.hash).replace('#','').split("?")[0]
- hash = History.unescapeHash(window.location.hash).replace('#','').split("?")[0]
- if (hash.substring(0,11)==askbot['urls']['questions']){
- url = hash
- }else{
- url = askbot['urls']['questions']+hash
- }
- if (hash !== ''){
- window.location = 'http://'+window.location.host+url
- }
- }
-
+ {% if active_tab == 'questions' %}
+ if (Modernizr.history) {
+ // history management works!
+ } else {
+ // no history support :(
+ //hash = unescape(window.location.hash).replace('#','').split("?")[0]
+ {# todo: fix this evil code!!! #}
+ var hash = History.unescapeHash(window.location.hash).replace('#','').split("?")[0];
+ var questions_url = askbot['urls']['questions'];
+ if (hash.substring(0, questions_url.length) === questions_url) {
+ var url = hash;
+ } else {
+ var url = questions_url + hash;
+ }
+ if (hash !== '' && hash !== undefined && url !== undefined){
+ {# was this causing strange redirects in IE??? #}
+ window.location = 'http://' + window.location.host + url;
+ }
+ }
+ {% endif %}
// focus input on the search bar endcomment
- {% if active_tab != "ask" %}
+ {% if active_tab in ('users', 'questions', 'tags') %}
$('#keywords').focus();
- {% else %}
+ {% elif active_tab == 'ask' %}
$('#id_title').focus();
+ {% else %}
+ animateHashes();
{% endif %}
- animateHashes();
});
-{% endif %}
{% if user_messages %}
$('#validate_email_alert').click(function(){notify.close(true)})
notify.show();
diff --git a/askbot/skins/default/templates/meta/html_head_stylesheets.html b/askbot/skins/default/templates/meta/html_head_stylesheets.html
index 0d2ba463..8977f152 100644
--- a/askbot/skins/default/templates/meta/html_head_stylesheets.html
+++ b/askbot/skins/default/templates/meta/html_head_stylesheets.html
@@ -1,4 +1,5 @@
{% if settings.ASKBOT_CSS_DEVEL == False %}
+
<link href="{{"/style/style.css"|media }}" rel="stylesheet" type="text/css" />
{% else %}
<link href="{{"/style/style.less"|media }}" rel="stylesheet/less" type="text/css" />
@@ -7,7 +8,7 @@
{% if settings.USE_LOCAL_FONTS %}
{% include "meta/fonts.html" %}
{% else %}
- <link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:300,400,700' rel='stylesheet' type='text/css'>
+ <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:400,700&subset=latin,cyrillic-ext,latin-ext' rel='stylesheet' type='text/css'>
{% endif %}
{{ skin.get_extra_css_link() }}
{% if settings.USE_CUSTOM_CSS %}
diff --git a/askbot/skins/default/templates/question/content.html b/askbot/skins/default/templates/question/content.html
index 58b1bcca..66b3014b 100644
--- a/askbot/skins/default/templates/question/content.html
+++ b/askbot/skins/default/templates/question/content.html
@@ -3,11 +3,6 @@
{# ==== BEGIN: question/question_card.html ==== #}
{% include "question/question_card.html" %}
{# ==== END: question/question_card.html ==== #}
-{% if thread.closed %}
- {# ==== START: question/closed_question_info.html ==== #}
- {% include "question/closed_question_info.html" %}
- {# ==== END: question/closed_question_info.html ==== #}
-{% endif %}
{% if answers %}
<div class="clean"></div>
@@ -34,8 +29,21 @@
{% endif %}
{# ==== START: question/new_answer_form.html ==== #}
-{% include "question/new_answer_form.html" %}
-{# ==== END: question/new_answer_form.html ==== #}
-{% if request.user == question.author %}{# this is outside the form on purpose #}
- <input type="button" class="submit after-editor answer-own-question" id="fmanswer_button" value="{% trans %}Answer Your Own Question{% endtrans %}"/>
-{%endif%}
+{# buttons below cannot be cached yet #}
+{% if user_already_gave_answer %}
+ <a
+ class="submit"
+ href="{% url "edit_answer" previous_answer.id %}"
+ >{% trans %}Edit Your Previous Answer{% endtrans %}</a>
+ <span>{% trans %}(only one answer per question is allowed){% endtrans %}</span>
+{% else %}
+ {% include "question/new_answer_form.html" %}
+{% endif %}
+{% if question.closed == False and request.user == question.author %}{# this is outside the form on purpose #}
+<input
+ type="button"
+ class="submit after-editor answer-own-question"
+ id="fmanswer_button"
+ value="{% trans %}Answer Your Own Question{% endtrans %}"
+/>
+{% endif %}
diff --git a/askbot/skins/default/templates/question/javascript.html b/askbot/skins/default/templates/question/javascript.html
index f0d6ed3a..e76849c9 100644
--- a/askbot/skins/default/templates/question/javascript.html
+++ b/askbot/skins/default/templates/question/javascript.html
@@ -1,37 +1,35 @@
-{% if not thread.closed %}
- <script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
- <script type='text/javascript'>
- {% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %}
- var codeFriendlyMarkdown = true;
- {% else %}
- var codeFriendlyMarkdown = false;
- {% endif %}
- var maxCommentLength = {{settings.MAX_COMMENT_LENGTH}};
- askbot['urls']['postComments'] = '{% url post_comments %}';
- askbot['urls']['editComment'] = '{% url edit_comment %}';
- askbot['urls']['deleteComment'] = '{% url delete_comment %}';
- askbot['urls']['getComment'] = '{% url get_comment %}';
- askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #}
- askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}';
- askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}';
- askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}';
- askbot['urls']['upvote_comment'] = '{% url upvote_comment %}';
- askbot['urls']['delete_post'] = '{% url delete_post %}';
- askbot['urls']['get_html_template'] = '{% url get_html_template %}';
- askbot['messages']['addComment'] = '{% trans %}post a comment{% endtrans %}';
- {% if settings.SAVE_COMMENT_ON_ENTER %}
- askbot['settings']['saveCommentOnEnter'] = true;
- {% else %}
- askbot['settings']['saveCommentOnEnter'] = false;
- {% endif %}
- askbot['settings']['tagSource'] = '{{ settings.TAG_SOURCE }}';
- </script>
- {% if settings.EDITOR_TYPE == 'markdown' %}
- <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
- <script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
+<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
+<script type='text/javascript'>
+ {% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %}
+ var codeFriendlyMarkdown = true;
{% else %}
- {% include "meta/tinymce.html" %}
+ var codeFriendlyMarkdown = false;
{% endif %}
+ var maxCommentLength = {{settings.MAX_COMMENT_LENGTH}};
+ askbot['urls']['postComments'] = '{% url post_comments %}';
+ askbot['urls']['editComment'] = '{% url edit_comment %}';
+ askbot['urls']['deleteComment'] = '{% url delete_comment %}';
+ askbot['urls']['getComment'] = '{% url get_comment %}';
+ askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #}
+ askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}';
+ askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}';
+ askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}';
+ askbot['urls']['upvote_comment'] = '{% url upvote_comment %}';
+ askbot['urls']['delete_post'] = '{% url delete_post %}';
+ askbot['urls']['get_html_template'] = '{% url get_html_template %}';
+ askbot['messages']['addComment'] = '{% trans %}post a comment{% endtrans %}';
+ {% if settings.SAVE_COMMENT_ON_ENTER %}
+ askbot['settings']['saveCommentOnEnter'] = true;
+ {% else %}
+ askbot['settings']['saveCommentOnEnter'] = false;
+ {% endif %}
+ askbot['settings']['tagSource'] = '{{ settings.TAG_SOURCE }}';
+</script>
+{% if settings.EDITOR_TYPE == 'markdown' %}
+ <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
+ <script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
+{% else %}
+ {% include "meta/tinymce.html" %}
{% endif %}
<script type='text/javascript' src='{{"/js/jquery.validate.min.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/post.js"|media}}'></script>
diff --git a/askbot/skins/default/templates/question/question_card.html b/askbot/skins/default/templates/question/question_card.html
index dd52ea0f..c787bf34 100644
--- a/askbot/skins/default/templates/question/question_card.html
+++ b/askbot/skins/default/templates/question/question_card.html
@@ -25,6 +25,12 @@
}
})();
</script>
+ {% if thread.closed %}
+ <div class="clearfix"></div>
+ {# ==== START: question/closed_question_info.html ==== #}
+ {% include "question/closed_question_info.html" %}
+ {# ==== END: question/closed_question_info.html ==== #}
+ {% endif %}
{% include "question/question_comments.html" %}
</div>
diff --git a/askbot/skins/default/templates/reopen.html b/askbot/skins/default/templates/reopen.html
index 52d926ce..4ddd6f31 100644
--- a/askbot/skins/default/templates/reopen.html
+++ b/askbot/skins/default/templates/reopen.html
@@ -9,8 +9,8 @@
<span class="big">{{ question.get_question_title()|escape }}</span>
</a>
</p>
-<p>{% trans %}This question has been closed by
- <a href="{{closed_by_profile_url}}">{{closed_by_username|escape}}</a>
+<p>{% trans username = closed_by_username|escape %}This question has been closed by
+ <a href="{{closed_by_profile_url}}">{{username}}</a>
{% endtrans %}
</p>
<p>
diff --git a/askbot/skins/default/templates/revisions.html b/askbot/skins/default/templates/revisions.html
index aa1996a9..a0531b80 100644
--- a/askbot/skins/default/templates/revisions.html
+++ b/askbot/skins/default/templates/revisions.html
@@ -79,8 +79,7 @@
$("#nav_questions").attr('className',"on");
$('div.revision div[id^=rev-header-]').bind('click', function(){
var revId = this.id.substr(11);
- toggleRev(revId);
-
+ toggleRev(revId);
});
lanai.highlightSyntax();
});
@@ -88,13 +87,13 @@
function toggleRev(id) {
var arrow = $("#rev-arrow-" + id);
var visible = arrow.attr("src").indexOf("hide") > -1;
- var path = mediaUrl(
- "media/images/expander-arrow-" +
- (visible ? "show" : "hide") +
- ".gif" +
- "?v={{settings.MEDIA_RESOURCE_REVISION}}"
- );
- arrow.attr("src", path);
+ if (visible) {
+ var image_path = '{{ "/images/expander-arrow-show.gif"|media }}';
+ } else {
+ var image_path = '{{ "/images/expander-arrow-hide.gif"|media }}';
+ }
+ image_path = image_path + "?v={{settings.MEDIA_RESOURCE_REVISION}}";
+ arrow.attr("src", image_path);
$("#rev-body-" + id).slideToggle("fast");
}
</script>
diff --git a/askbot/skins/default/templates/widgets/ask_button.html b/askbot/skins/default/templates/widgets/ask_button.html
index 31448b73..a27f3b2c 100644
--- a/askbot/skins/default/templates/widgets/ask_button.html
+++ b/askbot/skins/default/templates/widgets/ask_button.html
@@ -2,5 +2,8 @@
{% if not search_state %} {# get empty SearchState() if there's none #}
{% set search_state=search_state|get_empty_search_state %}
{% endif %}
- <a id="askButton" href="{{ search_state.full_ask_url() }}">{% trans %}Ask Your Question{% endtrans %}</a>
+ <a
+ id="askButton"
+ href="{{ search_state.full_ask_url() }}{% if group %}&group={{ group.id }}{% endif %}"
+ >{% trans %}Ask Your Question{% endtrans %}</a>
{% endif %}
diff --git a/askbot/tests/badge_tests.py b/askbot/tests/badge_tests.py
index dbb37dde..b66eadcc 100644
--- a/askbot/tests/badge_tests.py
+++ b/askbot/tests/badge_tests.py
@@ -68,7 +68,8 @@ class BadgeTests(AskbotTestCase):
self.assert_have_badge(badge_key, recipient = self.u2, expected_count = 1)
#post another question and check that there are no new badges
- answer2 = self.post_answer(user = self.u2, question = question)
+ question2 = self.post_question(user = self.u1)
+ answer2 = self.post_answer(user = self.u2, question = question2)
answer2.score = min_score - 1
answer2.save()
self.u1.upvote(answer2)
@@ -269,7 +270,8 @@ class BadgeTests(AskbotTestCase):
answer = self.post_answer(user = self.u2, question = question)
self.u1.accept_best_answer(answer)
self.assert_have_badge('scholar', recipient = self.u1)
- answer2 = self.post_answer(user = self.u2, question = question)
+ question2 = self.post_question(user = self.u1)
+ answer2 = self.post_answer(user = self.u2, question = question2)
self.u1.accept_best_answer(answer2)
self.assert_have_badge(
'scholar',
diff --git a/askbot/tests/permission_assertion_tests.py b/askbot/tests/permission_assertion_tests.py
index 2f746ef9..8061bdb8 100644
--- a/askbot/tests/permission_assertion_tests.py
+++ b/askbot/tests/permission_assertion_tests.py
@@ -447,9 +447,9 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase):
)
- def test_high_rep_nonowner_cannot_reopen(self):
+ def test_high_rep_nonowner_can_reopen(self):
self.other_user.reputation = 1000000
- self.assert_cannot_reopen(user = self.other_user)
+ self.assert_can_reopen(user = self.other_user)
def test_low_rep_admin_can_reopen(self):
self.other_user.set_admin_status()
@@ -482,7 +482,7 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase):
self.assert_cannot_reopen(user = self.other_user)
class EditQuestionPermissionAssertionTests(utils.AskbotTestCase):
-
+
def setUp(self):
self.create_user()
self.create_user(username = 'other_user')
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index b37cacb2..467282e5 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -470,7 +470,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
user_post_id_list = [
id for id in post_to_author if post_to_author[id] == request.user.id
]
-
+
#resolve page number and comment number for permalinks
show_comment_position = None
if show_comment:
@@ -535,7 +535,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
is_cacheable = False
elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW:
is_cacheable = False
-
+
answer_form = AnswerForm(
initial = {
'wiki': question_post.wiki and askbot_settings.WIKI_ON,
@@ -547,6 +547,16 @@ def question(request, id):#refactor - long subroutine. display question body, an
request.user.is_authenticated() and request.user.can_post_comment()
)
+ user_already_gave_answer = False
+ previous_answer = None
+ if request.user.is_authenticated():
+ if askbot_settings.LIMIT_ONE_ANSWER_PER_USER:
+ for answer in answers:
+ if answer.author == request.user:
+ user_already_gave_answer = True
+ previous_answer = answer
+ break
+
data = {
'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix
'long_time': const.LONG_TIME,#"forever" caching
@@ -561,6 +571,8 @@ def question(request, id):#refactor - long subroutine. display question body, an
'user_votes': user_votes,
'user_post_id_list': user_post_id_list,
'user_can_post_comment': user_can_post_comment,#in general
+ 'user_already_gave_answer': user_already_gave_answer,
+ 'previous_answer': previous_answer,
'tab_id' : answer_sort_method,
'favorited' : favorited,
'similar_threads' : thread.get_similar_threads(),
diff --git a/askbot/views/users.py b/askbot/views/users.py
index c15e665b..9012a048 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -81,7 +81,7 @@ def show_users(request, by_group = False, group_id = None, group_slug = None):
except models.Tag.DoesNotExist:
raise Http404
if group_slug == slugify(group.name):
- users = models.User.objects.filter(
+ users = users.filter(
group_memberships__group__id = group_id
)
if request.user.is_authenticated():
@@ -99,7 +99,6 @@ def show_users(request, by_group = False, group_id = None, group_slug = None):
}
)
return HttpResponseRedirect(group_page_url)
-
is_paginated = True
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 58584b94..2dee9c37 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -24,6 +24,7 @@ from django.core import exceptions
from django.conf import settings
from django.views.decorators import csrf
+from askbot import exceptions as askbot_exceptions
from askbot import forms
from askbot import models
from askbot.conf import settings as askbot_settings
@@ -523,6 +524,10 @@ def answer(request, id):#process a new answer
timestamp = update_time,
)
return HttpResponseRedirect(answer.get_absolute_url())
+ except askbot_exceptions.AnswerAlreadyGiven, e:
+ request.user.message_set.create(message = unicode(e))
+ answer = question.thread.get_answers_by_user(request.user)[0]
+ return HttpResponseRedirect(answer.get_absolute_url())
except exceptions.PermissionDenied, e:
request.user.message_set.create(message = unicode(e))
else: