(r'^course/(?P<course_id>\d+)/$', 'course_detail'),
(r'^instructor/(?P<instructor_id>.*)/$', 'instructor_detail'),
(r'^department/(?P<department_id>.*)/$', 'department_detail'),
+ (r'^course/(?P<course_id>\d+)/search/$', 'course_search'),
(ITEM_PREFIX + r'$', 'item_detail'),
(ITEM_PREFIX + r'dl/(?P<filename>.*)$', 'item_download'),
- (ITEM_PREFIX + r'meta/$', 'item_metadata'),
+ (ITEM_PREFIX + r'meta$', 'item_metadata'),
(ITEM_PREFIX + r'edit/$', 'item_edit'),
(ITEM_PREFIX + r'add/$', 'item_add'), # for adding sub-things
)
return login_required(lambda *args: None)(request)
return g.render('course_detail.xhtml', course=course)
+def course_search(request, course_id):
+ course = get_object_or_404(models.Course, pk=course_id)
+ return search(request, in_course=course)
+
def instructor_detail(request, instructor_id):
page_num = int(request.GET.get('page', 1))
count = int(request.GET.get('count', 5))
@login_required
def item_add(request, course_id, item_id):
- # The item-id is the id for the parent-heading item. Zero represents
- # 'top-level', i.e. the new item should have no heading. For any other
- # number, we must check that the parent item is of the Heading type.
- if item_id=='0':
+ # The parent_item_id is the id for the parent-heading item. Zero
+ # represents 'top-level', i.e. the new item should have no
+ # heading.
+ #For any other number, we must check that the parent
+ # item is of the Heading type.
+ parent_item_id = item_id
+ if parent_item_id=='0':
parent_item = None
course = get_object_or_404(models.Course, pk=course_id)
else:
- parent_item = get_object_or_404(models.Item, pk=item_id, course__id=course_id)
+ parent_item = get_object_or_404(models.Item, pk=parent_item_id, course__id=course_id)
assert parent_item.item_type == 'HEADING', 'Can only add items to headings!'
course = parent_item.course
assert item_type, 'No item_type parameter was provided.'
# for the moment, only HEADINGs, URLs and ELECs can be added.
- assert item_type in ('HEADING', 'URL', 'ELEC'), 'Sorry, only HEADINGs, URLs and ELECs can be added right now.'
+ assert item_type in ('HEADING', 'URL', 'ELEC'), \
+ 'Sorry, only HEADINGs, URLs and ELECs can be added right now.'
if request.method == 'GET':
return g.render('item_add_%s.xhtml' % item_type.lower(),
activation_date=datetime.now(),
last_modified=datetime.now())
item.save()
- return HttpResponseRedirect(item_url(item))
elif item_type == 'URL':
title = request.POST.get('title', '').strip()
url = request.POST.get('url', '').strip()
- if not (title or url):
+ if not (title and url):
# fixme, better error handling.
return HttpResponseRedirect(request.get_full_path())
else:
last_modified=datetime.now(),
url = url)
item.save()
- return HttpResponseRedirect(item_url(item, 'meta/'))
elif item_type == 'ELEC':
title = request.POST.get('title', '').strip()
upload = request.FILES.get('file')
+ if not (title and upload):
+ # fixme, better error handling.
+ return HttpResponseRedirect(request.get_full_path())
item = models.Item(
course=course,
item_type='ELEC',
)
item.fileobj.save(upload.name, upload)
item.save()
-
- return HttpResponseRedirect(item_url(item, 'meta/'))
else:
raise NotImplementedError
+ if parent_item:
+ return HttpResponseRedirect(item_url(parent_item, 'meta'))
+ else:
+ return HttpResponseRedirect(course_url(course))
+
def item_download(request, course_id, item_id, filename):
course = get_object_or_404(models.Course, pk=course_id)
item = get_object_or_404(models.Item, pk=item_id, course__id=course_id)
#------------------------------------------------------------
-def search(request):
+def search(request, in_course=None):
''' Need to work on this, the basic idea is
- put an entry point for instructor and course listings
- page through item entries
+ If in_course is provided, then limit search to the contents of the specified course.
'''
query_string = ''
found_entries = None
item_query = get_query(query_string, ['title', 'author'])
#need to think about sort order here, probably better by author (will make sortable at display level)
results_list = models.Item.objects.filter(item_query).order_by('title')
+ if in_course:
+ results_list = results_list.filter(course=in_course)
results_len = len(results_list)
paginator = Paginator( results_list,
count)
#course search
- course_query = get_query(query_string, ['title', 'department__name'])
- print 'course_query'
- print course_query
- course_results = models.Course.objects.filter(course_query).filter(active=True)
- # course_list = models.Course.objects.filter(course_query).filter(active=True).order_by('title')[0:5]
- course_list = course_results.order_by('title')[0:5]
- #there might be a better way of doing this, though instr and course tables should not be expensive to query
- #len directly on course_list will reflect limit
- course_len = len(course_results)
+ if in_course:
+ # then no course search is necessary.
+ course_list = []; course_len = 0
+ else:
+ course_query = get_query(query_string, ['title', 'department__name'])
+ print 'course_query'
+ print course_query
+ course_results = models.Course.objects.filter(course_query).filter(active=True)
+ # course_list = models.Course.objects.filter(course_query).filter(active=True).order_by('title')[0:5]
+ course_list = course_results.order_by('title')[0:5]
+ #there might be a better way of doing this, though instr and course tables should not be expensive to query
+ #len directly on course_list will reflect limit
+ course_len = len(course_results)
#instructor search
instr_query = get_query(query_string, ['user__last_name'])
instructor_results = models.Member.objects.filter(instr_query).filter(role='INSTR')
+ if in_course:
+ instructor_results = instructor_results.filter(course=in_course)
instructor_list = instructor_results.order_by('user__last_name')[0:5]
instr_len = len(instructor_results)
+ elif in_course:
+ # we are in a course, but have no query? Return to the course-home page.
+ return HttpResponseRedirect('../')
else:
results_list = models.Item.objects.order_by('title')
results_len = len(results_list)
--- /dev/null
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ py:strip="">
+
+ <div py:def="course_search(course)"
+ id="coursesearch" style="float: right;">
+ <form method="get" action="${course_url(course, 'search')}"
+ onsubmit="if(q.value.replace(/^\s*/, '').replace(/\s*$/, '') =='') return false;">
+ <input id="q" name="q" maxlength="100" size="25" type="text"
+ value="search this course..." onblur="if(this.value=='') this.value='search this course...';"
+ onfocus="if(this.value=='search this course...') this.value='';"/>
+ </form>
+ </div>
+
+ <div py:def="course_banner(course)"
+ id="coursebanner">
+ <div class="deptident">${course.department}</div>
+ ${course_search(course)}
+ <h1><a href="${course_url(course)}">${course.code}: ${course.title}</a></h1>
+ </div>
+
+ <!-- !show_tree: display a tree of items in a hierarchical style. -->
+ <ul py:def="show_tree(tree, edit=False)"
+ py:if="tree"
+ class="itemtree">
+ <li py:for="item, subs in tree" class="item_${item.item_type}">
+ <a href="${item_url(item)}">${item}</a>
+ <span py:if="item.needs_meta_link()" class="menublock">
+ <a href="${item_url(item, 'meta')}">about</a>
+ </span>
+ <!-- ${show_tree(subs, edit)} -->
+ </li>
+ </ul>
+
+ <div py:def="nested_title(item)"
+ py:if="item"
+ py:with="hier=item.hierarchy()[:-1]; lastnum=len(hier)"
+ class="nestedtitle">
+ <div class="breadcrumbs">
+ <span><a href="${course_url(item.course)}">Top</a></span> »
+ <span py:for="n, x in enumerate(hier)"><a href="${item_url(x)}">${x.title}</a> » </span>
+ <b>${item.title}</b>
+ </div>
+ </div>
+
+ <div py:def="add_subs(parent=None)" class="itemadd">
+ <div>Add a new item:</div>
+ <ul py:with="prefix = (not parent) and 'item/0/' or ''">
+ <li><a href="${prefix}add/?item_type=HEADING">Subheading</a></li>
+ <li><a href="${prefix}add/?item_type=URL">URL</a></li>
+ <li><a href="${prefix}add/?item_type=ELEC">Electronic Document</a></li>
+ <li><a href="${prefix}add/?item_type=PHYS">Physical Book/Document</a></li>
+ </ul>
+ </div>
+
+</html>
<li py:for="item, subs in tree" class="item_${item.item_type}">
<a href="${item_url(item)}">${item}</a>
<span py:if="item.needs_meta_link()" class="menublock">
- <a href="${item_url(item, 'meta/')}">about</a>
+ <a href="${item_url(item, 'meta')}">about</a>
</span>
<!-- ${show_tree(subs, edit)} -->
</li>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
+ <xi:include href="components/course.xhtml"/>
<head>
<title>${title}</title>
<script type="text/javascript" src="/static/menublocks.js"/>
</head>
<body>
- <div id="coursebanner">
- <div class="deptident">${course.department}</div>
- <h1>${title}</h1>
- </div>
+ ${course_banner(course)}
<p py:if="not item_tree">
There are no items associated with this course yet.
</p>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
+ <xi:include href="components/course.xhtml"/>
<head>
<title>${title}</title>
+ <script type="text/javascript">
+ $(function() {$('input[@name="title"]').focus();});
+ </script>
</head>
<body>
- <div id="coursebanner">
- <div>${course.department}</div>
- <h1><a href="${course_url(course)}">${course_title}</a></h1>
- </div>
- <div py:if="parent_item">${nested_title(parent_item)}</div>
- <h3>${title}</h3>
+ ${course_banner(course)}
+ ${nested_title(parent_item)}
+ <h3>${title}</h3>
<form action=".?item_type=${item_type}" method="POST"
enctype="multipart/form-data">
<table>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
+ <xi:include href="components/course.xhtml"/>
<head>
<title>${title}</title>
+ <script type="text/javascript">
+ $(function() {$('input[@name="title"]').focus();});
+ </script>
</head>
<body>
- <div class="courseident">
- <div id="coursebanner">
- <div>${course.department}</div>
- <h1><a href="${course_url(course)}">${course_title}</a></h1>
- </div>
- <div py:if="parent_item">${nested_title(parent_item)}</div>
- <h3>${title}</h3>
- <form action=".?item_type=${item_type}" method="POST">
- <table>
- <tr><th>Heading</th><td><input type="text" name="title"/></td></tr>
- </table>
- <p><input type="submit" value="Create heading"/></p>
- </form>
- </div>
+ ${course_banner(course)}
+ ${nested_title(parent_item)}
+ <h3>${title}</h3>
+ <form action=".?item_type=${item_type}" method="POST">
+ <table>
+ <tr><th>Heading</th><td><input type="text" name="title"/></td></tr>
+ </table>
+ <p><input type="submit" value="Create heading"/></p>
+ </form>
</body>
</html>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
+ <xi:include href="components/course.xhtml"/>
<head>
<title>${title}</title>
+ <script type="text/javascript">
+ $(function() {$('input[@name="title"]').focus();});
+ </script>
</head>
<body>
- <div class="courseident">
- <div id="coursebanner">
- <div>${course.department}</div>
- <h1><a href="${course_url(course)}">${course_title}</a></h1>
- </div>
- <div py:if="parent_item">${nested_title(parent_item)}</div>
- <h3>${title}</h3>
- <form action=".?item_type=${item_type}" method="POST">
- <table>
- <tr><th>Title</th><td><input type="text" name="title"/></td></tr>
- <tr><th>URL</th><td><input type="text" name="url"/></td></tr>
- </table>
- <p><input type="submit" value="Create item"/></p>
- </form>
- </div>
+ ${course_banner(course)}
+ ${nested_title(parent_item)}
+ <h3>${title}</h3>
+ <form action=".?item_type=${item_type}" method="POST">
+ <table>
+ <tr><th>Title</th><td><input type="text" name="title"/></td></tr>
+ <tr><th>URL</th><td><input type="text" name="url"/></td></tr>
+ </table>
+ <p><input type="submit" value="Create item"/></p>
+ </form>
</body>
</html>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
- <head>
+ <xi:include href="components/course.xhtml"/>
+ <head>
<title>${title}</title>
<script type="text/javascript" src="/static/menublocks.js"/>
</head>
<body>
- <div id="coursebanner">
- <div class="courseident">
- <div>${course.department}</div>
- <h1><a href="${course_url(course)}">${course_title}</a></h1>
- </div>
- </div>
+ ${course_banner(course)}
${nested_title(item)}
- <!-- <p py:if="not item_tree"> -->
- <!-- There are no items associated in this subheading. -->
- <!-- </p> -->
+ <p py:if="not item_tree">
+ There are no items in this section.
+ </p>
${show_tree(item_tree, edit=is_editor)}
<div py:if="is_editor">${add_subs(item)}</div>
</body>
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:py="http://genshi.edgewall.org/">
<xi:include href="master.xhtml"/>
- <xi:include href="components/item.xhtml"/>
+ <xi:include href="components/course.xhtml"/>
<head>
<title>${title}</title>
</head>
<body>
- <div id="coursebanner">
- <div class="courseident">
- <div>${course.department}</div>
- <h1><a href="${course_url(course)}">${course_title}</a></h1>
- </div>
- </div>
+ ${course_banner(course)}
${nested_title(item)}
<table>
</tr>
<tr py:for="course in courses">
<!-- will highlight this, probably pull in dept info -->
- <td>${course.title}</td>
+ <td><a href="../course/${course.id}/">${course.title}</a></td>
</tr>
<tr py:if="course_len > count">
<td></td>
<span py:def="pagerow(item)">
<td>${Markup(item.author_hl(norm_query))}</td>
<td><a href="${item_url(item)}">${Markup(item.title_hl(norm_query))}</a></td>
+ <td><a href="../course/${item.course.id}/">${item.course.title}</a></td>
</span>
${pagetable(paginator, count, pagerow, pageheader)}