mirror of
https://github.com/djohnlewis/stackdump
synced 2024-12-04 23:17:37 +00:00
Added answer permalinks and ability to rewrite internal answer permalinks.
This includes a new field in the Solr schema, so a re-index is required after this changeset. Fixes #1
This commit is contained in:
parent
4e924f6bd8
commit
f067353f62
@ -121,6 +121,8 @@
|
||||
<field name="title" type="text_general" indexed="true" stored="false" required="true"/>
|
||||
<field name="question-json" type="string" indexed="false" stored="true" required="true"/>
|
||||
<field name="answers-json" type="string" indexed="false" stored="true" multiValued="true"/>
|
||||
<!-- used for reverse question ID lookup from an answer -->
|
||||
<field name="answerId" type="tint" indexed="true" stored="false" multiValued="true"/>
|
||||
<field name="ownerUserId" type="tint" indexed="true" stored="true" required="true"/>
|
||||
<field name="lastEditorUserId" type="tint" indexed="false" stored="false"/>
|
||||
<field name="lastActivityDate" type="tdate" indexed="true" stored="false"/>
|
||||
|
@ -207,10 +207,14 @@ h3, h4, h5, h6 {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.post-tags {
|
||||
.post-tags, .post-actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.post-actions a {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.question h1 {
|
||||
border-bottom: 1px solid #CCCCCC;
|
||||
padding-bottom: 7px;
|
||||
|
@ -33,6 +33,7 @@ from stackdump import settings
|
||||
BOTTLE_ROOT = os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
MEDIA_ROOT = os.path.abspath(BOTTLE_ROOT + '/../../media')
|
||||
SE_QUESTION_ID_RE = re.compile(r'/questions/(?P<id>\d+)/')
|
||||
SE_ANSWER_ID_RE = re.compile(r'/a/(?P<id>\d+)/')
|
||||
|
||||
# THREAD LOCAL VARIABLES
|
||||
thread_locals = threading.local()
|
||||
@ -371,10 +372,11 @@ def site_search(site_key):
|
||||
return render_template('site_results.html', context)
|
||||
|
||||
@get('/:site_key#[\w\.]+#/:question_id#\d+#')
|
||||
@get('/:site_key#[\w\.]+#/:question_id#\d+#/:answer_id#\d+#')
|
||||
@uses_templates
|
||||
@uses_solr
|
||||
@uses_db
|
||||
def view_question(site_key, question_id):
|
||||
def view_question(site_key, question_id, answer_id=None):
|
||||
context = { }
|
||||
|
||||
try:
|
||||
@ -397,6 +399,8 @@ def view_question(site_key, question_id):
|
||||
rewrite_result(result)
|
||||
sort_answers(result)
|
||||
context['result'] = result
|
||||
|
||||
context['answer_id'] = answer_id
|
||||
|
||||
return render_template('question.html', context)
|
||||
|
||||
@ -408,6 +412,28 @@ def view_question_redirect(site_key, question_id):
|
||||
'''
|
||||
redirect('%s%s/%s' % (settings.APP_URL_ROOT, site_key, question_id))
|
||||
|
||||
@get('/:site_key#[\w\.]+#/a/:answer_id#\d+#')
|
||||
@uses_templates
|
||||
@uses_solr
|
||||
@uses_db
|
||||
def view_answer(site_key, answer_id):
|
||||
context = { }
|
||||
|
||||
try:
|
||||
context['site'] = Site.selectBy(key=site_key).getOne()
|
||||
except SQLObjectNotFound:
|
||||
raise HTTPError(code=404, output='No site exists with the key %s.' % site_key)
|
||||
|
||||
# get the question referenced by this answer id
|
||||
query = 'answerId:%s siteKey:%s' % (answer_id, site_key)
|
||||
results = solr_conn().search(query)
|
||||
if len(results) == 0:
|
||||
raise HTTPError(code=404, output='No answer exists with the ID %s for the site, %s.' % (answer_id, context['site'].name))
|
||||
|
||||
question_id = results.docs[0]['id']
|
||||
|
||||
redirect('%s%s/%s/%s' % (settings.APP_URL_ROOT, site_key, question_id, answer_id))
|
||||
|
||||
# END WEB REQUEST METHODS
|
||||
|
||||
|
||||
@ -797,6 +823,14 @@ def _rewrite_html(html, app_url_root, sites_by_urls):
|
||||
t.set('href', url)
|
||||
t.set('class', t.get('class', '') + ' internal-link')
|
||||
internal_link = True
|
||||
|
||||
answer_id = SE_ANSWER_ID_RE.search(url)
|
||||
if answer_id:
|
||||
answer_id = answer_id.groupdict()['id']
|
||||
url = '%s%s/a/%s' % (app_url_root, site.key, answer_id)
|
||||
t.set('href', url)
|
||||
t.set('class', t.get('class', '') + ' internal-link')
|
||||
internal_link = True
|
||||
|
||||
if not internal_link:
|
||||
t.set('class', t.get('class', '') + ' external-link')
|
||||
|
@ -462,6 +462,7 @@ class PostContentHandler(xml.sax.ContentHandler):
|
||||
doc['votes'] = q['score']
|
||||
doc['viewCount'] = q['viewCount']
|
||||
doc['title'] = q['title']
|
||||
doc['answerId'] = [ str(a['id']) for a in q['answers'] ]
|
||||
doc['ownerUserId'] = q['ownerUserId']
|
||||
if 'lastEditorUserId' in q:
|
||||
doc['lastEditorUserId'] = q['lastEditorUserId']
|
||||
|
@ -99,7 +99,8 @@ MathJax.Hub.Config({
|
||||
<h1 class="answers">{{ r.answers|length }} answer{% if r.answers|length != 1 %}s{% endif %}</h1>
|
||||
<ul class="answers">
|
||||
{% for a in r.answers %}
|
||||
<li>
|
||||
<li id="answer-{{ a.id }}">
|
||||
<a name="answer-{{ a.id }}"></a>
|
||||
<div class="post-stats-vertical">
|
||||
<div class="post-stat">
|
||||
<p class="post-stat-value {% if a.score < 0 %}post-stat-value-poor{% endif %}">
|
||||
@ -130,6 +131,9 @@ MathJax.Hub.Config({
|
||||
{{ macros.user_card(a.lastEditorUser) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="post-actions">
|
||||
<a href="{{ SETTINGS.APP_URL_ROOT }}{{ r.site.key }}/a/{{ a.id }}">permalink</a>
|
||||
</div>
|
||||
<div class="post-tags">
|
||||
{% for t in a.tags %}
|
||||
<span class="label">{{ t }}</span>
|
||||
@ -162,5 +166,15 @@ MathJax.Hub.Config({
|
||||
$('pre code').each(function(index, value) { $(value).addClass('prettyprint');});
|
||||
prettyPrint();
|
||||
});
|
||||
|
||||
{% if answer_id %}
|
||||
// scroll to a particular answer when answer ID given in URL
|
||||
$(document).ready(function() {
|
||||
$('html, body').animate({
|
||||
// minus 20 to add a bit of padding at the top of the window
|
||||
scrollTop: $('#answer-{{ answer_id }}').offset().top - 20
|
||||
}, 1000);
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
Loading…
Reference in New Issue
Block a user