diff options
author | NoahY <yuttadhammo@yahoo.com> | 2011-07-28 14:58:52 +0530 |
---|---|---|
committer | NoahY <yuttadhammo@yahoo.com> | 2011-07-28 14:58:52 +0530 |
commit | fa8827728ac51a1f0cfb7c126378ae0750599cb3 (patch) | |
tree | 0dfabea7f5e80b2052d61c0fe55f1476445ca0d3 | |
parent | 83db572a643d3f63dd17e8b529285a148788f2f1 (diff) | |
download | askbot-fa8827728ac51a1f0cfb7c126378ae0750599cb3.tar.gz askbot-fa8827728ac51a1f0cfb7c126378ae0750599cb3.tar.bz2 askbot-fa8827728ac51a1f0cfb7c126378ae0750599cb3.zip |
added print view button to questions
-rw-r--r-- | askbot/skins/default/media/images/print.png | bin | 0 -> 1391 bytes | |||
-rwxr-xr-x | askbot/skins/default/media/style/style.css | 16 | ||||
-rw-r--r-- | askbot/skins/default/templates/question.html | 37 | ||||
-rw-r--r-- | askbot/skins/default/templates/question_print.html | 256 | ||||
-rw-r--r-- | askbot/urls.py | 5 | ||||
-rw-r--r-- | askbot/views/readers.py | 79 |
6 files changed, 373 insertions, 20 deletions
diff --git a/askbot/skins/default/media/images/print.png b/askbot/skins/default/media/images/print.png Binary files differnew file mode 100644 index 00000000..37bf88af --- /dev/null +++ b/askbot/skins/default/media/images/print.png diff --git a/askbot/skins/default/media/style/style.css b/askbot/skins/default/media/style/style.css index 0306e45a..da03e913 100755 --- a/askbot/skins/default/media/style/style.css +++ b/askbot/skins/default/media/style/style.css @@ -884,6 +884,20 @@ a:hover.medal { margin-bottom: 10px; font-size: 100%; } +.question-title { + position:relative; +} +.print { + position:absolute; + width:24px; + height:24px; + top:12px; + right:6px; + background: url(../images/print.png); +} +.print:hover { + cursor: pointer; +} .question-status { margin-top: 10px; @@ -895,14 +909,12 @@ a:hover.medal { .question-status h3 { font-size: 125%; } - .question-body, .answer-body { min-height: 39px; line-height: 20px; overflow: auto; width: 660px; } - .question-body IMG, .answer-body IMG { max-width: 600px; } diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html index 168c31ce..208d4d69 100644 --- a/askbot/skins/default/templates/question.html +++ b/askbot/skins/default/templates/question.html @@ -8,10 +8,11 @@ {% block keywords %}{{question.tagname_meta_generator()}}{% endblock %} {% block forestyle %} <link rel="canonical" href="{{settings.APP_URL}}{{question.get_absolute_url()}}" /> - <link rel="stylesheet" type="text/css" href="{{"/js/wmd/wmd.css"|media}}" /> + <link rel="stylesheet" type="text/css" href="{{'/js/wmd/wmd.css'|media}}" /> {% endblock %} {% block content %} -<h1><a href="{{ question.get_absolute_url() }}">{{ question.get_question_title() }}</a></h1> +<div class="question-title"><h1><a href="{{ question.get_absolute_url() }}">{{ question.get_question_title() }}</a></h1><div class="print pointer" onclick="window.open('{% url questions %}{{ question.id }}/print/');" title="{% trans %}print page{% endtrans %}"></div></div> + <table style="width:100%;" id="question-table" {% if question.deleted %}class="deleted"{%endif%}> <tr> <td style="width:30px;vertical-align:top"> @@ -19,9 +20,9 @@ {% if question_vote %} <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote" {% if question_vote.is_upvote() %} - src="{{"/images/vote-arrow-up-on.png"|media}}" + src="{{'/images/vote-arrow-up-on.png'|media}}" {% else %} - src="{{"/images/vote-arrow-up.png"|media}}" + src="{{'/images/vote-arrow-up.png'|media}}" {% endif %} alt="{% trans %}i like this post (click again to cancel){% endtrans %}" title="{% trans %}i like this post (click again to cancel){% endtrans %}" /> @@ -31,35 +32,35 @@ </div> <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote" {% if question_vote.is_downvote() %} - src="{{"/images/vote-arrow-down-on.png"|media}}" + src="{{'/images/vote-arrow-down-on.png'|media}}" {% else %} - src="{{"/images/vote-arrow-down.png"|media}}" + src="{{'/images/vote-arrow-down.png'|media}}" {% endif %} alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}" title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" /> {% else %} <img id="question-img-upvote-{{ question.id }}" class="question-img-upvote" alt="{% trans %}i like this post (click again to cancel){% endtrans %}" - src="{{"/images/vote-arrow-up.png"|media}}" + src="{{'/images/vote-arrow-up.png'|media}}" title="{% trans %}i like this post (click again to cancel){% endtrans %}" /> <div id="question-vote-number-{{ question.id }}" class="vote-number" title="{% trans %}current number of votes{% endtrans %}"> {{ question.score }} </div> <img id="question-img-downvote-{{ question.id }}" class="question-img-downvote" - src="{{"/images/vote-arrow-down.png"|media}}" + src="{{'/images/vote-arrow-down.png'|media}}" alt="{% trans %}i dont like this post (click again to cancel){% endtrans %}" title="{% trans %}i dont like this post (click again to cancel){% endtrans %}" /> {% endif %} {% if favorited %} - <img class="question-img-favorite" src="{{"/images/vote-favorite-on.png"|media}}" + <img class="question-img-favorite" src="{{'/images/vote-favorite-on.png'|media}}" alt="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}" title="{% trans %}mark this question as favorite (click again to cancel){% endtrans %}" /> <div id="favorite-number" class="favorite-number my-favorite-number"> {{ question.favourite_count }} </div> {% else %} - <img class="question-img-favorite" src="{{"/images/vote-favorite-off.png"|media}}" + <img class="question-img-favorite" src="{{'/images/vote-favorite-off.png'|media}}" alt="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}" title="{% trans %}remove favorite mark from this question (click again to restore mark){% endtrans %}" /> <div id="favorite-number" class="favorite-number"> @@ -191,9 +192,9 @@ <div class="vote-buttons"> <img id="answer-img-upvote-{{ answer.id }}" class="answer-img-upvote" {% if user_answer_votes[answer.id] == 1 %} - src="{{"/images/vote-arrow-up-on.png"|media}}" + src="{{'/images/vote-arrow-up-on.png'|media}}" {% else %} - src="{{"/images/vote-arrow-up.png"|media}}" + src="{{'/images/vote-arrow-up.png'|media}}" {% endif %} alt="{% trans %}i like this answer (click again to cancel){% endtrans %}" title="{% trans %}i like this answer (click again to cancel){% endtrans %}"/> @@ -202,18 +203,18 @@ </div> <img id="answer-img-downvote-{{ answer.id }}" class="answer-img-downvote" {% if user_answer_votes[answer.id] == -1 %} - src="{{"/images/vote-arrow-down-on.png"|media}}" + src="{{'/images/vote-arrow-down-on.png'|media}}" {% else %} - src="{{"/images/vote-arrow-down.png"|media}}" + src="{{'/images/vote-arrow-down.png'|media}}" {% endif %} alt="{% trans %}i dont like this answer (click again to cancel){% endtrans %}" title="{% trans %}i dont like this answer (click again to cancel){% endtrans %}" /> {% if request.user == question.author %} <img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept" {% if answer.accepted %} - src="{{"/images/vote-accepted-on.png"|media}}" + src="{{'/images/vote-accepted-on.png'|media}}" {% else %} - src="{{"/images/vote-accepted.png"|media}}" + src="{{'/images/vote-accepted.png'|media}}" {% endif %} alt="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}" title="{% trans %}mark this answer as favorite (click again to undo){% endtrans %}" /> @@ -221,9 +222,9 @@ {% if answer.accepted %} <img id="answer-img-accept-{{ answer.id }}" class="answer-img-accept" {% if answer.accepted %} - src="{{"/images/vote-accepted-on.png"|media}}" + src="{{'/images/vote-accepted-on.png'|media}}" {% else %} - src="{{"/images/vote-accepted.png"|media}}" + src="{{'/images/vote-accepted.png'|media}}" {% endif %} alt="{% trans question_author=question.author.username %}{{question_author}} has selected this answer as correct{% endtrans %}" title="{% trans questsion_author=question.author.username%}{{question_author}} has selected this answer as correct{% endtrans %}" diff --git a/askbot/skins/default/templates/question_print.html b/askbot/skins/default/templates/question_print.html new file mode 100644 index 00000000..b59a0f13 --- /dev/null +++ b/askbot/skins/default/templates/question_print.html @@ -0,0 +1,256 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<!-- question_print.html --> +<html xmlns="http://www.w3.org/1999/xhtml"> + {% spaceless %} + <head> + <title>{% block title %}{% spaceless %}{{ question.get_question_title() }}{% endspaceless %}{% endblock %}</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + {% block meta_description %} + <meta name="description" content="{{question.summary|striptags|escape}}" /> + {% endblock %} + <meta name="keywords" content="{{question.tagname_meta_generator()}},{{settings.APP_KEYWORDS|escape}}" /> + <link href="{{'/style/style.css'|media }}" rel="stylesheet" type="text/css" /> + {{ skin.get_extra_css_link() }} + {% if settings.USE_CUSTOM_CSS %} + <link + href="{% url "custom_css" %}?v={{settings.MEDIA_RESOURCE_REVISION}}" + rel="stylesheet" + type="text/css" + /> + {% endif %} + {% block forestyle %} + <link rel="canonical" href="{{settings.APP_URL}}{{question.get_absolute_url()}}" /> + <link rel="stylesheet" type="text/css" href="{{'/js/wmd/wmd.css'|media}}" /> + {% endblock %} + {% if settings.USE_CUSTOM_HTML_HEAD %} + {{ settings.CUSTOM_HTML_HEAD }} + {% endif %} + <script type="text/javascript"> + var askbot = {}; + askbot['data'] = {}; + askbot['urls'] = {}; + askbot['settings'] = {}; + askbot['messages'] = {}; + </script> + {% block forejs %} + {% endblock %} + {# avoid adding javascript here so that pages load faster #} + </head> + {% endspaceless %} + <body onload="window.print()" class="question-page"> + {% import "macros.html" as macros %} + {% block content %} + <h1><a href="{{ question.get_absolute_url() }}">{{ question.get_question_title() }}</a></h1> + <table style="width:100%;" id="question-table" {% if question.deleted %}class="deleted"{%endif%}> + <tr> + <td style="width:30px;vertical-align:top"> + <div class="vote-buttons"> + <div id="question-vote-number-{{ question.id }}" class="vote-number" + title="{% trans %}current number of votes{% endtrans %}"> + {{ question.score }} + </div> + </div> + </td> + <td> + <div class="question-body-print"> + {{question.html}} + </div> + <ul id="question-tags" class="post-tags tags"> + {% for tag in question.get_tag_names() %} + {{ macros.tag_widget( + tag, + css_class = 'post-tag', + html_tag = 'li' + ) + }} + {% endfor %} + </ul> + <div class="post-update-info-container"> + {{ + macros.post_contributor_info( + question, + "original_author", + question.wiki, + settings.MIN_REP_TO_EDIT_WIKI + ) + }} + {{ + macros.post_contributor_info( + question, + "last_updater", + question.wiki, + settings.MIN_REP_TO_EDIT_WIKI, + ) + }} + </div> + <div class="comments"> + {% set comments = question.get_comments(visitor = user)[:comment_order_number] %} + {% if comments|count > 0 %} + {% for comment in comments %} + <div class="comment"> + <div class="comment-body"> + {{comment.html}} – + <a + class="author" + href="{{comment.user.get_profile_url()}}" + >{{comment.user.username}}</a> + <span class="age"> ({{comment.added_at|diff_date}})</span> + </div> + </div> + {% endfor %} + {% endif %} + </div> + <!--/div--> + </td> + </tr> + </table> + {% if question.closed %} + <div class="question-status" style="margin-bottom:15px"> + <h3>{% trans close_reason=question.get_close_reason_display() %}The question has been closed for the following reason "{{ close_reason }}" by{% endtrans %} + <a href="{{ question.closed_by.get_profile_url() }}">{{ question.closed_by.username }}</a> + {% trans closed_at=question.closed_at %}close date {{closed_at}}{% endtrans %}</h3> + </div> + {% endif %} + {% if answers %} + <div class="tabBar"> + <h2 id="sort-top"> + {% trans counter=answers|length %} + {{counter}} Answer: + {% pluralize %} + {{counter}} Answers: + {% endtrans %} + </h2> + </div> + {% for answer in answers %} + <a name="{{ answer.id }}"></a> + <div id="answer-container-{{ answer.id }}" class="answer {% if answer.accepted %}accepted-answer{% endif %} {% if answer.author_id==question.author_id %} answered-by-owner{% endif %} {% if answer.deleted %}deleted{% endif %}"> + <table style="width:100%;" class="answer-table"> + <tr> + <td style="width:30px;vertical-align:top"> + <div class="vote-buttons"> + <div id="answer-vote-number-{{ answer.id }}" class="vote-number" title="{% trans %}current number of votes{% endtrans %}"> + {{ answer.score }} + </div> + </div> + </td> + <td> + <div class="item-right"> + <div class="answer-body-print"> + {{ answer.html }} + </div> + <div class="post-update-info-container"> + {{ + macros.post_contributor_info( + answer, + "original_author", + answer.wiki, + settings.MIN_REP_TO_EDIT_WIKI + ) + }} + {{ + macros.post_contributor_info( + answer, + "last_updater", + answer.wiki, + settings.MIN_REP_TO_EDIT_WIKI + ) + }} + </div> + <div class="comments"> + {% set comments = answer.get_comments(visitor = user)[:comment_order_number] %} + {% if comments|count > 0 %} + {% for comment in comments %} + <div class="comment"> + <div class="comment-body"> + {{comment.html}} – + <a + class="author" + href="{{comment.user.get_profile_url()}}" + >{{comment.user.username}}</a> + <span class="age"> ({{comment.added_at|diff_date}})</span> + </div> + </div> + {% endfor %} + {% endif %} + </div> + </div> + </td> + </tr> + </table> + </div> + {% endfor %} + {% endif %} + {% endblock %} + {% include "blocks/bottom_scripts.html" %} + {% block endjs %} + {% if not question.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 + '{% trans %}question/{% endtrans %}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #} + askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}'; + askbot['urls']['vote_url_template'] = scriptUrl + '{% trans %}questions/{% endtrans %}{{ "{{QuestionID}}/" }}{% trans %}vote/{% endtrans %}'; + askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}'; + askbot['urls']['upvote_comment'] = '{% url upvote_comment %}'; + askbot['messages']['addComment'] = '{% trans %}add comment{% endtrans %}'; + {% if settings.SAVE_COMMENT_ON_ENTER %} + askbot['settings']['saveCommentOnEnter'] = true; + {% else %} + askbot['settings']['saveCommentOnEnter'] = false; + {% endif %} + </script> + <script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script> + <script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script> + {% endif %} + <script type='text/javascript' src='{{"/js/jquery.validate.min.js"|media}}'></script> + <script type='text/javascript' src='{{"/js/post.js"|media}}'></script> + <script type="text/javascript"> + // define reputation needs for comments + var repNeededForComments = 50; + $().ready(function(){ + $("#nav_questions").attr('className',"on"); + var answer_sort_tab = "{{ tab_id }}"; + $("#" + answer_sort_tab).attr('className',"on"); + + Vote.init({{ question.id }}, '{{ question.title|slugify }}', '{{ question.author.id }}','{{ request.user.id }}'); + + {% if not question.closed and request.user.is_authenticated %}initEditor();{% endif %} + + lanai.highlightSyntax(); + $('#btLogin').bind('click', function(){window.location.href='{{ settings.LOGIN_URL }}'; } ) + if (window.location.hash === 'fmanswer'){ + $('#fmanswer textarea').focus(); + } + }); + + function initEditor(){ + $('#editor').TextAreaResizer(); + //highlight code synctax when editor has new text + $("#editor").typeWatch({highlight: false, wait: 3000, + captureLength: 5, callback: lanai.highlightSyntax}); + + var display = true; + var txt = "[{% trans %}hide preview{% endtrans %}]"; + $('#pre-collapse').text(txt); + $('#pre-collapse').bind('click', function(){ + txt = display ? "[{% trans %}show preview{% endtrans %}]" : "[{% trans %}hide preview{% endtrans %}]"; + display = !display; + $('#previewer').toggle(); + $('#pre-collapse').text(txt); + }); + setupFormValidation($("#fmanswer"), CPValidator.getQuestionFormRules(), CPValidator.getQuestionFormMessages()); + } + </script> + {% include "blocks/editor_data.html" %} + {% endblock %} + </body> +</html> diff --git a/askbot/urls.py b/askbot/urls.py index c6d79492..8dff3ae1 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -55,6 +55,11 @@ urlpatterns = patterns('', kwargs = {'object_name': 'Answer'}, name='answer_revisions' ), + url( + r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('print/')), + views.readers.question_print, + name='question_print' + ), url(#this url works both normally and through ajax r'^%s$' % _('questions/'), views.readers.questions, diff --git a/askbot/views/readers.py b/askbot/views/readers.py index d512cf83..b896bfa6 100644 --- a/askbot/views/readers.py +++ b/askbot/views/readers.py @@ -600,6 +600,85 @@ def question(request, id):#refactor - long subroutine. display question body, an } return render_into_skin('question.html', data, request) +@csrf.csrf_protect +def question_print(request, id):#refactor - long subroutine. print question body, answers and comments + """view that displays body of the question and + all answers to it in print format + """ + #todo: fix inheritance of sort method from questions + default_sort_method = request.session.get('questions_sort_method', 'votes') + form = ShowQuestionForm(request.GET, default_sort_method) + form.full_clean()#always valid + show_answer = form.cleaned_data['show_answer'] + show_comment = form.cleaned_data['show_comment'] + show_page = form.cleaned_data['show_page'] + is_permalink = form.cleaned_data['is_permalink'] + answer_sort_method = form.cleaned_data['answer_sort_method'] + + #load question and maybe refuse showing deleted question + try: + question = get_object_or_404(models.Question, id=id) + question.assert_is_visible_to(request.user) + except exceptions.QuestionHidden, error: + request.user.message_set.create(message = unicode(error)) + return HttpResponseRedirect(reverse('index')) + + logging.debug('answer_sort_method=' + unicode(answer_sort_method)) + #load answers + answers = question.get_answers(user = request.user) + answers = answers.select_related(depth=1) + + user_answer_votes = {} + for answer in answers: + vote = answer.get_user_vote(request.user) + if vote is not None and not user_answer_votes.has_key(answer.id): + vote_value = -1 + if vote.is_upvote(): + vote_value = 1 + user_answer_votes[answer.id] = vote_value + + view_dic = {"latest":"-added_at", "oldest":"added_at", "votes":"-score" } + orderby = view_dic[answer_sort_method] + if answers is not None: + answers = answers.order_by("-accepted", orderby) + + filtered_answers = [] + for answer in answers: + if answer.deleted == True: + if answer.author_id == request.user.id: + filtered_answers.append(answer) + else: + filtered_answers.append(answer) + + #resolve page number and comment number for permalinks + comment_order_number = None + + favorited = question.has_favorite_by_user(request.user) + if request.user.is_authenticated(): + question_vote = question.votes.select_related().filter(user=request.user) + else: + question_vote = None #is this correct? + if question_vote is not None and question_vote.count() > 0: + question_vote = question_vote[0] + + data = { + 'page_class': 'question-page', + 'active_tab': 'questions', + 'question' : question, + 'question_vote' : question_vote, + 'question_comment_count':question.comments.count(), + 'answer' : AnswerForm(question,request.user), + 'answers' : filtered_answers, + 'user_answer_votes': user_answer_votes, + 'tags' : question.tags.all(), + 'tab_id' : answer_sort_method, + 'favorited' : favorited, + 'similar_questions' : question.get_similar_questions(), + 'language_code': translation.get_language(), + 'comment_order_number': comment_order_number + } + return render_into_skin('question_print.html', data, request) + def revisions(request, id, object_name=None): assert(object_name in ('Question', 'Answer')) post = get_object_or_404(models.get_model(object_name), id=id) |