Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
0605c941
Commit
0605c941
authored
Mar 11, 2013
by
David Ormsbee
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1636 from MITx/feature/brian/htmlbook
Initial implementation of htmlbook.
parents
aceb6660
53f85f2a
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
218 additions
and
2 deletions
+218
-2
common/lib/xmodule/xmodule/course_module.py
+8
-1
lms/djangoapps/courseware/tabs.py
+12
-0
lms/djangoapps/staticbook/views.py
+41
-1
lms/static/sass/course/_textbook.scss
+13
-0
lms/templates/static_htmlbook.html
+135
-0
lms/urls.py
+9
-0
No files found.
common/lib/xmodule/xmodule/course_module.py
View file @
0605c941
...
...
@@ -356,7 +356,14 @@ class CourseDescriptor(SequenceDescriptor):
"""
Return the pdf_textbooks config, as a python object, or None if not specified.
"""
return
self
.
metadata
.
get
(
'pdf_textbooks'
)
return
self
.
metadata
.
get
(
'pdf_textbooks'
,
[])
@property
def
html_textbooks
(
self
):
"""
Return the html_textbooks config, as a python object, or None if not specified.
"""
return
self
.
metadata
.
get
(
'html_textbooks'
,
[])
@tabs.setter
def
tabs
(
self
,
value
):
...
...
lms/djangoapps/courseware/tabs.py
View file @
0605c941
...
...
@@ -130,6 +130,17 @@ def _pdf_textbooks(tab, user, course, active_page):
for
index
,
textbook
in
enumerate
(
course
.
pdf_textbooks
)]
return
[]
def
_html_textbooks
(
tab
,
user
,
course
,
active_page
):
"""
Generates one tab per textbook. Only displays if user is authenticated.
"""
if
user
.
is_authenticated
():
# since there can be more than one textbook, active_page is e.g. "book/0".
return
[
CourseTab
(
textbook
[
'tab_title'
],
reverse
(
'html_book'
,
args
=
[
course
.
id
,
index
]),
active_page
==
"htmltextbook/{0}"
.
format
(
index
))
for
index
,
textbook
in
enumerate
(
course
.
html_textbooks
)]
return
[]
def
_staff_grading
(
tab
,
user
,
course
,
active_page
):
if
has_access
(
user
,
course
,
'staff'
):
link
=
reverse
(
'staff_grading'
,
args
=
[
course
.
id
])
...
...
@@ -209,6 +220,7 @@ VALID_TAB_TYPES = {
'external_link'
:
TabImpl
(
key_checker
([
'name'
,
'link'
]),
_external_link
),
'textbooks'
:
TabImpl
(
null_validator
,
_textbooks
),
'pdf_textbooks'
:
TabImpl
(
null_validator
,
_pdf_textbooks
),
'html_textbooks'
:
TabImpl
(
null_validator
,
_html_textbooks
),
'progress'
:
TabImpl
(
need_name
,
_progress
),
'static_tab'
:
TabImpl
(
key_checker
([
'name'
,
'url_slug'
]),
_static_tab
),
'peer_grading'
:
TabImpl
(
null_validator
,
_peer_grading
),
...
...
lms/djangoapps/staticbook/views.py
View file @
0605c941
from
lxml
import
etree
# from django.conf import settings
from
django.contrib.auth.decorators
import
login_required
from
django.http
import
Http404
from
mitxmako.shortcuts
import
render_to_response
from
courseware.access
import
has_access
...
...
@@ -15,6 +15,8 @@ def index(request, course_id, book_index, page=None):
staff_access
=
has_access
(
request
.
user
,
course
,
'staff'
)
book_index
=
int
(
book_index
)
if
book_index
<
0
or
book_index
>=
len
(
course
.
textbooks
):
raise
Http404
(
"Invalid book index value: {0}"
.
format
(
book_index
))
textbook
=
course
.
textbooks
[
book_index
]
table_of_contents
=
textbook
.
table_of_contents
...
...
@@ -40,6 +42,8 @@ def pdf_index(request, course_id, book_index, chapter=None, page=None):
staff_access
=
has_access
(
request
.
user
,
course
,
'staff'
)
book_index
=
int
(
book_index
)
if
book_index
<
0
or
book_index
>=
len
(
course
.
pdf_textbooks
):
raise
Http404
(
"Invalid book index value: {0}"
.
format
(
book_index
))
textbook
=
course
.
pdf_textbooks
[
book_index
]
def
remap_static_url
(
original_url
,
course
):
...
...
@@ -67,3 +71,39 @@ def pdf_index(request, course_id, book_index, chapter=None, page=None):
'chapter'
:
chapter
,
'page'
:
page
,
'staff_access'
:
staff_access
})
@login_required
def
html_index
(
request
,
course_id
,
book_index
,
chapter
=
None
,
anchor_id
=
None
):
course
=
get_course_with_access
(
request
.
user
,
course_id
,
'load'
)
staff_access
=
has_access
(
request
.
user
,
course
,
'staff'
)
book_index
=
int
(
book_index
)
if
book_index
<
0
or
book_index
>=
len
(
course
.
html_textbooks
):
raise
Http404
(
"Invalid book index value: {0}"
.
format
(
book_index
))
textbook
=
course
.
html_textbooks
[
book_index
]
def
remap_static_url
(
original_url
,
course
):
input_url
=
"'"
+
original_url
+
"'"
output_url
=
replace_static_urls
(
input_url
,
course
.
metadata
[
'data_dir'
],
course_namespace
=
course
.
location
)
# strip off the quotes again...
return
output_url
[
1
:
-
1
]
if
'url'
in
textbook
:
textbook
[
'url'
]
=
remap_static_url
(
textbook
[
'url'
],
course
)
# then remap all the chapter URLs as well, if they are provided.
if
'chapters'
in
textbook
:
for
entry
in
textbook
[
'chapters'
]:
entry
[
'url'
]
=
remap_static_url
(
entry
[
'url'
],
course
)
return
render_to_response
(
'static_htmlbook.html'
,
{
'book_index'
:
book_index
,
'course'
:
course
,
'textbook'
:
textbook
,
'chapter'
:
chapter
,
'anchor_id'
:
anchor_id
,
'staff_access'
:
staff_access
})
lms/static/sass/course/_textbook.scss
View file @
0605c941
...
...
@@ -158,6 +158,19 @@ div.book-wrapper {
img
{
max-width
:
100%
;
}
div
{
text-align
:
left
;
line-height
:
1
.6em
;
margin-left
:
5px
;
margin-right
:
5px
;
margin-top
:
5px
;
margin-bottom
:
5px
;
.Paragraph
,
h2
{
margin-top
:
10px
;
}
}
}
}
...
...
lms/templates/static_htmlbook.html
0 → 100644
View file @
0605c941
<
%
inherit
file=
"main.html"
/>
<
%
namespace
name=
'static'
file=
'static_content.html'
/>
<
%
block
name=
"title"
><title>
${course.number} Textbook
</title>
</
%
block>
<
%
block
name=
"headextra"
>
<
%
static:css
group=
'course'
/>
<
%
static:js
group=
'courseware'
/>
</
%
block>
<
%
block
name=
"js_extra"
>
<script
type=
"text/javascript"
>
(
function
(
$
)
{
$
.
fn
.
myHTMLViewer
=
function
(
options
)
{
var
urlToLoad
=
null
;
if
(
options
.
url
)
{
urlToLoad
=
options
.
url
;
}
var
chapterUrls
=
null
;
if
(
options
.
chapters
)
{
chapterUrls
=
options
.
chapters
;
}
var
chapterToLoad
=
1
;
if
(
options
.
chapterNum
)
{
// TODO: this should only be specified if there are
// chapters, and it should be in-bounds.
chapterToLoad
=
options
.
chapterNum
;
}
var
anchorToLoad
=
null
;
if
(
options
.
chapters
)
{
anchorToLoad
=
options
.
anchor_id
;
}
loadUrl
=
function
htmlViewLoadUrl
(
url
,
anchorId
)
{
// clear out previous load, if any:
parentElement
=
document
.
getElementById
(
'bookpage'
);
while
(
parentElement
.
hasChildNodes
())
parentElement
.
removeChild
(
parentElement
.
lastChild
);
// load new URL in:
$
(
'#bookpage'
).
load
(
url
);
// if there is an anchor set, then go to that location:
if
(
anchorId
!=
null
)
{
// TODO: add implementation....
}
};
loadChapterUrl
=
function
htmlViewLoadChapterUrl
(
chapterNum
,
anchorId
)
{
if
(
chapterNum
<
1
||
chapterNum
>
chapterUrls
.
length
)
{
return
;
}
var
chapterUrl
=
chapterUrls
[
chapterNum
-
1
];
loadUrl
(
chapterUrl
,
anchorId
);
};
// define navigation links for chapters:
if
(
chapterUrls
!=
null
)
{
var
loadChapterUrlHelper
=
function
(
i
)
{
return
function
(
event
)
{
// when opening a new chapter, always open to the top:
loadChapterUrl
(
i
,
null
);
};
};
for
(
var
index
=
1
;
index
<=
chapterUrls
.
length
;
index
+=
1
)
{
$
(
"#htmlchapter-"
+
index
).
click
(
loadChapterUrlHelper
(
index
));
}
}
// finally, load the appropriate url/page
if
(
urlToLoad
!=
null
)
{
loadUrl
(
urlToLoad
,
anchorToLoad
);
}
else
{
loadChapterUrl
(
chapterToLoad
,
anchorToLoad
);
}
}
})(
jQuery
);
$
(
document
).
ready
(
function
()
{
var
options
=
{};
%
if
'url'
in
textbook
:
options
.
url
=
"${textbook['url']}"
;
%
endif
%
if
'chapters'
in
textbook
:
var
chptrs
=
[];
%
for
chap
in
textbook
[
'chapters'
]:
chptrs
.
push
(
"${chap['url']}"
);
%
endfor
options
.
chapters
=
chptrs
;
%
endif
%
if
chapter
is
not
None
:
options
.
chapterNum
=
$
{
chapter
};
%
endif
%
if
anchor_id
is
not
None
:
options
.
anchor_id
=
$
{
anchor_id
};
%
endif
$
(
'#outerContainer'
).
myHTMLViewer
(
options
);
});
</script>
</
%
block>
<
%
include
file=
"/courseware/course_navigation.html"
args=
"active_page='htmltextbook/{0}'.format(book_index)"
/>
<div
id=
"outerContainer"
>
<div
id=
"mainContainer"
class=
"book-wrapper"
>
%if 'chapters' in textbook:
<section
aria-label=
"Textbook Navigation"
class=
"book-sidebar"
>
<ul
id=
"booknav"
class=
"treeview-booknav"
>
<
%
def
name=
"print_entry(entry, index_value)"
>
<li
id=
"htmlchapter-${index_value}"
>
<a
class=
"chapter"
>
${entry.get('title')}
</a>
</li>
</
%
def>
%for (index, entry) in enumerate(textbook['chapters']):
${print_entry(entry, index+1)}
% endfor
</ul>
</section>
%endif
<section
id=
"viewerContainer"
class=
"book"
>
<section
class=
"page"
>
<div
id=
"bookpage"
/>
</section>
</section>
</div>
</div>
lms/urls.py
View file @
0605c941
...
...
@@ -280,6 +280,15 @@ if settings.COURSEWARE_ENABLED:
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/pdfbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<page>[^/]*)$'
,
'staticbook.views.pdf_index'
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/$'
,
'staticbook.views.html_index'
,
name
=
"html_book"
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/$'
,
'staticbook.views.html_index'
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/chapter/(?P<chapter>[^/]*)/(?P<anchor_id>[^/]*)/$'
,
'staticbook.views.html_index'
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/htmlbook/(?P<book_index>[^/]*)/(?P<anchor_id>[^/]*)/$'
,
'staticbook.views.html_index'
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/?$'
,
'courseware.views.index'
,
name
=
"courseware"
),
url
(
r'^courses/(?P<course_id>[^/]+/[^/]+/[^/]+)/courseware/(?P<chapter>[^/]*)/$'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment