Commit 2eabe867 by Rocky Duan

Merge branch 'feature/bk_forum_int' of github.com:MITx/mitx into feature/bk_forum_int

parents 22657130 08e892ce
...@@ -263,7 +263,7 @@ def add_user_to_default_group(user, group): ...@@ -263,7 +263,7 @@ def add_user_to_default_group(user, group):
utg.users.add(User.objects.get(username=user)) utg.users.add(User.objects.get(username=user))
utg.save() utg.save()
@receiver(post_save, sender=User) # @receiver(post_save, sender=User)
def update_user_information(sender, instance, created, **kwargs): def update_user_information(sender, instance, created, **kwargs):
try: try:
cc_user = cc.User.from_django_user(instance) cc_user = cc.User.from_django_user(instance)
...@@ -274,7 +274,7 @@ def update_user_information(sender, instance, created, **kwargs): ...@@ -274,7 +274,7 @@ def update_user_information(sender, instance, created, **kwargs):
log.error("update user info to discussion failed for user with id: " + str(instance.id)) log.error("update user info to discussion failed for user with id: " + str(instance.id))
########################## REPLICATION SIGNALS ################################# ########################## REPLICATION SIGNALS #################################
@receiver(post_save, sender=User) # @receiver(post_save, sender=User)
def replicate_user_save(sender, **kwargs): def replicate_user_save(sender, **kwargs):
user_obj = kwargs['instance'] user_obj = kwargs['instance']
if not should_replicate(user_obj): if not should_replicate(user_obj):
...@@ -282,7 +282,7 @@ def replicate_user_save(sender, **kwargs): ...@@ -282,7 +282,7 @@ def replicate_user_save(sender, **kwargs):
for course_db_name in db_names_to_replicate_to(user_obj.id): for course_db_name in db_names_to_replicate_to(user_obj.id):
replicate_user(user_obj, course_db_name) replicate_user(user_obj, course_db_name)
@receiver(post_save, sender=CourseEnrollment) # @receiver(post_save, sender=CourseEnrollment)
def replicate_enrollment_save(sender, **kwargs): def replicate_enrollment_save(sender, **kwargs):
"""This is called when a Student enrolls in a course. It has to do the """This is called when a Student enrolls in a course. It has to do the
following: following:
...@@ -308,12 +308,12 @@ def replicate_enrollment_save(sender, **kwargs): ...@@ -308,12 +308,12 @@ def replicate_enrollment_save(sender, **kwargs):
user_profile = UserProfile.objects.get(user_id=enrollment_obj.user_id) user_profile = UserProfile.objects.get(user_id=enrollment_obj.user_id)
replicate_model(UserProfile.save, user_profile, enrollment_obj.user_id) replicate_model(UserProfile.save, user_profile, enrollment_obj.user_id)
@receiver(post_delete, sender=CourseEnrollment) # @receiver(post_delete, sender=CourseEnrollment)
def replicate_enrollment_delete(sender, **kwargs): def replicate_enrollment_delete(sender, **kwargs):
enrollment_obj = kwargs['instance'] enrollment_obj = kwargs['instance']
return replicate_model(CourseEnrollment.delete, enrollment_obj, enrollment_obj.user_id) return replicate_model(CourseEnrollment.delete, enrollment_obj, enrollment_obj.user_id)
@receiver(post_save, sender=UserProfile) # @receiver(post_save, sender=UserProfile)
def replicate_userprofile_save(sender, **kwargs): def replicate_userprofile_save(sender, **kwargs):
"""We just updated the UserProfile (say an update to the name), so push that """We just updated the UserProfile (say an update to the name), so push that
change to all Course DBs that we're enrolled in.""" change to all Course DBs that we're enrolled in."""
......
...@@ -8,6 +8,7 @@ import logging ...@@ -8,6 +8,7 @@ import logging
from datetime import datetime from datetime import datetime
from django.test import TestCase from django.test import TestCase
from nose.plugins.skip import SkipTest
from .models import User, UserProfile, CourseEnrollment, replicate_user, USER_FIELDS_TO_COPY from .models import User, UserProfile, CourseEnrollment, replicate_user, USER_FIELDS_TO_COPY
...@@ -22,6 +23,7 @@ class ReplicationTest(TestCase): ...@@ -22,6 +23,7 @@ class ReplicationTest(TestCase):
def test_user_replication(self): def test_user_replication(self):
"""Test basic user replication.""" """Test basic user replication."""
raise SkipTest()
portal_user = User.objects.create_user('rusty', 'rusty@edx.org', 'fakepass') portal_user = User.objects.create_user('rusty', 'rusty@edx.org', 'fakepass')
portal_user.first_name='Rusty' portal_user.first_name='Rusty'
portal_user.last_name='Skids' portal_user.last_name='Skids'
...@@ -80,6 +82,7 @@ class ReplicationTest(TestCase): ...@@ -80,6 +82,7 @@ class ReplicationTest(TestCase):
def test_enrollment_for_existing_user_info(self): def test_enrollment_for_existing_user_info(self):
"""Test the effect of Enrolling in a class if you've already got user """Test the effect of Enrolling in a class if you've already got user
data to be copied over.""" data to be copied over."""
raise SkipTest()
# Create our User # Create our User
portal_user = User.objects.create_user('jack', 'jack@edx.org', 'fakepass') portal_user = User.objects.create_user('jack', 'jack@edx.org', 'fakepass')
portal_user.first_name = "Jack" portal_user.first_name = "Jack"
...@@ -143,6 +146,8 @@ class ReplicationTest(TestCase): ...@@ -143,6 +146,8 @@ class ReplicationTest(TestCase):
def test_enrollment_for_user_info_after_enrollment(self): def test_enrollment_for_user_info_after_enrollment(self):
"""Test the effect of modifying User data after you've enrolled.""" """Test the effect of modifying User data after you've enrolled."""
raise SkipTest()
# Create our User # Create our User
portal_user = User.objects.create_user('patty', 'patty@edx.org', 'fakepass') portal_user = User.objects.create_user('patty', 'patty@edx.org', 'fakepass')
portal_user.first_name = "Patty" portal_user.first_name = "Patty"
......
...@@ -80,8 +80,8 @@ def course_wiki_redirect(request, course_id): ...@@ -80,8 +80,8 @@ def course_wiki_redirect(request, course_id):
urlpath = URLPath.create_article( urlpath = URLPath.create_article(
root, root,
course_slug, course_slug,
title=course.title, title=course.number,
content="This is the wiki for " + course.title + ".", content="{0}\n===\nThis is the wiki for **{1}**'s _{2}_.".format(course.number, course.org, course.title),
user_message="Course page automatically created.", user_message="Course page automatically created.",
user=None, user=None,
ip_address=None, ip_address=None,
......
...@@ -155,8 +155,18 @@ def progress_summary(student, course, grader, student_module_cache): ...@@ -155,8 +155,18 @@ def progress_summary(student, course, grader, student_module_cache):
chapters = [] chapters = []
# Don't include chapters that aren't displayable (e.g. due to error) # Don't include chapters that aren't displayable (e.g. due to error)
for c in course.get_display_items(): for c in course.get_display_items():
# Skip if the chapter is hidden
hidden = c.metadata.get('hide_from_toc','false')
if hidden.lower() == 'true':
continue
sections = [] sections = []
for s in c.get_display_items(): for s in c.get_display_items():
# Skip if the section is hidden
hidden = s.metadata.get('hide_from_toc','false')
if hidden.lower() == 'true':
continue
# Same for sections # Same for sections
graded = s.metadata.get('graded', False) graded = s.metadata.get('graded', False)
scores = [] scores = []
......
"""
This must be run only after seed_permissions_roles.py!
Creates default roles for all users currently in the database. Just runs through
Enrollments.
"""
from django.core.management.base import BaseCommand, CommandError
from student.models import CourseEnrollment
from django_comment_client.permissions import assign_default_role
class Command(BaseCommand):
args = 'course_id'
help = 'Seed default permisssions and roles'
def handle(self, *args, **options):
if len(args) != 0:
raise CommandError("This Command takes no arguments")
print "Updated roles for ",
for i, enrollment in enumerate(CourseEnrollment.objects.all(), start=1):
assign_default_role(None, enrollment)
if i % 1000 == 0:
print "{0}...".format(i),
print
\ No newline at end of file
...@@ -11,9 +11,9 @@ from util.cache import cache ...@@ -11,9 +11,9 @@ from util.cache import cache
@receiver(post_save, sender=CourseEnrollment) @receiver(post_save, sender=CourseEnrollment)
def assign_default_role(sender, instance, **kwargs): def assign_default_role(sender, instance, **kwargs):
if instance.user.is_staff: if instance.user.is_staff:
role = Role.objects.get(course_id=instance.course_id, name="Moderator") role = Role.objects.get_or_create(course_id=instance.course_id, name="Moderator")[0]
else: else:
role = Role.objects.get(course_id=instance.course_id, name="Student") role = Role.objects.get_or_create(course_id=instance.course_id, name="Student")[0]
logging.info("assign_default_role: adding %s as %s" % (instance.user, role)) logging.info("assign_default_role: adding %s as %s" % (instance.user, role))
instance.user.roles.add(role) instance.user.roles.add(role)
......
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils import unittest from django.test import TestCase
from student.models import CourseEnrollment, \ from student.models import CourseEnrollment, \
replicate_enrollment_save, \ replicate_enrollment_save, \
replicate_enrollment_delete, \ replicate_enrollment_delete, \
...@@ -13,120 +13,11 @@ import random ...@@ -13,120 +13,11 @@ import random
from .permissions import has_permission from .permissions import has_permission
from .models import Role, Permission from .models import Role, Permission
# code adapted from https://github.com/justquick/django-activity-stream/issues/88 class PermissionsTestCase(TestCase):
class NoSignalTestCase(unittest.TestCase):
def _receiver_in_lookup_keys(self, receiver, lookup_keys):
"""
Evaluate if the receiver is in the provided lookup_keys; instantly terminates when found.
"""
for key in lookup_keys:
if (receiver[0][0] == key[0] or key[0] is None) and receiver[0][1] == key[1]:
return True
return False
def _find_allowed_receivers(self, receivers, lookup_keys):
"""
Searches the receivers, keeping any that have a lookup_key in the lookup_keys list
"""
kept_receivers = []
for receiver in receivers:
if self._receiver_in_lookup_keys(receiver, lookup_keys):
kept_receivers.append(receiver)
return kept_receivers
def _create_lookup_keys(self, sender_receivers_tuple_list):
"""
Creates a signal lookup keys from the provided array of tuples.
"""
lookup_keys = []
for keep in sender_receivers_tuple_list:
receiver = keep[0]
sender = keep[1]
lookup_key = (_make_id(receiver) if receiver else receiver, _make_id(sender))
lookup_keys.append(lookup_key)
return lookup_keys
def _remove_disallowed_receivers(self, receivers, lookup_keys):
"""
Searches the receivers, discarding any that have a lookup_key in the lookup_keys list
"""
kept_receivers = []
for receiver in receivers:
if not self._receiver_in_lookup_keys(receiver, lookup_keys):
kept_receivers.append(receiver)
return kept_receivers
def setUp(self, sender_receivers_to_keep=None, sender_receivers_to_discard=None):
"""
Turns off signals from other apps
The `sender_receivers_to_keep` can be set to an array of tuples (reciever, sender,), preserving matching signals.
The `sender_receivers_to_discard` can be set to an array of tuples (reciever, sender,), discarding matching signals.
with both, you can set the `receiver` to None if you want to target all signals for a model
"""
self.m2m_changed_receivers = m2m_changed.receivers
self.pre_delete_receivers = pre_delete.receivers
self.pre_save_receivers = pre_save.receivers
self.post_delete_receivers = post_delete.receivers
self.post_save_receivers = post_save.receivers
new_m2m_changed_receivers = []
new_pre_delete_receivers = []
new_pre_save_receivers = []
new_post_delete_receivers = []
new_post_save_receivers = []
if sender_receivers_to_keep:
lookup_keys = self._create_lookup_keys(sender_receivers_to_keep)
new_m2m_changed_receivers = self._find_allowed_receivers(self.m2m_changed_receivers, lookup_keys)
new_pre_delete_receivers = self._find_allowed_receivers(self.pre_delete_receivers, lookup_keys)
new_pre_save_receivers = self._find_allowed_receivers(self.pre_save_receivers, lookup_keys)
new_post_delete_receivers = self._find_allowed_receivers(self.post_delete_receivers, lookup_keys)
new_post_save_receivers = self._find_allowed_receivers(self.post_save_receivers, lookup_keys)
if sender_receivers_to_discard:
lookup_keys = self._create_lookup_keys(sender_receivers_to_discard)
new_m2m_changed_receivers = self._remove_disallowed_receivers(new_m2m_changed_receivers or self.m2m_changed_receivers, lookup_keys)
new_pre_delete_receivers = self._remove_disallowed_receivers(new_pre_delete_receivers or self.pre_delete_receivers, lookup_keys)
new_pre_save_receivers = self._remove_disallowed_receivers(new_pre_save_receivers or self.pre_save_receivers, lookup_keys)
new_post_delete_receivers = self._remove_disallowed_receivers(new_post_delete_receivers or self.post_delete_receivers, lookup_keys)
new_post_save_receivers = self._remove_disallowed_receivers(new_post_save_receivers or self.post_save_receivers, lookup_keys)
m2m_changed.receivers = new_m2m_changed_receivers
pre_delete.receivers = new_pre_delete_receivers
pre_save.receivers = new_pre_save_receivers
post_delete.receivers = new_post_delete_receivers
post_save.receivers = new_post_save_receivers
super(NoSignalTestCase, self).setUp()
def tearDown(self):
"""
Restores the signals that were turned off.
"""
super(NoSignalTestCase, self).tearDown()
m2m_changed.receivers = self.m2m_changed_receivers
pre_delete.receivers = self.pre_delete_receivers
pre_save.receivers = self.pre_save_receivers
post_delete.receivers = self.post_delete_receivers
post_save.receivers = self.post_save_receivers
class PermissionsTestCase(NoSignalTestCase):
def random_str(self, length=15, chars=string.ascii_uppercase + string.digits): def random_str(self, length=15, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for x in range(length)) return ''.join(random.choice(chars) for x in range(length))
def setUp(self): def setUp(self):
sender_receivers_to_discard = [
(replicate_enrollment_save, CourseEnrollment),
(replicate_enrollment_delete, CourseEnrollment),
(update_user_information, User),
(replicate_user_save, User),
]
super(PermissionsTestCase, self).setUp(sender_receivers_to_discard=sender_receivers_to_discard)
self.course_id = "MITx/6.002x/2012_Fall" self.course_id = "MITx/6.002x/2012_Fall"
self.moderator_role = Role.objects.get_or_create(name="Moderator", course_id=self.course_id)[0] self.moderator_role = Role.objects.get_or_create(name="Moderator", course_id=self.course_id)[0]
...@@ -144,9 +35,10 @@ class PermissionsTestCase(NoSignalTestCase): ...@@ -144,9 +35,10 @@ class PermissionsTestCase(NoSignalTestCase):
def tearDown(self): def tearDown(self):
self.student_enrollment.delete() self.student_enrollment.delete()
self.moderator_enrollment.delete() self.moderator_enrollment.delete()
self.student.delete()
self.moderator.delete() # Do we need to have this? We shouldn't be deleting students, ever
super(PermissionsTestCase, self).tearDown() # self.student.delete()
# self.moderator.delete()
def testDefaultRoles(self): def testDefaultRoles(self):
self.assertTrue(self.student_role in self.student.roles.all()) self.assertTrue(self.student_role in self.student.roles.all())
......
...@@ -39,7 +39,7 @@ def update_template_dictionary(dictionary, request=None, course=None, article=No ...@@ -39,7 +39,7 @@ def update_template_dictionary(dictionary, request=None, course=None, article=No
if course: if course:
dictionary['course'] = course dictionary['course'] = course
if 'namespace' not in dictionary: if 'namespace' not in dictionary:
dictionary['namespace'] = course.wiki_namespace dictionary['namespace'] = "edX"
else: else:
dictionary['course'] = None dictionary['course'] = None
...@@ -99,7 +99,7 @@ def root_redirect(request, course_id=None): ...@@ -99,7 +99,7 @@ def root_redirect(request, course_id=None):
course = get_opt_course_with_access(request.user, course_id, 'load') course = get_opt_course_with_access(request.user, course_id, 'load')
#TODO: Add a default namespace to settings. #TODO: Add a default namespace to settings.
namespace = course.wiki_namespace if course else "edX" namespace = "edX"
try: try:
root = Article.get_root(namespace) root = Article.get_root(namespace)
...@@ -479,7 +479,7 @@ def not_found(request, article_path, course): ...@@ -479,7 +479,7 @@ def not_found(request, article_path, course):
"""Generate a NOT FOUND message for some URL""" """Generate a NOT FOUND message for some URL"""
d = {'wiki_err_notfound': True, d = {'wiki_err_notfound': True,
'article_path': article_path, 'article_path': article_path,
'namespace': course.wiki_namespace} 'namespace': "edX"}
update_template_dictionary(d, request, course) update_template_dictionary(d, request, course)
return render_to_response('simplewiki/simplewiki_error.html', d) return render_to_response('simplewiki/simplewiki_error.html', d)
......
...@@ -304,6 +304,7 @@ SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False ...@@ -304,6 +304,7 @@ SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False
################################# WIKI ################################### ################################# WIKI ###################################
WIKI_ACCOUNT_HANDLING = False WIKI_ACCOUNT_HANDLING = False
WIKI_EDITOR = 'course_wiki.editors.CodeMirror' WIKI_EDITOR = 'course_wiki.editors.CodeMirror'
WIKI_SHOW_MAX_CHILDREN = 0 # We don't use the little menu that shows children of an article in the breadcrumb
################################# Jasmine ################################### ################################# Jasmine ###################################
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee' JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/static/coffee'
......
...@@ -84,11 +84,17 @@ DATABASES = { ...@@ -84,11 +84,17 @@ DATABASES = {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': ENV_ROOT / "db" / "course1.db", 'NAME': ENV_ROOT / "db" / "course1.db",
}, },
'edx/full/6.002_Spring_2012': { 'edx/full/6.002_Spring_2012': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': ENV_ROOT / "db" / "course2.db", 'NAME': ENV_ROOT / "db" / "course2.db",
} },
'edX/toy/TT_2012_Fall': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ENV_ROOT / "db" / "course3.db",
},
} }
CACHES = { CACHES = {
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<%static:js group='courseware'/> <%static:js group='courseware'/>
<%include file="discussion/_js_dependencies.html" /> <%include file="../discussion/_js_dependencies.html" />
<%include file="/mathjax_include.html" /> <%include file="/mathjax_include.html" />
<!-- TODO: http://docs.jquery.com/Plugins/Validation --> <!-- TODO: http://docs.jquery.com/Plugins/Validation -->
...@@ -59,8 +59,8 @@ ...@@ -59,8 +59,8 @@
<div id="course-errors"> <div id="course-errors">
<ul> <ul>
% for (msg, err) in course_errors: % for (msg, err) in course_errors:
<li>${msg} <li>${msg | h}
<ul><li><pre>${err}</pre></li></ul> <ul><li><pre>${err | h}</pre></li></ul>
</li> </li>
% endfor % endfor
</ul> </ul>
......
...@@ -69,6 +69,7 @@ ${"Edit " + wiki_title + " - " if wiki_title is not UNDEFINED else ""}MITx 6.002 ...@@ -69,6 +69,7 @@ ${"Edit " + wiki_title + " - " if wiki_title is not UNDEFINED else ""}MITx 6.002
%else: %else:
<input type="submit" id="submit_edit" name="edit" value="Save Changes" /> <input type="submit" id="submit_edit" name="edit" value="Save Changes" />
<input type="submit" id="submit_delete" name="delete" value="Delete article" /> <input type="submit" id="submit_delete" name="delete" value="Delete article" />
%endif
<%include file="simplewiki_instructions.html"/> <%include file="simplewiki_instructions.html"/>
......
...@@ -52,6 +52,9 @@ ...@@ -52,6 +52,9 @@
</style> </style>
{% endaddtoblock %} {% endaddtoblock %}
<p class="lead">
{% trans "Click each revision to see a list of edited lines. Click the Preview button to see how the article looked at this stage. At the bottom of this page, you can change to a particular revision or merge an old revision with the current one." %}
</p>
<form method="GET"> <form method="GET">
<div class="tab-content" style="overflow: visible;"> <div class="tab-content" style="overflow: visible;">
...@@ -60,20 +63,14 @@ ...@@ -60,20 +63,14 @@
<div class="accordion-group"> <div class="accordion-group">
<div class="accordion-heading"> <div class="accordion-heading">
<a class="accordion-toggle" style="float: left;" href="#collapse{{ revision.revision_number }}" onclick="get_diff_json('{% url 'wiki:diff' revision.id %}', $('#collapse{{ revision.revision_number }}'))"> <a class="accordion-toggle" style="float: left;" href="#collapse{{ revision.revision_number }}" onclick="get_diff_json('{% url 'wiki:diff' revision.id %}', $('#collapse{{ revision.revision_number }}'))">
{{ revision.created }} (#{{ revision.revision_number }}) by {% if revision.user %}{{ revision.user }}{% else %}{% if user|is_moderator %}{{ revision.ip_address|default:"anonymous (IP not logged)" }}{% else %}{% trans "anonymous (IP logged)" %}{% endif %}{% endif %} <span class="icon-plus"></span>
{% if revision == article.current_revision %} {% include "wiki/includes/revision_info.html" with current_revision=article.current_revision %}
<strong>*</strong>
{% endif %}
{% if revision.deleted %}
<span class="badge badge-important">{% trans "deleted" %}</span>
{% endif %}
{% if revision.previous_revision.deleted and not revision.deleted %}
<span class="badge badge-success">{% trans "restored" %}</span>
{% endif %}
<div style="color: #CCC;"> <div style="color: #CCC;">
<small> <small>
{% if revision.user_message %} {% if revision.user_message %}
{{ revision.user_message }} {{ revision.user_message }}
{% elif revision.automatic_log %}
{{ revision.automatic_log }}
{% else %} {% else %}
({% trans "no log message" %}) ({% trans "no log message" %})
{% endif %} {% endif %}
...@@ -84,21 +81,12 @@ ...@@ -84,21 +81,12 @@
<div class="bar" style="width: 100%;"></div> <div class="bar" style="width: 100%;"></div>
</div> </div>
<div class="pull-right" style="vertical-align: middle; margin: 8px 3px;"> <div class="pull-right" style="vertical-align: middle; margin: 8px 3px;">
{% if revision == article.current_revision %} {% if not revision == article.current_revision %}
<a href="#" class="btn disabled">
<span class="icon-lock"></span>
{% trans "Preview this version" %}
</a>
{% else %}
<button type="submit" class="btn" onclick="$('#previewModal').modal('show'); this.form.target='previewWindow'; this.form.r.value='{{ revision.id }}'; this.form.action='{% url 'wiki:preview_revision' article.id %}'; $('#previewModal .switch-to-revision').attr('href', '{% url 'wiki:change_revision' path=urlpath.path article_id=article.id revision_id=revision.id %}')"> <button type="submit" class="btn" onclick="$('#previewModal').modal('show'); this.form.target='previewWindow'; this.form.r.value='{{ revision.id }}'; this.form.action='{% url 'wiki:preview_revision' article.id %}'; $('#previewModal .switch-to-revision').attr('href', '{% url 'wiki:change_revision' path=urlpath.path article_id=article.id revision_id=revision.id %}')">
<span class="icon-eye-open"></span> <span class="icon-eye-open"></span>
{% trans "Preview this version" %} {% trans "Preview this revision" %}
</button> </button>
{% endif %} {% endif %}
<a class="btn btn-info" href="#collapse{{ revision.revision_number }}" onclick="get_diff_json('{% url 'wiki:diff' revision_id=revision.id %}', $('#collapse{{ revision.revision_number }}'))">
<span class="icon-list-alt"></span>
{% trans "Show changes" %}
</a>
{% if article|can_write:user %} {% if article|can_write:user %}
<input type="radio"{% if revision == article.current_revision %} disabled="true"{% endif %} style="margin: 0 10px;" value="{{ revision.id }}" name="revision_id" switch-button-href="{% url 'wiki:change_revision' path=urlpath.path revision_id=revision.id %}" merge-button-href="{% url 'wiki:merge_revision_preview' article_id=article.id revision_id=revision.id %}" merge-button-commit-href="{% url 'wiki:merge_revision' path=urlpath.path article_id=article.id revision_id=revision.id %}" /> <input type="radio"{% if revision == article.current_revision %} disabled="true"{% endif %} style="margin: 0 10px;" value="{{ revision.id }}" name="revision_id" switch-button-href="{% url 'wiki:change_revision' path=urlpath.path revision_id=revision.id %}" merge-button-href="{% url 'wiki:merge_revision_preview' article_id=article.id revision_id=revision.id %}" merge-button-commit-href="{% url 'wiki:merge_revision' path=urlpath.path article_id=article.id revision_id=revision.id %}" />
...@@ -157,7 +145,7 @@ ...@@ -157,7 +145,7 @@
<input type="hidden" name="r" value="" /> <input type="hidden" name="r" value="" />
<div class="modal hide fade" id="previewModal"> <div class="modal hide fade" id="previewModal">
<div class="modal-body"> <div class="modal-body">
<iframe name="previewWindow" frameborder="0"></iframe> <iframe name="previewWindow"></iframe>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn btn-large" data-dismiss="modal"> <a href="#" class="btn btn-large" data-dismiss="modal">
...@@ -184,7 +172,7 @@ ...@@ -184,7 +172,7 @@
<p class="lead"><span class="icon-info-sign"></span> {% trans "When you merge a revision with the current, all data will be retained from both versions and merged at its approximate location from each revision." %} <strong>{% trans "After this, it's important to do a manual review." %}</strong></p> <p class="lead"><span class="icon-info-sign"></span> {% trans "When you merge a revision with the current, all data will be retained from both versions and merged at its approximate location from each revision." %} <strong>{% trans "After this, it's important to do a manual review." %}</strong></p>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<iframe name="mergeWindow" frameborder="0"></iframe> <iframe name="mergeWindow"></iframe>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<a href="#" class="btn btn-large" data-dismiss="modal"> <a href="#" class="btn btn-large" data-dismiss="modal">
......
{% load i18n %}{% load url from future %} ## mako
{% if urlpath %} <%! from django.core.urlresolvers import reverse %>
%if urlpath is not Undefined and urlpath:
<header> <header>
<ul class="breadcrumb pull-left" class=""> <ul class="breadcrumb pull-left" class="">
{% for ancestor in urlpath.get_ancestors.all %} <%
<li><a href="{% url 'wiki:get' path=ancestor.path %}">{{ ancestor.article.current_revision.title }}</a></li> # The create button links to the highest ancestor we have edit priveleges to
{% endfor %} create_article_root = None
<li class="active"><a href="{% url 'wiki:get' path=urlpath.path %}">{{ article.current_revision.title }}</a></li> %>
%for ancestor in urlpath.cached_ancestors:
<li><a href="${reverse('wiki:get', kwargs={'path' : ancestor.path})}">${ancestor.article.current_revision.title}</a></li>
<%
if not create_article_root and ancestor.article.can_write(user):
create_article_root = ancestor
%>
%endfor
<li class="active"><a href="${reverse('wiki:get', kwargs={'path' : urlpath.path})}">${article.current_revision.title}</a></li>
<%
if not create_article_root and urlpath.article.can_write(user):
create_article_root = urlpath
%>
</ul> </ul>
<div class="pull-left" style="margin-left: 10px;">
<div class="btn-group">
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#" style="padding: 7px;" title="{% trans "Sub-articles for" %} {{ article.current_revision.title }}">
<span class="icon-list"></span>
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
{% for child in children_slice %}
<li>
<a href="{% url 'wiki:get' path=child.path %}">
{{ child.article.current_revision.title }}
</a>
</li>
{% empty %}
<li><a href="#"><em>{% trans "No sub-articles" %}</em></a></li>
{% endfor %}
{% if children_slice_more %}
<li><a href="#"><em>{% trans "...and more" %}</em></a></li>
{% endif %}
<li class="divider"></li>
<li>
<a href="" onclick="alert('TODO')">{% trans "List sub-pages" %} &raquo;</a>
</li>
</ul>
</div>
</div>
<div class="global-functions pull-right"> <div class="global-functions pull-right">
<form class="search-wiki pull-left"> <!-- <form class="search-wiki pull-left">
<input type="search" placeholder="search wiki" /> <input type="search" placeholder="search wiki" />
</form> </form> -->
<a class="add-article-btn btn pull-left" href="{% url 'wiki:create' path=urlpath.path %}" style="padding: 7px;"> %if create_article_root:
<a class="add-article-btn btn pull-left" href="${reverse('wiki:create', kwargs={'path' : create_article_root.path})}" style="padding: 7px;">
<span class="icon-plus"></span> <span class="icon-plus"></span>
{% trans "Add article" %} Add article
</a> </a>
%endif
</div> </div>
</header> </header>
{% endif %} %endif
{% extends "wiki/base.html" %}
{% load wiki_tags i18n %}
{% load url from future %}
{% block pagetitle %}{{ article.current_revision.title }}{% endblock %}
{% block wiki_breadcrumbs %}
{% include "wiki/includes/breadcrumbs.html" %}
{% endblock %}
{% block wiki_contents %}
<div class="missing-wrapper">
<p>This article was not found, and neither was the parent. <a href="#">Go back to the main wiki article.</a></p>
<button type="submit">Create a new article</button>
</div>
{% endblock %}
-e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles -e git://github.com/MITx/django-staticfiles.git@6d2504e5c8#egg=django-staticfiles
-e git://github.com/MITx/django-pipeline.git#egg=django-pipeline -e git://github.com/MITx/django-pipeline.git#egg=django-pipeline
-e git://github.com/benjaoming/django-wiki.git@c145596#egg=django-wiki -e git://github.com/benjaoming/django-wiki.git@e237b2ac#egg=django-wiki
-e git://github.com/dementrock/pystache_custom.git#egg=pystache_custom
-e common/lib/capa -e common/lib/capa
-e common/lib/xmodule -e common/lib/xmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment