Commit 1831ab4e by Calen Pennington

Merge remote-tracking branch 'origin/master' into asset-pipeline

Conflicts:
	envs/dev.py
	sass/README
	static/css
	static/css/application.css
	static/css/marketing-ie.css
	static/css/marketing.css
parents b80d1904 3632f6a7
source :rubygems
gem 'guard', '~> 1.0.3'
gem 'guard-process', '~> 1.0.3'
gem 'guard-coffeescript', '~> 0.6.0'
gem 'sass', '3.1.15'
gem 'guard-sass', :github => 'sikachu/guard-sass'
gem 'bourbon', '~> 1.3.6'
gem 'libnotify', '~> 0.7.2'
gem 'ruby_gntp', '~> 0.3.4'
GIT
remote: git://github.com/sikachu/guard-sass.git
revision: 2a646996d7fdaa2fabf5f65ba700bd8b02f14c1b
specs:
guard-sass (0.6.0)
guard (>= 0.4.0)
sass (>= 3.1)
GEM
remote: http://rubygems.org/
specs:
bourbon (1.3.6)
sass (>= 3.1)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.3.3)
execjs (1.3.2)
multi_json (~> 1.0)
ffi (1.0.11)
guard (1.0.3)
ffi (>= 0.5.0)
thor (>= 0.14.6)
guard-coffeescript (0.6.0)
coffee-script (>= 2.2.0)
guard (>= 0.8.3)
guard-process (1.0.3)
ffi (~> 1.0.9)
guard (>= 0.4.2)
spoon (~> 0.0.1)
libnotify (0.7.2)
multi_json (1.3.5)
ruby_gntp (0.3.4)
sass (3.1.15)
spoon (0.0.1)
thor (0.15.2)
PLATFORMS
ruby
DEPENDENCIES
bourbon (~> 1.3.6)
guard (~> 1.0.3)
guard-coffeescript (~> 0.6.0)
guard-process (~> 1.0.3)
guard-sass!
libnotify (~> 0.7.2)
ruby_gntp (~> 0.3.4)
sass (= 3.1.15)
require 'bourbon'
# Helper method
def production?
@@options[:group].include? 'production'
end
guard :coffeescript, :name => :jasmine, :input => 'templates/coffee/spec', :all_on_start => production?
guard :coffeescript, :input => 'templates/coffee/src', :noop => true
guard :process, :name => :coffeescript, :command => "coffee -j static/js/application.js -c templates/coffee/src" do
watch(%r{^templates/coffee/src/(.+)\.coffee$})
end
if production?
guard :sass, :input => 'templates/sass', :output => 'static/css', :style => :compressed, :all_on_start => true
else
guard :sass, :input => 'templates/sass', :output => 'static/css', :style => :nested, :line_numbers => true
end
import logging import logging
import urllib import urllib
import json
from django.conf import settings from django.conf import settings
from django.core.context_processors import csrf from django.core.context_processors import csrf
...@@ -16,6 +17,8 @@ from lxml import etree ...@@ -16,6 +17,8 @@ from lxml import etree
from module_render import render_module, make_track_function, I4xSystem from module_render import render_module, make_track_function, I4xSystem
from models import StudentModule from models import StudentModule
from student.models import UserProfile from student.models import UserProfile
from util.errors import record_exception
from util.views import accepts
from multicourse import multicourse_settings from multicourse import multicourse_settings
import courseware.content_parser as content_parser import courseware.content_parser as content_parser
...@@ -110,12 +113,16 @@ def render_section(request, section): ...@@ -110,12 +113,16 @@ def render_section(request, section):
if 'coursename' in request.session: coursename = request.session['coursename'] if 'coursename' in request.session: coursename = request.session['coursename']
else: coursename = None else: coursename = None
# try: try:
dom = content_parser.section_file(user, section, coursename) dom = content_parser.section_file(user, section, coursename)
#except: except:
# raise Http404 record_exception(log, "Unable to parse courseware xml")
return render_to_response('courseware-error.html', {})
accordion=render_accordion(request, '', '', '') context = {
'csrf': csrf(request)['csrf_token'],
'accordion': render_accordion(request, '', '', '')
}
module_ids = dom.xpath("//@id") module_ids = dom.xpath("//@id")
...@@ -125,15 +132,20 @@ def render_section(request, section): ...@@ -125,15 +132,20 @@ def render_section(request, section):
else: else:
module_object_preload = [] module_object_preload = []
module=render_module(user, request, dom, module_object_preload) try:
module = render_module(user, request, dom, module_object_preload)
if 'init_js' not in module: except:
module['init_js']='' record_exception(log, "Unable to load module")
context.update({
context={'init':module['init_js'], 'init': '',
'accordion':accordion, 'content': render_to_string("module-error.html", {}),
'content':module['content'], })
'csrf':csrf(request)['csrf_token']} return render_to_response('courseware.html', context)
context.update({
'init':module.get('init_js', ''),
'content':module['content'],
})
result = render_to_response('courseware.html', context) result = render_to_response('courseware.html', context)
return result return result
...@@ -167,22 +179,22 @@ def index(request, course=None, chapter="Using the System", section="Hints"): ...@@ -167,22 +179,22 @@ def index(request, course=None, chapter="Using the System", section="Hints"):
if not multicourse_settings.is_valid_course(course): if not multicourse_settings.is_valid_course(course):
return redirect('/') return redirect('/')
#import logging
#log = logging.getLogger("mitx")
#log.info( "DEBUG: "+str(user) )
request.session['coursename'] = course # keep track of current course being viewed in django's request.session request.session['coursename'] = course # keep track of current course being viewed in django's request.session
dom = content_parser.course_file(user,course) # also pass course to it, for course-specific XML path try:
dom = content_parser.course_file(user,course) # also pass course to it, for course-specific XML path
except:
record_exception(log, "Unable to parse courseware xml")
return render_to_response('courseware-error.html', {})
dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]", dom_module = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]/*[1]",
course=course, chapter=chapter, section=section) course=course, chapter=chapter, section=section)
if len(dom_module) == 0: if len(dom_module) == 0:
module = None module = None
else: else:
module = dom_module[0] module = dom_module[0]
accordion=render_accordion(request, course, chapter, section)
module_ids = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]//@id", module_ids = dom.xpath("//course[@name=$course]/chapter[@name=$chapter]//section[@name=$section]//@id",
course=course, chapter=chapter, section=section) course=course, chapter=chapter, section=section)
...@@ -191,18 +203,27 @@ def index(request, course=None, chapter="Using the System", section="Hints"): ...@@ -191,18 +203,27 @@ def index(request, course=None, chapter="Using the System", section="Hints"):
module_id__in=module_ids)) module_id__in=module_ids))
else: else:
module_object_preload = [] module_object_preload = []
module=render_module(user, request, module, module_object_preload)
if 'init_js' not in module: context = {
module['init_js']='' 'csrf': csrf(request)['csrf_token'],
'accordion': render_accordion(request, course, chapter, section),
context={'init':module['init_js'], 'COURSE_TITLE':multicourse_settings.get_course_title(course),
'accordion':accordion, }
'content':module['content'],
'COURSE_TITLE':multicourse_settings.get_course_title(course), try:
'csrf':csrf(request)['csrf_token']} module = render_module(user, request, module, module_object_preload)
except:
record_exception(log, "Unable to load module")
context.update({
'init': '',
'content': render_to_string("module-error.html", {}),
})
return render_to_response('courseware.html', context)
context.update({
'init': module.get('init_js', ''),
'content': module['content'],
})
result = render_to_response('courseware.html', context) result = render_to_response('courseware.html', context)
return result return result
...@@ -234,7 +255,15 @@ def modx_dispatch(request, module=None, dispatch=None, id=None): ...@@ -234,7 +255,15 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
else: coursename = None else: coursename = None
# Grab the XML corresponding to the request from course.xml # Grab the XML corresponding to the request from course.xml
xml = content_parser.module_xml(request.user, module, 'id', id, coursename) try:
xml = content_parser.module_xml(request.user, module, 'id', id, coursename)
except:
record_exception(log, "Unable to load module during ajax call")
if accepts(request, 'text/html'):
return render_to_response("module-error.html", {})
else:
response = HttpResponse(json.dumps({'success': "We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible"}))
return response
# Create the module # Create the module
system = I4xSystem(track_function = make_track_function(request), system = I4xSystem(track_function = make_track_function(request),
...@@ -242,10 +271,20 @@ def modx_dispatch(request, module=None, dispatch=None, id=None): ...@@ -242,10 +271,20 @@ def modx_dispatch(request, module=None, dispatch=None, id=None):
ajax_url = ajax_url, ajax_url = ajax_url,
filestore = None filestore = None
) )
instance=courseware.modules.get_module_class(module)(system,
xml, try:
id, instance=courseware.modules.get_module_class(module)(system,
state=oldstate) xml,
id,
state=oldstate)
except:
record_exception(log, "Unable to load module instance during ajax call")
if accepts(request, 'text/html'):
return render_to_response("module-error.html", {})
else:
response = HttpResponse(json.dumps({'success': "We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible"}))
return response
# Let the module handle the AJAX # Let the module handle the AJAX
ajax_return=instance.handle_ajax(dispatch, request.POST) ajax_return=instance.handle_ajax(dispatch, request.POST)
# Save the state back to the database # Save the state back to the database
......
...@@ -79,6 +79,7 @@ TEMPLATE_DIRS = ( ...@@ -79,6 +79,7 @@ TEMPLATE_DIRS = (
TEMPLATE_CONTEXT_PROCESSORS = ( TEMPLATE_CONTEXT_PROCESSORS = (
'django.core.context_processors.request', 'django.core.context_processors.request',
'django.core.context_processors.static',
'askbot.context.application_settings', 'askbot.context.application_settings',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
#'django.core.context_processors.i18n', #'django.core.context_processors.i18n',
...@@ -105,6 +106,20 @@ DEV_CONTENT = True ...@@ -105,6 +106,20 @@ DEV_CONTENT = True
TRACK_MAX_EVENT = 10000 TRACK_MAX_EVENT = 10000
DEBUG_TRACK_LOG = False DEBUG_TRACK_LOG = False
MITX_ROOT_URL = ''
COURSE_NAME = "6.002_Spring_2012"
COURSE_NUMBER = "6.002x"
COURSE_TITLE = "Circuits and Electronics"
ROOT_URLCONF = 'urls'
### Dark code. Should be enabled in local settings for devel.
ENABLE_MULTICOURSE = False # set to False to disable multicourse display (see lib.util.views.mitxhome)
###
############################### DJANGO BUILT-INS ############################### ############################### DJANGO BUILT-INS ###############################
# Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here # Change DEBUG/TEMPLATE_DEBUG in your environment settings files, not here
DEBUG = False DEBUG = False
...@@ -162,14 +177,22 @@ MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage' ...@@ -162,14 +177,22 @@ MESSAGE_STORAGE = 'django.contrib.messages.storage.session.SessionStorage'
AWS_QUERYSTRING_EXPIRE = 10 * 365 * 24 * 60 * 60 # 10 years AWS_QUERYSTRING_EXPIRE = 10 * 365 * 24 * 60 * 60 # 10 years
################################### ASKBOT ##################################### ################################### ASKBOT #####################################
LIVESETTINGS_OPTIONS['MITX_ROOT_URL'] = MITX_ROOT_URL
skin_settings = LIVESETTINGS_OPTIONS[1]['SETTINGS']['GENERAL_SKIN_SETTINGS']
skin_settings['SITE_FAVICON'] = unicode(MITX_ROOT_URL) + skin_settings['SITE_FAVICON']
skin_settings['SITE_LOGO_URL'] = unicode(MITX_ROOT_URL) + skin_settings['SITE_LOGO_URL']
skin_settings['LOCAL_LOGIN_ICON'] = unicode(MITX_ROOT_URL) + skin_settings['LOCAL_LOGIN_ICON']
LIVESETTINGS_OPTIONS[1]['SETTINGS']['LOGIN_PROVIDERS']['WORDPRESS_SITE_ICON'] = unicode(MITX_ROOT_URL) + LIVESETTINGS_OPTIONS[1]['SETTINGS']['LOGIN_PROVIDERS']['WORDPRESS_SITE_ICON']
LIVESETTINGS_OPTIONS[1]['SETTINGS']['LICENSE_SETTINGS']['LICENSE_LOGO_URL'] = unicode(MITX_ROOT_URL) + LIVESETTINGS_OPTIONS[1]['SETTINGS']['LICENSE_SETTINGS']['LICENSE_LOGO_URL']
ASKBOT_EXTRA_SKINS_DIR = ASKBOT_ROOT / "askbot" / "skins" ASKBOT_EXTRA_SKINS_DIR = ASKBOT_ROOT / "askbot" / "skins"
ASKBOT_ALLOWED_UPLOAD_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff') ASKBOT_ALLOWED_UPLOAD_FILE_TYPES = ('.jpg', '.jpeg', '.gif', '.bmp', '.png', '.tiff')
ASKBOT_MAX_UPLOAD_FILE_SIZE = 1024 * 1024 # result in bytes ASKBOT_MAX_UPLOAD_FILE_SIZE = 1024 * 1024 # result in bytes
CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True CACHE_MIDDLEWARE_ANONYMOUS_ONLY = True
ASKBOT_URL = 'discussion/' ASKBOT_URL = 'discussion/'
LOGIN_REDIRECT_URL = '/' LOGIN_REDIRECT_URL = MITX_ROOT_URL + '/'
LOGIN_URL = '/' LOGIN_URL = MITX_ROOT_URL + '/'
ALLOW_UNICODE_SLUGS = False ALLOW_UNICODE_SLUGS = False
ASKBOT_USE_STACKEXCHANGE_URLS = False # mimic url scheme of stackexchange ASKBOT_USE_STACKEXCHANGE_URLS = False # mimic url scheme of stackexchange
...@@ -184,6 +207,9 @@ djcelery.setup_loader() ...@@ -184,6 +207,9 @@ djcelery.setup_loader()
SIMPLE_WIKI_REQUIRE_LOGIN_EDIT = True SIMPLE_WIKI_REQUIRE_LOGIN_EDIT = True
SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False SIMPLE_WIKI_REQUIRE_LOGIN_VIEW = False
################################# Jasmine ###################################
JASMINE_TEST_DIRECTORY = PROJECT_ROOT + '/templates/coffee'
################################# Middleware ################################### ################################# Middleware ###################################
# List of finder classes that know how to find static files in # List of finder classes that know how to find static files in
# various locations. # various locations.
...@@ -202,6 +228,7 @@ TEMPLATE_LOADERS = ( ...@@ -202,6 +228,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'util.middleware.ExceptionLoggingMiddleware', 'util.middleware.ExceptionLoggingMiddleware',
'util.middleware.AcceptMiddleware',
'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
...@@ -289,6 +316,9 @@ INSTALLED_APPS = ( ...@@ -289,6 +316,9 @@ INSTALLED_APPS = (
'track', 'track',
'util', 'util',
# For testing
'django_jasmine',
# For Askbot # For Askbot
'django.contrib.sitemaps', 'django.contrib.sitemaps',
'django.contrib.admin', 'django.contrib.admin',
......
import newrelic.agent
import sys
def record_exception(logger, msg, params={}, ignore_errors=[]):
logger.exception(msg)
newrelic.agent.record_exception(*sys.exc_info())
...@@ -13,3 +13,4 @@ class ExceptionLoggingMiddleware(object): ...@@ -13,3 +13,4 @@ class ExceptionLoggingMiddleware(object):
def process_exception(self, request, exception): def process_exception(self, request, exception):
log.exception(exception) log.exception(exception)
return HttpResponseServerError("Server Error - Please try again later.") return HttpResponseServerError("Server Error - Please try again later.")
...@@ -66,3 +66,29 @@ def mitxhome(request): ...@@ -66,3 +66,29 @@ def mitxhome(request):
if settings.ENABLE_MULTICOURSE: if settings.ENABLE_MULTICOURSE:
return render_to_response("mitxhome.html", {}) return render_to_response("mitxhome.html", {})
return info(request) return info(request)
# From http://djangosnippets.org/snippets/1042/
def parse_accept_header(accept):
"""Parse the Accept header *accept*, returning a list with pairs of
(media_type, q_value), ordered by q values.
"""
result = []
for media_range in accept.split(","):
parts = media_range.split(";")
media_type = parts.pop(0)
media_params = []
q = 1.0
for part in parts:
(key, value) = part.lstrip().split("=", 1)
if key == "q":
q = float(value)
else:
media_params.append((key, value))
result.append((media_type, tuple(media_params), q))
result.sort(lambda x, y: -cmp(x[2], y[2]))
return result
def accepts(request, media_type):
"""Return whether this request has an Accept header that matches type"""
accept = parse_accept_header(request.META.get("HTTP_ACCEPT", ""))
return media_type in [t for (t, p, q) in accept]
This project is using Sass to generate it's CSS. Sass is a CSS preprocessor that allows for faster development of CSS. For more information about sass: http://sass-lang.com
To use sass all you need to do is enter:
$ gem install sass
We are also using Bourbon with sass. They are a generic set of mixins, and functions that allow for more rapid development of CSS3. Find out more about bourbon here: https://github.com/thoughtbot/bourbon
To use bourbon you need to install it with:
$ gem install bourbon
Then to generate Sass files cd to templates directory and watch the sass files for development:
$ sass --watch sass:../static/css/ -r ./sass/bourbon/lib/bourbon.rb
To generate a compressed css file for production:
$ sass --watch sass:../static/css/ -r ./sass/bourbon/lib/bourbon.rb --style :compressed
These will automatically generate the CSS files on save.
...@@ -124,10 +124,8 @@ h1.top-header { ...@@ -124,10 +124,8 @@ h1.top-header {
} }
h3 { h3 {
@extend .bottom-border;
background: none; background: none;
border: none; border: none;
border-bottom: 1px solid #d3d3d3;
color: #000; color: #000;
font-weight: normal; font-weight: normal;
margin: 0; margin: 0;
...@@ -140,11 +138,6 @@ h1.top-header { ...@@ -140,11 +138,6 @@ h1.top-header {
padding: 7px 7px 7px 30px; padding: 7px 7px 7px 30px;
text-decoration: none; text-decoration: none;
@include transition(); @include transition();
&:hover {
background: #efefef;
@include box-shadow(0 1px 0 #fff);
}
} }
span.ui-icon { span.ui-icon {
...@@ -153,9 +146,9 @@ h1.top-header { ...@@ -153,9 +146,9 @@ h1.top-header {
&.active { &.active {
background: none; background: none;
border: 0; @include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225)));
border-bottom: 1px solid #bbb; border-bottom: 1px solid #d3d3d3;
@include box-shadow(none); @include box-shadow(inset 0 1px 0 0 #eee);
color: #000; color: #000;
font-weight: bold; font-weight: bold;
......
...@@ -5,11 +5,17 @@ section.course-index { ...@@ -5,11 +5,17 @@ section.course-index {
div#accordion { div#accordion {
h3 { h3 {
@include box-shadow(inset 0 1px 0 0 #eee);
border-top: 1px solid #d3d3d3;
overflow: hidden; overflow: hidden;
margin: 0; margin: 0;
&:last-child { &:first-child {
@include box-shadow(none); border: none;
}
&:hover {
@include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225)));
} }
&.ui-accordion-header { &.ui-accordion-header {
...@@ -20,14 +26,10 @@ section.course-index { ...@@ -20,14 +26,10 @@ section.course-index {
color: lighten($text-color, 10%); color: lighten($text-color, 10%);
} }
&.ui-state-hover {
border: none;
border-bottom: 1px solid #d3d3d3;
}
&.ui-state-active { &.ui-state-active {
@include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225))); @include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225)));
@extend .active; @extend .active;
border-bottom: 1px solid #d3d3d3;
} }
} }
} }
...@@ -37,7 +39,6 @@ section.course-index { ...@@ -37,7 +39,6 @@ section.course-index {
@include box-shadow(inset -1px 0 0 #e6e6e6); @include box-shadow(inset -1px 0 0 #e6e6e6);
background: #dadada; background: #dadada;
border: none; border: none;
border-bottom: 1px solid #c3c3c3;
font-size: 12px; font-size: 12px;
margin: 0; margin: 0;
padding: 1em 1.5em; padding: 1em 1.5em;
......
...@@ -333,7 +333,7 @@ ...@@ -333,7 +333,7 @@
.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }
.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } .ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }
.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }
.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }
.ui-accordion .ui-accordion-content-active { display: block; } .ui-accordion .ui-accordion-content-active { display: block; }
/* /*
* jQuery UI Autocomplete 1.8.16 * jQuery UI Autocomplete 1.8.16
...@@ -565,4 +565,4 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad ...@@ -565,4 +565,4 @@ button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra pad
* http://docs.jquery.com/UI/Progressbar#theming * http://docs.jquery.com/UI/Progressbar#theming
*/ */
.ui-progressbar { height:2em; text-align: left; } .ui-progressbar { height:2em; text-align: left; }
.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
\ No newline at end of file
...@@ -10,27 +10,35 @@ div#wiki_panel { ...@@ -10,27 +10,35 @@ div#wiki_panel {
} }
input[type="button"] { input[type="button"] {
@extend h3; background: transparent;
color: lighten($text-color, 10%); border: none;
font-size: $body-font-size; @include box-shadow(none);
margin: 0 !important; color: #666;
font-size: 14px;
font-weight: bold;
margin: 0px;
padding: 7px lh(); padding: 7px lh();
text-align: left; text-align: left;
@include transition(); @include transition();
width: 100%; width: 100%;
&:hover {
@include box-shadow(0 1px 0 #fff);
background: #efefef;
}
} }
ul { ul {
li { li {
@include box-shadow(inset 0 1px 0 0 #eee);
border-top: 1px solid #d3d3d3;
&:hover {
background: #efefef;
@include background-image(linear-gradient(-90deg, rgb(245,245,245), rgb(225,225,225)));
}
&:first-child {
border: none;
}
&.search { &.search {
border-bottom: 1px solid #d3d3d3; padding: 10px lh();
@include box-shadow(0 1px 0 #eee);
padding: 7px lh();
label { label {
display: none; display: none;
...@@ -39,18 +47,21 @@ div#wiki_panel { ...@@ -39,18 +47,21 @@ div#wiki_panel {
&.create-article { &.create-article {
h3 { h3 {
a {
padding: 7px lh();
}
} }
} }
a {
color: #666;
font-size: 14px;
padding: 7px lh();
}
} }
} }
div#wiki_create_form { div#wiki_create_form {
@extend .clearfix; @extend .clearfix;
background: #d6d6d6; background: #dadada;
border-bottom: 1px solid #bbb; border-bottom: 1px solid #d3d3d3;
padding: 15px; padding: 15px;
input[type="text"] { input[type="text"] {
......
...@@ -133,6 +133,7 @@ TEMPLATE_LOADERS = ( ...@@ -133,6 +133,7 @@ TEMPLATE_LOADERS = (
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
'util.middleware.ExceptionLoggingMiddleware', 'util.middleware.ExceptionLoggingMiddleware',
'util.middleware.AcceptMiddleware',
'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
......
<h3><a href="#">Using the System</a></h3>
<div>
<ul>
<li> Lecture
<li> Homework
<li> Lab
</ul>
</div>
<h3><a href="#">Basic Circuit Analysis</a></h3>
<div>
<ul>
<li> Electronic Text
<li> Introduction <br><small>lecture, 50min, due Feb 1</small>
<li> KVL, KCL, and Resistive <br><small>lecture, 50min, due Feb 3</small>
<li> Nodal analysis <br><small>lecture, 50min, due Feb 5</small>
<li> <div style="background-color:#aed0ea;">Linearity, Superposition <br><small>lecture, 50min, due Feb 7</small></div>
<li> Homework 1 <br><small>due Feb 14</small>
<li> Lab 0 <br><small>due Feb 7</small>
</ul>
</div>
<h3><a href="#">Digital Systems</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
<h3><a href="#">Nonlinear Elements</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
<h3><a href="#">Analog Amplification</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
<h3><a href="#">Capacitors and Inductors</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
<h3><a href="#">Operational Amplifiers</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
<h3><a href="#">Applications</a></h3>
<div>
<!--ul>
<li> Lecture
<li> Homework
<li> Lab
</ul-->
</div>
...@@ -15,9 +15,9 @@ npm (Node Package Manager) to be able to install the CoffeeScript compiler. ...@@ -15,9 +15,9 @@ npm (Node Package Manager) to be able to install the CoffeeScript compiler.
Install Node via Homebrew, then use npm: Install Node via Homebrew, then use npm:
brew install node $ brew install node
curl http://npmjs.org/install.sh | sh $ curl http://npmjs.org/install.sh | sh
npm install -g git://github.com/jashkenas/coffee-script.git $ npm install -g git://github.com/jashkenas/coffee-script.git
(Note that we're using the edge version of CoffeeScript for now, as there was (Note that we're using the edge version of CoffeeScript for now, as there was
some issue with directory watching in 1.3.1.) some issue with directory watching in 1.3.1.)
...@@ -28,32 +28,26 @@ Try to run `coffee` and make sure you get a coffee prompt. ...@@ -28,32 +28,26 @@ Try to run `coffee` and make sure you get a coffee prompt.
Conveniently, you can install Node via `apt-get`, then use npm: Conveniently, you can install Node via `apt-get`, then use npm:
sudo apt-get install nodejs npm && $ sudo apt-get install nodejs npm &&
sudo npm install -g git://github.com/jashkenas/coffee-script.git $ sudo npm install -g git://github.com/jashkenas/coffee-script.git
Compiling Compiling
--------- ---------
Run this command in the `mitx` directory to easily make the compiler watch for We're using Guard to watch your folder and automatic compile those CoffeeScript
changes in your file, and join the result into `application.js`: files. First, install guard by using Bundler:
coffee -j static/js/application.js -cw templates/coffee/src $ gem install bundler
$ bundle install
Please note that the compiler will not be able to detect the file that get added Then you can run this command:
after you've ran the command, so you'll need to restart the compiler if there's
a new CoffeeScript file. $ bundle exec guard
Testing Testing
======= -------
We're also using Jasmine to unit-testing the JavaScript files. All the specs are We're also using Jasmine to unit-testing the JavaScript files. All the specs are
written in CoffeeScript for the consistency. Because of the limitation of written in CoffeeScript for the consistency. To access the test cases, start the
`django-jasmine` plugin, we'll need to also running another compiler to compile server in debug mode, navigate to http://127.0.0.1:8000/_jasmine to see the
the test file. test result.
Using this command to compile the test files:
coffee -cw templates/coffee/spec/*.coffee
Then start the server in debug mode, navigate to http://127.0.0.1:8000/_jasmine
to see the test result.
// Generated by CoffeeScript 1.3.2-pre
(function() { (function() {
describe('Calculator', function() { describe('Calculator', function() {
......
// Generated by CoffeeScript 1.3.2-pre
(function() { (function() {
describe('Courseware', function() { describe('Courseware', function() {
......
// Generated by CoffeeScript 1.3.2-pre
(function() { (function() {
describe('FeedbackForm', function() { describe('FeedbackForm', function() {
......
// Generated by CoffeeScript 1.3.2-pre
(function() { (function() {
jasmine.getFixtures().fixturesPath = "/_jasmine/fixtures/"; jasmine.getFixtures().fixturesPath = "/_jasmine/fixtures/";
......
<%inherit file="main.html" />
<%block name="bodyclass">courseware</%block>
<%block name="title"><title>Courseware – MITx 6.002x</title></%block>
<%include file="navigation.html" args="active_page='courseware'" />
<section class="main-content">
<section class="outside-app">
<h1>There has been an error on the <em>MITx</em> servers</h1>
<p>We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p>
</section>
</section>
<section class="outside-app">
<h1>There has been an error on the <em>MITx</em> servers</h1>
<p>We're sorry, this module is temporarily unavailable. Our staff is working to fix it as soon as possible. Please email us at <a href="mailto:technical@mitx.mit.edu">technical@mitx.mit.edu</a> to report any problems or downtime.</p>
</section>
SASS
====
This project is using Sass to generate its CSS. Sass is a CSS preprocessor that
allows for faster development of CSS. For more information about sass:
http://sass-lang.com
Install SASS
------------
To use sass, make sure that you have RubyGems install, then you can use Bundler:
$ gem install bundler
$ bundle install
This should ensure that you have all the dependencies required for compiling.
Compiling
---------
We're using Guard to watch your folder and automatic compile those SASS files.
If you already install all the dependencies using Bundler, you can just do:
$ bundle exec guard
This will generate the sass file for development which some debugging
information.
### Before Commit
Since this compiled style you're going to push are going to be used on live
production site, you're encouraged to compress all of the style to save some
bandwidth. You can do that by run this command:
$ bundle exec guard -g production
Guard will watch your directory and generated a compressed version of CSS.
...@@ -84,9 +84,11 @@ ...@@ -84,9 +84,11 @@
%> %>
<ul class="action"> <ul class="action">
<li> <li>
<input type="button" onclick="javascript:location.href='${reverse("wiki_list_articles", args=[])}'" value="All articles" class="button" /> <h3>
<a href="${reverse("wiki_list_articles", args=[])}">All Articles</a>
</h3>
</li> </li>
<li class="create-article"> <li class="create-article">
<h3> <h3>
<a href="#" id="create-article"/>Create Article</a> <a href="#" id="create-article"/>Create Article</a>
......
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