summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-04-10 10:50:02 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-04-10 10:50:02 -0400
commitc5a44b521650dd35c9092308ab30f29c5e3a8f43 (patch)
treee64430be885e3de7492e947d1f6b2523d56e979a
parent72c356b993771063e080c7cb47b8fc23a964dc1a (diff)
downloadaskbot-c5a44b521650dd35c9092308ab30f29c5e3a8f43.tar.gz
askbot-c5a44b521650dd35c9092308ab30f29c5e3a8f43.tar.bz2
askbot-c5a44b521650dd35c9092308ab30f29c5e3a8f43.zip
intermediate broken commit
-rwxr-xr-xforum/const.py2
-rwxr-xr-xforum/forms.py3
-rw-r--r--forum/middleware/view_log.py26
-rwxr-xr-xforum/models/__init__.py3
-rwxr-xr-xforum/models/question.py11
-rw-r--r--forum/search/indexer.py9
-rw-r--r--forum/search/state_manager.py28
-rwxr-xr-xforum/skins/default/media/style/style.css76
-rw-r--r--forum/skins/default/templates/base.html15
-rw-r--r--forum/skins/default/templates/book.html2
-rw-r--r--forum/skins/default/templates/header.html107
-rw-r--r--forum/skins/default/templates/index.html5
-rw-r--r--forum/skins/default/templates/index_.html5
-rw-r--r--forum/skins/default/templates/question.html13
-rw-r--r--forum/skins/default/templates/question_list.html2
-rw-r--r--forum/skins/default/templates/question_summary_list_roll.html2
-rw-r--r--forum/skins/default/templates/questions.html131
-rw-r--r--forum/skins/default/templates/tag_selector.html9
-rw-r--r--forum/skins/default/templates/tags.html3
-rw-r--r--forum/skins/default/templates/user_stats.html2
-rw-r--r--forum/skins/default/templates/users_questions.html2
-rwxr-xr-xforum/templatetags/extra_tags.py81
-rwxr-xr-xforum/utils/decorators.py1
-rw-r--r--forum/views/readers.py32
-rwxr-xr-xforum/views/users.py11
-rwxr-xr-xforum/views/writers.py10
-rw-r--r--settings.py1
27 files changed, 416 insertions, 176 deletions
diff --git a/forum/const.py b/forum/const.py
index 6f6086f0..dd85bb2e 100755
--- a/forum/const.py
+++ b/forum/const.py
@@ -58,7 +58,7 @@ DEFAULT_QUESTIONS_PAGE_SIZE = 30
PAGE_SIZES = (10,30,50)
UNANSWERED_MEANING_LIST = ('NO_ANSWERS','NO_UPVOTED_ANSWERS','NO_ACCEPTED_ANSWERS')
-UNANSWERED_MEANING = 'NO_ANSWERS'
+UNANSWERED_MEANING = 'NO_ACCEPTED_ANSWERS'
assert(UNANSWERED_MEANING in UNANSWERED_MEANING_LIST)
#todo:
diff --git a/forum/forms.py b/forum/forms.py
index c32ce6c0..2c2df738 100755
--- a/forum/forms.py
+++ b/forum/forms.py
@@ -136,6 +136,7 @@ class AdvancedSearchForm(forms.Form):
reset_tags = forms.BooleanField(required=False)
reset_author = forms.BooleanField(required=False)
reset_query = forms.BooleanField(required=False)
+ start_over = forms.BooleanField(required=False)
tags = forms.CharField(max_length=256,required=False)
author = forms.IntegerField(required=False)
page_size = forms.ChoiceField(choices=const.PAGE_SIZES, required=False)
@@ -188,6 +189,8 @@ class AdvancedSearchForm(forms.Form):
del self.cleaned_data['reset_author']
if self.cleaned_data['reset_query'] == False:
del self.cleaned_data['reset_query']
+ if self.cleaned_data['start_over'] == False:
+ del self.cleaned_data['start_over']
if self.cleaned_data['author'] is None:
del self.cleaned_data['author']
if self.cleaned_data['page'] is None:
diff --git a/forum/middleware/view_log.py b/forum/middleware/view_log.py
index 6f59568a..213292fe 100644
--- a/forum/middleware/view_log.py
+++ b/forum/middleware/view_log.py
@@ -1,8 +1,16 @@
import logging
from django.conf import settings
from forum.views.readers import questions as questions_view
-from forum.views.commands import vote as vote_view
-from django.views.static import serve as django_serve_view
+from forum.views.commands import vote
+from django.views.static import serve
+from forum.views.writers import delete_comment, question_comments, answer_comments
+from forum.views.readers import question, question_revisions, answer_revisions
+
+#todo: the list is getting bigger and bigger - maybe there is a better way to
+#trigger reset of sarch state?
+IGNORED_VIEWS = (serve, vote, delete_comment,
+ question_comments, answer_comments,
+ question, question_revisions, answer_revisions)
class ViewLog(object):
"""must be modified only in this middlware
@@ -36,17 +44,21 @@ class ViewLogMiddleware(object):
def process_view(self, request, view_func, view_args, view_kwargs):
if view_func == questions_view:
view_str = 'questions'
- elif view_func in (django_serve_view, vote_view):
+ elif view_func in IGNORED_VIEWS:
return
- elif settings.DEBUG == True:
+ else:
+ view_str = view_func.__name__
+ if view_str == 'wrap':
+ print str(view_func.__module__)# == 'forum.utils.decorators':
+ return
+
+ if settings.DEBUG == True:
#todo: dependency!
- from debug_toolbar.views import debug_media_view
+ from debug_toolbar.views import debug_media as debug_media_view
if view_func == debug_media_view:
return
else:
view_str = view_func.__name__
- else:
- view_str = view_func.__name__
if request.user.is_authenticated():
user_name = request.user.username
diff --git a/forum/models/__init__.py b/forum/models/__init__.py
index 2349c9e3..191f66d3 100755
--- a/forum/models/__init__.py
+++ b/forum/models/__init__.py
@@ -5,6 +5,8 @@ from meta import Vote, Comment, FlaggedItem
from user import Activity, ValidationHash, EmailFeedSetting, AuthKeyUserAssociation
from repute import Badge, Award, Repute
from django.core.urlresolvers import reverse
+from forum.search.indexer import create_fulltext_indexes
+from django.db.models.signals import post_syncdb
import re
from base import *
@@ -440,6 +442,7 @@ tags_updated.connect(record_update_tags, sender=Question)
post_save.connect(record_favorite_question, sender=FavoriteQuestion)
user_updated.connect(record_user_full_updated, sender=User)
user_logged_in.connect(post_stored_anonymous_content)
+post_syncdb.connect(create_fulltext_indexes)
Question = Question
QuestionRevision = QuestionRevision
diff --git a/forum/models/question.py b/forum/models/question.py
index 98b50490..aae99da2 100755
--- a/forum/models/question.py
+++ b/forum/models/question.py
@@ -10,6 +10,7 @@ import datetime
from django.conf import settings
from django.utils.datastructures import SortedDict
from forum.models.tag import MarkedTag
+from django.db.models import Q
markdowner = Markdown(html4tags=True)
@@ -77,7 +78,8 @@ class QuestionManager(models.Manager):
#return metadata
meta_data = {}
if tag_selector:
- qs = qs.filter(tags__name__in = tag_selector)
+ for tag in tag_selector:
+ qs = qs.filter(tags__name = tag)
if search_query:
qs = qs.filter(deleted=False).extra(
@@ -101,9 +103,9 @@ class QuestionManager(models.Manager):
#user contributed questions & answers
if author_selector:
try:
- u = User.objects.get(username=author_selector)
- qs = qs.filter(Q(author=u) | Q(answers__author=u))
- meta_data['author_name'] = author_selector
+ u = User.objects.get(id=int(author_selector))
+ qs = qs.filter(Q(author=u, deleted=False) | Q(answers__author=u, answers__deleted=False))
+ meta_data['author_name'] = u.username
except User.DoesNotExist:
meta_data['author_name'] = None
@@ -155,6 +157,7 @@ class QuestionManager(models.Manager):
if orderby:
#relevance will be ignored here
qs = qs.order_by(orderby)
+ qs = qs.distinct()
return qs, meta_data
def update_tags(self, question, tagnames, user):
diff --git a/forum/search/indexer.py b/forum/search/indexer.py
new file mode 100644
index 00000000..c7c45c59
--- /dev/null
+++ b/forum/search/indexer.py
@@ -0,0 +1,9 @@
+from django.conf import settings
+from django.db import connection
+
+def create_fulltext_indexes():
+ if settings.DATABASE_ENGINE == 'mysql':
+ cursor = connection.cursor()
+ cursor.execute('ALTER TABLE question ADD FULLTEXT (title, text, tagnames)')
+ cursor.execute('ALTER TABLE answer ADD FULLTEXT (title, text, tagnames)')
+
diff --git a/forum/search/state_manager.py b/forum/search/state_manager.py
index b36c5e53..4b3772b6 100644
--- a/forum/search/state_manager.py
+++ b/forum/search/state_manager.py
@@ -51,12 +51,13 @@ class SearchState(object):
setattr(self, key, new_value)
self.reset_page()
- def update_from_user_input(self,input):
+ def update_from_user_input(self,input, raw_input = {}):
#todo: this function will probably not
#fit the case of multiple parameters entered at the same tiem
- print ','.join(input.keys())
+ if 'start_over' in input:
+ self.reset()
+
if 'page' in input:
- print input['page']
self.page = input['page']
#special case - on page flip no other input is accepted
return
@@ -76,7 +77,10 @@ class SearchState(object):
if 'tags' in input:
if self.tags:
old_tags = self.tags.copy()
- self.tags.union(input['tags'])
+ print 'old tags %s' % str(old_tags)
+ print 'new tags %s' % str(input['tags'])
+ self.tags = self.tags.union(input['tags'])
+ print 'combined %s' % str(self.tags)
if self.tags != old_tags:
self.reset_page()
else:
@@ -97,11 +101,7 @@ class SearchState(object):
return
if 'reset_query' in input:
- if self.query:
- self.query = None
- self.reset_page()
- if self.sort == 'relevant':
- self.reset_sort()
+ self.reset_query()
return
self.update_value('author',input)
@@ -109,6 +109,9 @@ class SearchState(object):
if 'query' in input:
self.update_value('query',input)
self.sort = 'relevant'
+ elif 'search' in raw_input:#a case of use nulling search query by hand
+ self.reset_query()
+ return
if 'sort' in input:
@@ -120,6 +123,13 @@ class SearchState(object):
def reset_page(self):
self.page = 1
+ def reset_query(self):
+ if self.query:
+ self.query = None
+ self.reset_page()
+ if self.sort == 'relevant':
+ self.reset_sort()
+
def reset_sort(self):
self.sort = const.DEFAULT_POST_SORT_METHOD
diff --git a/forum/skins/default/media/style/style.css b/forum/skins/default/media/style/style.css
index 8315839d..81c6965e 100755
--- a/forum/skins/default/media/style/style.css
+++ b/forum/skins/default/media/style/style.css
@@ -204,7 +204,6 @@ blockquote {
background-color: #F5F5F5;
}
-/*页面布局*/
#wrapper {
width: 960px;
margin: auto;
@@ -340,28 +339,56 @@ blockquote {
padding-right: 0px;
}
-/*搜索栏*/
#searchBar {
width: 958px;
background-color: #888a85; /*#e9b96e;*/
border: 1px solid #aaaaaa;
- padding: 4px 0 0 0;
+ padding: 4px 0 5px 5px;
}
-
-/* #B02B2C */
-#searchBar .content {
+#fakeSearchBar {
+ width: 958px;
+ height: 4px;
+ background-color: #888a85; /*#e9b96e;*/
+ border: 1px solid #aaaaaa;
}
#searchBar .searchInput {
- font-size: 13px;
- height: 18px;
- width: 400px;
+ font-size: 24px;
+ line-height: 24px;
+ height: 36px;
+ width: 620px;
+ margin: 0px;
+ padding: 5px 0 0 5px;
+}
+
+#searchBar .searchInputCancelable {
+ font-size: 24px;
+ line-height: 24px;
+ height: 36px;
+ width: 570px;
+ padding: 5px 0 0 5px;
+ margin: 0px;
}
#searchBar .searchBtn {
- font-size: 14px;
- height: 26px;
- width: 80px;
+ font-size: 20px;
+ color: #666666;
+ height: 40px;
+ line-height: 22px;
+ text-align: center;
+ margin-top:1px;
+ padding-bottom: 4px;
+}
+
+#searchBar .cancelSearchBtn {
+ font-size: 20px;
+ color: #666666;
+ height: 40px;
+ width: 40px;
+ line-height: 22px;
+ padding-bottom: 4px;
+ margin-top:1px;
+ text-align: center;
}
#searchBar .options {
@@ -552,6 +579,10 @@ blockquote {
font-weight: 800;
}
+.evenMore a {
+ text-decoration: underline;
+}
+
.questions-count {
font-size: 32px;
font-family: sans-serif;
@@ -1503,6 +1534,10 @@ span.form-error {
width: 100%;
}
+#id_title {
+ width: 100%;
+}
+
.wmd-preview {
margin-top: 10px;
padding: 6px;
@@ -2539,3 +2574,20 @@ p.signup_p {
color:red;
padding:5px;
}
+
+.search-result-summary {
+ font-weight: bold;
+ font-size:18px;
+ line-height:30px;
+ margin:0px 0px 0px 5px;
+ padding:0px;
+}
+.search-tips {
+ font-size:12px;
+ line-height:12px;
+ margin:0 0 5px 5px;
+ padding:0px;
+}
+.search-tips a {
+ text-decoration: underline;
+}
diff --git a/forum/skins/default/templates/base.html b/forum/skins/default/templates/base.html
index 1018da50..fe5a95a3 100644
--- a/forum/skins/default/templates/base.html
+++ b/forum/skins/default/templates/base.html
@@ -2,6 +2,7 @@
<!-- template base.html -->
{% load extra_filters %}
{% load extra_tags %}
+{% load smart_if %}
{% load i18n %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@@ -36,7 +37,19 @@
});
</script>
{% endif %}
-
+ {% if active_tab != "tags" and active_tab != "users" %}
+ <script type="text/javascript">
+ $('#nav_ask').click(
+ function(){
+ alert('hullo');
+ var starting_title = $('#keywords').attr('value');
+ alert('tittle is ' + starting_title);
+ window.location.href = $(this).attr('href') + '?'
+ + starting_title;
+ }
+ );
+ </script>
+ {% endif %}
{% block forejs %}
{% endblock %}
</head>
diff --git a/forum/skins/default/templates/book.html b/forum/skins/default/templates/book.html
index 8574fa73..528b800d 100644
--- a/forum/skins/default/templates/book.html
+++ b/forum/skins/default/templates/book.html
@@ -122,7 +122,7 @@
</h3>
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% "see questions tagged with" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
diff --git a/forum/skins/default/templates/header.html b/forum/skins/default/templates/header.html
index aaf19874..efc0d8f2 100644
--- a/forum/skins/default/templates/header.html
+++ b/forum/skins/default/templates/header.html
@@ -1,5 +1,6 @@
<!-- template header.html -->
{% load extra_tags %}
+{% load smart_if %}
{% load i18n %}
<div id="roof">
<div id="navBar">
@@ -15,53 +16,75 @@
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
- <td width="23%">
- <div id="logo">
- <a href="{% url index %}">
- <img src="{% media "/media/images/logo.png" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
- </a>
- </div>
- </td>
- <td width="77%" valign="bottom">
- <div class="nav">
- <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a>
- <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a>
- <a id="nav_users" href="{% url users %}">{% trans "users" %}</a>
- {% if settings.BOOKS_ON %}
- <a id="nav_books" href="{% url books %}">{% trans "books" %}</a>
- {% endif %}
- <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a>
- {% comment %}
- <a id="nav_unanswered" href="{% url unanswered %}">{% trans "unanswered questions" %}</a>
- {% endcomment %}
- <div class="focus">
- <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
- </div>
+ <td width="23%">
+ <div id="logo">
+ <a href="{% url questions %}?start_over=true"><img
+ src="{% media "/media/images/logo.png" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/></a>
+ </div>
+ </td>
+ <td width="77%" valign="bottom">
+ <div class="nav">
+ <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a>
+ <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a>
+ <a id="nav_users" href="{% url users %}">{% trans "users" %}</a>
+ {% if settings.BOOKS_ON %}
+ <a id="nav_books" href="{% url books %}">{% trans "books" %}</a>
+ {% endif %}
+ <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a>
+ <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
+ {% comment %}
+ <a id="nav_unanswered" href="{% url unanswered %}">{% trans "unanswered questions" %}</a>
+ <div class="focus">
+ <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
</div>
-
- </td>
+ {% endcomment %}
+ </div>
+ </td>
</tr>
</table>
</div>
+ {% if active_tab != "ask" %}
<div id="searchBar">
- <table width="100%" border="0" cellpadding="0" cellspacing="0" class="content">
- <tr>
- <td align="center" valign="middle">
- <form action="{% url search %}" method="get">
- <div>
- <input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" />
- <input type="submit" name="Submit" value="{% trans "search" %}" class="searchBtn" />
- </div>
- <div class="options">
- <input id="type-question" type="radio" value="question" name="t"
- checked="checked" /><label for="type-question">{% trans "questions" %}</label>
- <input id="type-tag" type="radio" value="tag" name="t" /><label for="type-tag">{% trans "tags" %}</label>
- <input id="type-user" type="radio" value="user" name="t" /><label for="type-user">{% trans "users" %}</label>
- </div>
- </form>
- </td>
- </tr>
- </table>
+ {% comment %}url action depends on which tab is active{% endcomment %}
+ <form
+ {% if active_tab == "tags" or active_tab == "users" %}
+ action="{% url search %}"
+ {% else %}
+ action="{% url questions %}"
+ {% endif %}
+ method="get">
+ {% comment %} class was searchInput {% endcomment %}
+ <input
+ {% if query %}
+ class="searchInputCancelable"
+ {% else %}
+ class="searchInput"
+ {% endif %}
+ type="text"
+ value="{{ query|default_if_none:"" }}"
+ name="query"
+ id="keywords"/>
+ {% if active_tab == "tags" %}
+ <input type="hidden" name="t" value="tag"/>
+ {% else %}
+ {% if active_tab == "users" %}
+ <input type="hidden" name="t" value="user"/>
+ {% endif %}
+ {% endif %}
+ {% if query %}{% comment %}query is only defined by questions view{% endcomment %}
+ <input type="button"
+ value="x"
+ name="reset_query"
+ {% comment %}todo - make sure it works on Enter keypress{% endcomment %}
+ onclick="window.location.href='{% url questions %}?reset_query=true'"
+ value="true"
+ class="cancelSearchBtn"/>
+ {% endif %}
+ <input type="submit" value="{% trans "search" %}" name="search" class="searchBtn" default />
+ </form>
</div>
+ {% else %}
+ <div id="fakeSearchBar"></div>
+ {% endif %}
</div>
<!-- end template header.html -->
diff --git a/forum/skins/default/templates/index.html b/forum/skins/default/templates/index.html
index 8a885dd4..b90d788a 100644
--- a/forum/skins/default/templates/index.html
+++ b/forum/skins/default/templates/index.html
@@ -57,11 +57,12 @@
{% cache 60 recent_tags %}
{% for tag in tags %}
<a rel="tag"
- title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
{% endfor %}
{% endcache %}
</div>
- <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} </a> </div>
+ <div class="more"><a href="{% url tags %}">{% trans "see all tags" %}</a> </div>
</div>
</div>
{% if awards %}
diff --git a/forum/skins/default/templates/index_.html b/forum/skins/default/templates/index_.html
index 5e4cf533..8ba169a7 100644
--- a/forum/skins/default/templates/index_.html
+++ b/forum/skins/default/templates/index_.html
@@ -60,7 +60,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
@@ -87,7 +87,8 @@
<div class="tags">
{% for tag in tags %}
<a rel="tag"
- title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
{% endfor %}
</div>
<div class="more"><a href="{% url tags %}">{% trans "popular tags" %} »</a> </div>
diff --git a/forum/skins/default/templates/question.html b/forum/skins/default/templates/question.html
index 1c542c8b..c3564a34 100644
--- a/forum/skins/default/templates/question.html
+++ b/forum/skins/default/templates/question.html
@@ -128,10 +128,12 @@
{{ question.html|safe }}
</div>
<div id="question-controls" class="post-controls">
+ {% comment %}todo: here we have important case to reset search state{% endcomment %}
<div id="question-tags" class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" class="post-tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}&start_over=true"
+ class="post-tag"
+ title="{% blocktrans %}see questions tagged '{{tag}}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
{% joinitems using '<span class="action-link-separator">|</span>' %}
@@ -474,9 +476,10 @@
</p>
<p class="tags" >
{% for tag in tags %}
- <a href="{% url tag_questions tag.name|urlencode %}"
- 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/>
+ <a href="{% url questions %}?tags={{tag.name|urlencode}}&start_over=true"
+ title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{tag_name}}'{% endblocktrans %}"
+ rel="tag">{{ tag.name }}</a>
+ <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>
{% endfor %}
</p>
<p>
diff --git a/forum/skins/default/templates/question_list.html b/forum/skins/default/templates/question_list.html
index 53633691..38ac254a 100644
--- a/forum/skins/default/templates/question_list.html
+++ b/forum/skins/default/templates/question_list.html
@@ -16,7 +16,7 @@
</div>
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{%endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
diff --git a/forum/skins/default/templates/question_summary_list_roll.html b/forum/skins/default/templates/question_summary_list_roll.html
index 57685d6d..f2432a24 100644
--- a/forum/skins/default/templates/question_summary_list_roll.html
+++ b/forum/skins/default/templates/question_summary_list_roll.html
@@ -49,7 +49,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
diff --git a/forum/skins/default/templates/questions.html b/forum/skins/default/templates/questions.html
index 0a7c0c96..03ccc324 100644
--- a/forum/skins/default/templates/questions.html
+++ b/forum/skins/default/templates/questions.html
@@ -48,7 +48,7 @@
</div><br/>
{% endcomment %}
<div class="tabsC">
- <span class="label">{% trans "Pick:" %}</span>
+ <span class="label">{% trans "In:" %}</span>
<a id="all" class="off" href="?scope=all" title="{% trans "see all questions" %}">{% trans "all" %}</a>
<a id="unanswered" class="off" href="?scope=unanswered" title="{% trans "see unanswered questions" %}">{% trans "unanswered" %}</a>
{% if request.user.is_authenticated %}
@@ -134,20 +134,90 @@
{% endif %}
</div>
</div>
+{% if questions_count > 0 %}
+ <div style="clear:both">
+ <p class="search-result-summary">
+ {% if author_name or search_tags or query %}
+ {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} One question found{% plural %}{{q_num}} questions found{% endblocktrans %}
+ {% else %}
+ {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} {{q_num}} question{% plural %}{{q_num}} questions{% endblocktrans %}
+ {% endif %}
+ {% joinitems using ', ' %}
+ {% if author_name %}
+ {% blocktrans %}with {{author_name}}'s contributions{% endblocktrans %}
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ {% trans "tagged" %}
+ "{{ search_tags|join:"\", \"" }}"
+ {% endif %}
+ {% endjoinitems %}
+ </p>
+ {% if author_name or search_tags or query %}
+ <p class="search-tips">{% trans "Search tips:" %}
+ {% ifmany query search_tags author_name %}
+ {% joinitems using ', ' ' or ' %}
+ {% if author_name %}
+ <a href="{% url questions %}?reset_author=true">{% trans "reset author" %}</a>
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ <a href="{% url questions %}?reset_tags=true">{% trans "reset tags" %}</a>
+ {% endif %}
+ {% separator %}
+ {% ifmany query search_tags author_name %}
+ <a href="{% url questions %}?start_over=true">{% trans "start over" %}</a>
+ {% endifmany %}
+ {% endjoinitems %}
+ {% else %}
+ <a href="{% url questions %}?start_over=true">{% trans "start over" %}</a>
+ {% endifmany %}
+ {% trans " - to expand, or dig in by adding more tags and revising the query." %}
+ </p>
+ {% else %}
+ <p class="search-tips">{% trans "Search tip:" %} {% trans "add tags and a query to focus your search" %}</p>
+ {% endif %}
+
+ </div>
+{% endif %}
<div id="listA">
{% include "question_list.html" %}
+ {% comment %}todo: fix css here{% endcomment %}
{% if questions_count == 0 %}
+ {% comment %}todo: add tips to widen selection{% endcomment%}
<p class="evenMore" style="padding-top:30px;text-align:center;">
{% if scope == "unanswered" %}
- {% trans "There are no unanswered questions in this selection" %}
+ {% trans "There are no unanswered questions here" %}
{% endif %}
{% if scope == "favorite" %}
{% trans "No favorite questions here. " %}
- {% trans "Please bookmark some questions with a star and find them here later." %}
+ {% trans "Please start (bookmark) some questions when you visit them" %}
{% endif %}
- {% if scope == "all" %}
- {% trans "Did not find anything? Please feel free to ask your question!" %}
+ </p>
+ {% if query or search_tags or author_name %}
+ <p class="evenMore" style="text-align:center">
+ {% trans "You can expand your search by " %}
+ {% ifmany query search_tags author_name %}
+ {% joinitems using ', ' ' or ' %}
+ {% if author_name %}
+ <a href="{% url questions %}?reset_author=true">{% trans "resetting author" %}</a>
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ <a href="{% url questions %}?reset_tags=true">{% trans "resetting tags" %}</a>
+ {% endif %}
+ {% separator %}
+ {% ifmany query search_tags author_name %}
+ <a href="{% url questions %}?start_over=true">{% trans "starting over" %}</a>
+ {% endifmany %}
+ {% endjoinitems %}
+ {% else %}
+ <a href="{% url questions %}?start_over=true">{% trans "starting over" %}</a>
+ {% endifmany %}
+ </p>
{% endif %}
+ <p class="evenMore" style="text-align:center">
+ <a href="{% url ask %}">{% trans "Please always feel free to ask your question!" %}</a>
</p>
{% else %}
<p class="evenMore" style="padding-left:9px">
@@ -158,51 +228,14 @@
</div>
{% endblock %}
-{% block tail %}
- <div class="pager">{% cnprog_paginator context %}</div>
- <div class="pagesize">{% cnprog_pagesize context %}</div>
-{% endblock %}
+ {% block tail %}
+ {% if questions_count > 10 %}{%comment%}todo: remove magic number{%endcomment%}
+ <div class="pager">{% cnprog_paginator context %}</div>
+ <div class="pagesize">{% cnprog_pagesize context %}</div>
+ {% endif %}
+ {% endblock %}
{% block sidebar %}
-<div class="boxC">
- {% if searchtag %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num and searchtag as tagname %}have total {{q_num}} questions tagged {{tagname}}{% plural %}have total {{q_num}} questions tagged {{tagname}}{% endblocktrans %}
- {% else %}
- {% if searchtitle %}
- {% if settings.USE_SPHINX_SEARCH %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions containing {{searchtitle}} in full text {% plural %} have total {{q_num}} questions containing {{searchtitle}} in full text {% endblocktrans %}
- {% else %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions containing {{searchtitle}} {% plural %} have total {{q_num}} questions containing {{searchtitle}} {% endblocktrans %}
- {% endif %}
- {% else %}
- {% if is_unanswered %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} unanswered questions {% plural %} have total {{q_num}} unanswered questions {% endblocktrans %}
- {% else %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions {% plural %} have total {{q_num}} questions {% endblocktrans %}
- {% endif %}
- {% endif %}
- {% endif %}
- <p class="nomargin">
- {% ifequal tab_id "latest" %}
- {% trans "latest questions info" %}
- {% endifequal %}
-
- {% ifequal tab_id "active" %}
- {% trans "Questions are sorted by the <strong>time of last update</strong>." %}
- {% trans "Most recently answered ones are shown first." %}
- {% endifequal %}
-
- {% ifequal tab_id "hottest" %}
- {% trans "Questions sorted by <strong>number of responses</strong>." %}
- {% trans "Most answered questions are shown first." %}
- {% endifequal %}
-
- {% ifequal tab_id "mostvoted" %}
- {% trans "Questions are sorted by the <strong>number of votes</strong>." %}
- {% trans "Most voted questions are shown first." %}
- {% endifequal %}
- </p>
-</div>
{% if request.user.is_authenticated %}
{% include "tag_selector.html" %}
{% endif %}
@@ -210,7 +243,7 @@
<h3 class="subtitle">{% trans "Related tags" %}</h3>
<div class="tags">
{% for tag in tags %}
- <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
<br />
{% endfor %}
diff --git a/forum/skins/default/templates/tag_selector.html b/forum/skins/default/templates/tag_selector.html
index 5e3e2ad8..85b858d2 100644
--- a/forum/skins/default/templates/tag_selector.html
+++ b/forum/skins/default/templates/tag_selector.html
@@ -1,5 +1,6 @@
{% load i18n %}
{% load extra_tags %}
+{% comment %}todo - maybe disable navigation from ignored tags here when "hide" is on - with js?{%endcomment%}
<div id="tagSelector" class="boxC">
<h3 class="subtitle">{% trans "Interesting tags" %}</h3>
<div class="tags interesting marked-tags">
@@ -7,8 +8,8 @@
{% spaceless %}
<span class="deletable-tag" id="interesting-tag-{{tag_name}}">
<a rel="tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ title="{% blocktrans %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{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 %}"/>
@@ -24,8 +25,8 @@
{% spaceless %}
<span class="deletable-tag" id="ignored-tag-{{tag_name}}">
<a rel="tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ title="{% blocktrans %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{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 %}"/>
diff --git a/forum/skins/default/templates/tags.html b/forum/skins/default/templates/tags.html
index 50f90fb1..2bc01070 100644
--- a/forum/skins/default/templates/tags.html
+++ b/forum/skins/default/templates/tags.html
@@ -46,7 +46,8 @@
<ul class="tagsList tags">
{% for tag in tags.object_list %}
<li>
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
+ <a href="{% url questions %}?tags={{tag|urlencode}}"
+ title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">
{{ tag }}
</a>&nbsp;
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
diff --git a/forum/skins/default/templates/user_stats.html b/forum/skins/default/templates/user_stats.html
index 1f462581..482b1228 100644
--- a/forum/skins/default/templates/user_stats.html
+++ b/forum/skins/default/templates/user_stats.html
@@ -98,7 +98,7 @@
{% for tag in user_tags%}
<a rel="tag"
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 questions %}?tags={{tag|urlencode}}&author={{view_user.id}}&start_over=true">{{tag.name}}</a>
<span class="tag-number">&#215; {{ tag.user_tag_usage_count|intcomma }}</span><br/>
{% if forloop.counter|divisibleby:"10" %}
</td>
diff --git a/forum/skins/default/templates/users_questions.html b/forum/skins/default/templates/users_questions.html
index be6aaf7d..99a7f90c 100644
--- a/forum/skins/default/templates/users_questions.html
+++ b/forum/skins/default/templates/users_questions.html
@@ -31,7 +31,7 @@
{% convert2tagname_list question %}
{% for tag in question.tagnames %}
<!--todo - move trans below to blocktrans -->
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py
index 382d19f0..a10c473b 100755
--- a/forum/templatetags/extra_tags.py
+++ b/forum/templatetags/extra_tags.py
@@ -304,8 +304,12 @@ class ItemSeparatorNode(template.Node):
return self.content
class JoinItemListNode(template.Node):
- def __init__(self,separator=ItemSeparatorNode("''"), items=()):
+ def __init__(self,separator=ItemSeparatorNode("''"), last_separator=None, items=()):
self.separator = separator
+ if last_separator:
+ self.last_separator = last_separator
+ else:
+ self.last_separator = separator
self.items = items
def render(self,context):
out = []
@@ -314,16 +318,34 @@ class JoinItemListNode(template.Node):
bit = item.render(context)
if not empty_re.search(bit):
out.append(bit)
- return self.separator.render(context).join(out)
+ if len(out) == 1:
+ return out[0]
+ if len(out) > 1:
+ last = out.pop()
+ all_but_last = self.separator.render(context).join(out)
+ return self.last_separator.render(context).join((all_but_last,last))
+ else:
+ assert(len(out)==0)
+ return ''
@register.tag(name="joinitems")
def joinitems(parser,token):
try:
- tagname,junk,sep_token = token.split_contents()
- except ValueError:
- raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters")
+ tagname, junk, sep_token = token.split_contents()
+ last_sep_token = None
+ except:
+ try:
+ tagname, junk, sep_token, last_sep_token = token.split_contents()
+ except:
+ raise template.TemplateSyntaxError('incorrect usage of joinitems tag first param '
+ 'must be \'using\' second - separator and '
+ 'optional third - last item separator')
if junk == 'using':
sep_node = ItemSeparatorNode(sep_token)
+ if last_sep_token:
+ last_sep_node = ItemSeparatorNode(last_sep_token)
+ else:
+ last_sep_node = None
else:
raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters")
nodelist = []
@@ -333,7 +355,7 @@ def joinitems(parser,token):
if next.contents == 'endjoinitems':
break
- return JoinItemListNode(separator=sep_node,items=nodelist)
+ return JoinItemListNode(separator=sep_node,last_separator=last_sep_node,items=nodelist)
class BlockMediaUrlNode(template.Node):
def __init__(self,nodelist):
@@ -436,3 +458,50 @@ def question_counter_widget(question):
#returns a dictionary with keys like 'votes_bg', etc
return locals()
+class IsManyNode(template.Node):
+ def __init__(self, test_items, true_nodelist, false_nodelist):
+ self.true_nodelist = true_nodelist
+ self.false_nodelist = false_nodelist
+ self.test_items = test_items
+ def render(self, context):
+ maybe = False
+ for item in self.test_items:
+ is_good = item.resolve(context)
+ print item, is_good
+ if maybe == True and is_good:
+ print 'have many!'
+ return self.true_nodelist.render(context)
+ if is_good:
+ maybe = True
+ print 'have one item'
+ return self.false_nodelist.render(context)
+
+@register.tag(name='ifmany')
+def ifmany(parser,token):
+ """usage {% ifmany item1 item2 item3 ... itemN %} stuff {% endifmany %}
+ returns content included into the tag if more than one
+ item evaluates to Tru'ish value - that's the idea
+ {% else %} is not supported yet
+ """
+
+ bits = list(token.split_contents())
+ start_tag = bits.pop(0)
+
+ test_items = []
+ for bit in bits:
+ item = parser.compile_filter(bit)
+ test_items.append(item)
+
+ end_tag = 'end' + start_tag
+ else_tag = 'else'
+ true_nodelist = parser.parse((end_tag,else_tag,))
+ token = parser.next_token()
+ if token.contents == else_tag:
+ print 'have else clause'
+ false_nodelist = parser.parse((end_tag,))
+ token = parser.next_token()
+ else:
+ false_nodelist = template.NodeList()
+
+
+ return IsManyNode(test_items, true_nodelist, false_nodelist)
diff --git a/forum/utils/decorators.py b/forum/utils/decorators.py
index e4e7acb3..440e8312 100755
--- a/forum/utils/decorators.py
+++ b/forum/utils/decorators.py
@@ -22,4 +22,3 @@ def ajax_method(view_func):
json = simplejson.dumps(retval)
return HttpResponse(json,mimetype='application/json')
return wrap
-
diff --git a/forum/views/readers.py b/forum/views/readers.py
index 9e9662dd..01dfc035 100644
--- a/forum/views/readers.py
+++ b/forum/views/readers.py
@@ -90,18 +90,15 @@ def questions(request):#a view generating listing of questions, used by 'unanswe
if request.user.is_authenticated():
search_state.set_logged_in()
- print 'before: ', search_state
-
form = AdvancedSearchForm(request.GET)
if form.is_valid():
- print 'form is valid'
- search_state.update_from_user_input(form.cleaned_data)
+ search_state.update_from_user_input(form.cleaned_data, request.GET)
request.session['search_state'] = search_state
request.session.modified = True
- print 'after: ', search_state
-
- print 'going into the search'
+ #force reset for debugging
+ #search_state.reset()
+ #request.session.modified = True
#have this call implemented for sphinx, mysql and pgsql
(qs, meta_data) = Question.objects.run_advanced_search(
@@ -113,10 +110,6 @@ def questions(request):#a view generating listing of questions, used by 'unanswe
sort_method = search_state.sort
)
- print 'got out of the search'
-
- logging.debug('search state is %s' % search_state)
-
objects_list = Paginator(qs, search_state.page_size)
questions = objects_list.page(search_state.page)
@@ -128,17 +121,16 @@ def questions(request):#a view generating listing of questions, used by 'unanswe
#todo!!!!
#contributors = #User.objects.get_related_to_questions
- print 'rendering template!!!'
- print 'have %d' % objects_list.count
-
+ #todo: organize variables by type
return render_to_response('questions.html', {
'questions' : questions,
'author_name' : meta_data.get('author_name',None),
'tab_id' : search_state.sort,
'questions_count' : objects_list.count,
'tags' : related_tags,
+ 'query': search_state.query,
+ 'search_tags' : search_state.tags,
'tags_autocomplete' : tags_autocomplete,
- 'searchtag' : search_state.tags,
'is_unanswered' : False,#remove this from template
'interesting_tag_names': meta_data.get('interesting_tag_names',None),
'ignored_tag_names': meta_data.get('ignored_tag_names',None),
@@ -163,15 +155,16 @@ def search(request): #generates listing of questions matching a search query - i
are useless under the search bar
"""
if request.method == "GET":
- search_type == request.GET.get('t')
+ search_type = request.GET.get('t')
+ query = request.GET.get('query')
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
if search_type == 'tag':
- return HttpResponseRedirect(reverse('tags') + '?q=%s&page=%s' % (keywords.strip(), page))
- elif search_type == "user":
- return HttpResponseRedirect(reverse('users') + '?q=%s&page=%s' % (keywords.strip(), page))
+ return HttpResponseRedirect(reverse('tags') + '?q=%s&page=%s' % (query.strip(), page))
+ elif search_type == 'user':
+ return HttpResponseRedirect(reverse('users') + '?q=%s&page=%s' % (query.strip(), page))
else:
raise Http404
else:
@@ -205,6 +198,7 @@ def tags(request):#view showing a listing of available tags - plain list
tags = objects_list.page(objects_list.num_pages)
return render_to_response('tags.html', {
+ "active_tab": "tags",
"tags" : tags,
"stag" : stag,
"tab_id" : sortby,
diff --git a/forum/views/users.py b/forum/views/users.py
index 245a1f85..2356bf38 100755
--- a/forum/views/users.py
+++ b/forum/views/users.py
@@ -63,11 +63,12 @@ def users(request):
users = objects_list.page(objects_list.num_pages)
return render_to_response('users.html', {
- "users" : users,
- "suser" : suser,
- "keywords" : suser,
- "tab_id" : sortby,
- "context" : {
+ 'active_tab': 'users',
+ 'users' : users,
+ 'suser' : suser,
+ 'keywords' : suser,
+ 'tab_id' : sortby,
+ 'context' : {
'is_paginated' : is_paginated,
'pages': objects_list.num_pages,
'page': page,
diff --git a/forum/views/writers.py b/forum/views/writers.py
index b9b1aad5..57c8e043 100755
--- a/forum/views/writers.py
+++ b/forum/views/writers.py
@@ -132,9 +132,18 @@ def ask(request):#view used to ask a new question
return HttpResponseRedirect(reverse('user_signin_new_question'))
else:
form = AskForm()
+ if 'title' in request.GET:
+ raw_title = request.GET['title']
+ form.initial['title'] = strip_tags(strip_entities(raw_title))
+ else:
+ search_state = request.session.get('search_state',None)
+ if search_state:
+ query = search_state.query
+ form.initial['title'] = query
tags = _get_tags_cache_json()
return render_to_response('ask.html', {
+ 'active_tab': 'ask',
'form' : form,
'tags' : tags,
'email_validation_faq_url':reverse('faq') + '#validate',
@@ -318,7 +327,6 @@ def __generate_comments_json(obj, type, user):#non-view generates json data for
data = simplejson.dumps(json_comments)
return HttpResponse(data, mimetype="application/json")
-
def question_comments(request, id):#ajax handler for loading comments to question
question = get_object_or_404(Question, id=id)
user = request.user
diff --git a/settings.py b/settings.py
index 4d799a13..b80eb4f2 100644
--- a/settings.py
+++ b/settings.py
@@ -75,6 +75,7 @@ INSTALLED_APPS = (
'django_authopenid',
'debug_toolbar' ,
#'stackexchange', #se loader
+ 'south',
)
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)