Large update on colors and fonts in SCSS and templates
The different elements in the templates are now properly styled using Flexbox and colors. The H1 heading has received a nice update that makes it stand out like it's supposed to.
The header and footer can now be colored in a different color than UHasselt default with a special context item, main_color. This is easily seen with the different courses.
The font used for H1 has been changed to the Ubuntu font; this is the same font used by UHasselt for some visual elements in their style, even though, this is mentioned nowhere.
- Author
- Maarten 'Vngngdn' Vangeneugden
- Date
- April 15, 2018, 5:47 p.m.
- Hash
- a7ed4858a91d073026a4ad7eff4f6d31de25e572
- Parent
- 3b1bea45175455d37fa5e39b6fa0119d32b30d32
- Modified files
- courses/templates/courses/index.djhtml
- courses/views.py
- joeni/templates/joeni/base.djhtml
- static/css/_variables.scss
- static/css/classes.scss
- static/css/footer.scss
- static/css/global.scss
- static/css/header.scss
- static/css/main.scss
- static/css/stylesheet.scss
courses/templates/courses/index.djhtml ¶
7 additions and 11 deletions.
View changes Hide changes
1 |
1 |
{% load i18n %} |
2 |
2 |
|
3 |
3 |
{% block title %} |
4 |
4 |
{#{% trans "◀ Joeni /▶ | Courses" %}#} |
5 |
5 |
{% trans "Courses" %} | {{ block.super }} |
6 |
6 |
{% endblock %} |
7 |
7 |
|
8 |
8 |
{% block main %} |
9 |
9 |
<h1>{% trans "Your courses" %}</h1> |
10 |
10 |
<!--<ul> |
11 |
- | {% for course in courses %} |
12 |
- | <div style="background-color: {{ course.color }}"> |
13 |
- | |
14 |
- | <li> |
15 |
- | <a href="{% url 'courses-course-index' course_slug=course.slug_name %}"> |
16 |
- | {{ course }} |
17 |
- | </a> |
18 |
- | </li> |
19 |
- | {% endfor %} |
20 |
- | </ul> |
21 |
- | {% endblock main %} |
+ |
11 |
{% for course in courses %} |
+ |
12 |
<a class="flex-items" style="background-color: #{{ course.color }};" flex-wrapper" href="{% url 'courses-course-index' course_slug=course.slug_name %}"> |
+ |
13 |
{{ course }}<br /> |
+ |
14 |
</a> |
+ |
15 |
{% endfor %} |
+ |
16 |
</div> |
+ |
17 |
{% endblock main %} |
22 |
18 |
courses/views.py ¶
1 addition and 0 deletions.
View changes Hide changes
1 |
1 |
import datetime |
2 |
2 |
from django.urls import reverse # Why? |
3 |
3 |
from django.utils.translation import gettext as _ |
4 |
4 |
from .models import * |
5 |
5 |
from .forms import * |
6 |
6 |
import administration |
7 |
7 |
from django.contrib.auth.decorators import login_required |
8 |
8 |
from joeni.constants import current_academic_year |
9 |
9 |
|
10 |
10 |
@login_required |
11 |
11 |
def index(request): |
12 |
12 |
""" Starting page regarding the courses. This serves two specific groups: |
13 |
13 |
- Students: Displays all courses that this student has in his/her curriculum |
14 |
14 |
for this academic year. Requires the curriculum to be accepted. |
15 |
15 |
- Staff: Displays all courses in which the staff member is part of the |
16 |
16 |
educating team, or is otherwise related to the course. |
17 |
17 |
Users who are not logged in will be sent to the login page. |
18 |
18 |
""" |
19 |
19 |
template = "courses/index.djhtml" |
20 |
20 |
courses = request.user.user_data.current_courses() |
21 |
21 |
|
22 |
22 |
context = { |
23 |
23 |
'courses': courses, |
24 |
24 |
} |
25 |
25 |
|
26 |
26 |
return render(request, template, context) |
27 |
27 |
|
28 |
28 |
@login_required |
29 |
29 |
def course(request, course_slug): |
30 |
30 |
template = "courses/course.djhtml" |
31 |
31 |
course = Course.objects.get(slug_name=course_slug) |
32 |
32 |
|
33 |
33 |
# Check if user can see this page |
34 |
34 |
if request.user.user_data.is_student: |
35 |
35 |
if course not in request.user.user_data.current_courses(): |
36 |
36 |
""" I'm currently just redirecting to the index page, but maybe it's |
37 |
37 |
just as good to make an announcement that this course cannot be |
38 |
38 |
used by this user. """ |
39 |
39 |
return index(request) |
40 |
40 |
|
41 |
41 |
context = { |
42 |
42 |
'course': course, |
43 |
43 |
'announcements': Announcement.objects.filter(course=course), |
+ |
44 |
'announcements': Announcement.objects.filter(course=course), |
44 |
45 |
'assignments': Assignment.objects.filter(course=course), |
45 |
46 |
'course-items': CourseItem.objects.filter(course=course), |
46 |
47 |
'study-groups': StudyGroup.objects.filter(course=course), |
47 |
48 |
'uploads': Upload.objects.filter(course=course).filter(student=request.user) |
48 |
49 |
} |
49 |
50 |
if request.user.user_data.is_student: |
50 |
51 |
context['upload_form'] = UploadForm() |
51 |
52 |
|
52 |
53 |
return render(request, template, context) |
53 |
54 |
|
54 |
55 |
# TODO: Find a way to see if it's possible to require some permissions and to |
55 |
56 |
# put them in a decorator |
56 |
57 |
#@permission_required |
57 |
58 |
@login_required |
58 |
59 |
def new_item(request, course_slug): |
59 |
60 |
template = "courses/new_item.djhtml" |
60 |
61 |
course = Course.objects.get(slug_name=course_slug) |
61 |
62 |
|
62 |
63 |
if request.user.user_data.is_student or request.user not in course.course_team: |
63 |
64 |
# Students can't add new items. Redirect to index |
64 |
65 |
# Also redirect people who are not part of the course team |
65 |
66 |
redirect('courses-index') |
66 |
67 |
# Now able to assume user is allowed to add items to this course |
67 |
68 |
|
68 |
69 |
context = { |
69 |
70 |
'course': course, |
70 |
71 |
'announcements': Announcement.objects.filter(course=course), |
71 |
72 |
'assignments': Assignment.objects.filter(course=course), |
72 |
73 |
'course-items': CourseItem.objects.filter(course=course), |
73 |
74 |
'study-groups': StudyGroup.objects.filter(course=course), |
74 |
75 |
'uploads': Upload.objects.filter(course=course) |
75 |
76 |
} |
76 |
77 |
|
77 |
78 |
return render(request, template, context) |
78 |
79 |
|
79 |
80 |
@login_required |
80 |
81 |
def edit_course_items(request, course_slug): |
81 |
82 |
# TODO Only allow people on the course team to this page! |
82 |
83 |
template = "courses/edit_course_items.djhtml" |
83 |
84 |
context = dict() |
84 |
85 |
course_ = Course.objects.get(slug_name=course_slug) |
85 |
86 |
if request.method == 'POST': |
86 |
87 |
assignments = AssignmentFormSet(request.POST, prefix='assignments') |
87 |
88 |
announcements = AnnouncementFormSet(request.POST, prefix='announcements') |
88 |
89 |
course_items = CourseItemFormSet(request.POST, request.FILES, prefix='course_items') |
89 |
90 |
if assignments.is_valid() and announcements.is_valid() and course_items.is_valid(): |
90 |
91 |
assignments.save(commit=False) |
91 |
92 |
announcements.save(commit=False) |
92 |
93 |
course_items.save(commit=False) |
93 |
94 |
for new_assignment in assignments.new_objects: |
94 |
95 |
new_assignment.course = course_ |
95 |
96 |
for new_announcement in announcements.new_objects: |
96 |
97 |
new_announcement.course = course_ |
97 |
98 |
for new_course_item in course_items.new_objects: |
98 |
99 |
new_coutse_item.course = course_ |
99 |
100 |
assignments.save() |
100 |
101 |
announcements.save() |
101 |
102 |
course_items.save() |
102 |
103 |
return course(request, course_slug) |
103 |
104 |
else: |
104 |
105 |
assignments = AssignmentFormSet( |
105 |
106 |
queryset=Assignment.objects.filter(course=course_), |
106 |
107 |
prefix="assignments", |
107 |
108 |
) |
108 |
109 |
announcements = AnnouncementFormSet( |
109 |
110 |
queryset=Announcement.objects.filter(course=course_), |
110 |
111 |
prefix="announcements", |
111 |
112 |
) |
112 |
113 |
course_items = CourseItemFormSet( |
113 |
114 |
queryset=CourseItem.objects.filter(course=course_), |
114 |
115 |
prefix="course_items", |
115 |
116 |
) |
116 |
117 |
context['assignments'] = assignments |
117 |
118 |
context['announcements'] = announcements |
118 |
119 |
context['course_items'] = course_items |
119 |
120 |
return render(request, template, context) |
120 |
121 |
|
121 |
122 |
|
122 |
123 |
@login_required |
123 |
124 |
def remove(request, type, id): |
124 |
125 |
pass |
125 |
126 |
|
126 |
127 |
@login_required |
127 |
128 |
def upload(request): |
128 |
129 |
pass |
129 |
130 |
|
130 |
131 |
@login_required |
131 |
132 |
def groups(request): |
132 |
133 |
pass |
133 |
134 |
|
134 |
135 |
def fiche(request, course_slug): |
135 |
136 |
"""Displays the fiche for the given course. Includes information about all |
136 |
137 |
course programs.""" |
137 |
138 |
template = "courses/fiche.djhtml" |
138 |
139 |
context = dict() |
139 |
140 |
course = Course.objects.get(slug_name=course_slug) |
140 |
141 |
|
141 |
142 |
joeni/templates/joeni/base.djhtml ¶
9 additions and 0 deletions.
View changes Hide changes
1 |
1 |
{% load i18n %} |
2 |
2 |
{% get_current_language as LANGUAGE_CODE %} |
3 |
3 |
{% get_language_info for LANGUAGE_CODE as lang %} |
4 |
4 |
{% load static %} |
5 |
5 |
{% get_media_prefix as media %} |
6 |
6 |
|
7 |
7 |
<!DOCTYPE html> |
8 |
8 |
<html lang="{{ lang.code }}"> |
9 |
9 |
<head> |
10 |
10 |
<title> |
11 |
11 |
{% block title %} |
12 |
12 |
{#◀ Joeni /▶ | ▶▶ UHasselt#} |
13 |
13 |
▶▶ UHasselt |
14 |
14 |
{% endblock title %} |
15 |
15 |
</title> |
16 |
16 |
|
17 |
17 |
{% block stylesheets %} |
18 |
18 |
{% comment %}<link href="{% static "css/header.css" %}" rel="stylesheet" media="screen, projection" /> |
19 |
19 |
<link href="{% static "css/footer.css" %}" rel="stylesheet" media="screen, projection" /> |
20 |
20 |
<link href="{% static "css/base.css" %}" rel="stylesheet" media="screen, projection" /> |
21 |
21 |
{% endcomment %} |
22 |
22 |
<link href="{% static "css/stylesheet.css" %}" rel="stylesheet" media="screen, projection" /> |
23 |
23 |
<style type="text/css"> |
24 |
24 |
header, footer { |
25 |
25 |
background-color: #{{ user.account.settings.color|default:"UHASSELT" }}; |
26 |
26 |
} |
27 |
27 |
</style> |
28 |
28 |
{% endblock stylesheets %} |
29 |
29 |
|
30 |
30 |
{% block metaflags %} |
31 |
31 |
{# This is standard for all web pages and doesn't require changing. #} |
32 |
32 |
{# UTF-8, always #} |
33 |
33 |
<meta charset="utf-8" /> |
34 |
34 |
{#<meta name="author" content="Maarten Vangeneugden">#} |
35 |
35 |
{# Indicates this page is suited for mobile devices #} |
36 |
36 |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
37 |
37 |
<meta |
38 |
38 |
name="description" |
39 |
39 |
content="{% block description %} |
40 |
40 |
{% trans "The digital platform of Hasselt University" %} |
41 |
41 |
{% endblock description %}" /> |
42 |
42 |
{% endblock metaflags %} |
43 |
43 |
</head> |
+ |
44 |
h1 { |
+ |
45 |
color: #{{ main_color|default:"E73B2B" }}; |
+ |
46 |
text-decoration-color: #{{ main_color|default:"E73B2B" }}; |
+ |
47 |
} |
+ |
48 |
header, footer { |
+ |
49 |
background-color: #{{ main_color|default:"E73B2B" }}; |
+ |
50 |
} |
+ |
51 |
</style> |
+ |
52 |
</head> |
44 |
53 |
|
45 |
54 |
<body> |
46 |
55 |
<header> |
47 |
56 |
{% block header %} |
48 |
57 |
{% include "joeni/header.djhtml" %} |
49 |
58 |
{% endblock header %} |
50 |
59 |
</header> |
51 |
60 |
|
52 |
61 |
<main> |
53 |
62 |
{% block main %} |
54 |
63 |
{% endblock main %} |
55 |
64 |
</main> |
56 |
65 |
|
57 |
66 |
<footer> |
58 |
67 |
{% block footer %} |
59 |
68 |
{% include "joeni/footer.djhtml" %} |
60 |
69 |
{% endblock footer %} |
61 |
70 |
</footer> |
62 |
71 |
|
63 |
72 |
</body> |
64 |
73 |
{% block JavaScript %} |
65 |
74 |
{% comment "JavaScript" %} |
66 |
75 |
My website does not require JavaScript for basic actions. However, it may be |
67 |
76 |
used to make certain things look better, or to spice up some actions for the |
68 |
77 |
user. Should it be necessary, add the appropriate JavaScript code in this |
69 |
78 |
block. |
70 |
79 |
The reason this block is at the bottom? |
71 |
80 |
Remember to always put JavaScript on the bottom to reduce load time. |
72 |
81 |
Otherwise it just errors like a fucktard, which is really the only thing |
73 |
82 |
you can always expect from JavaScript. |
74 |
83 |
{% endcomment %} |
75 |
84 |
{% endblock JavaScript %} |
76 |
85 |
</html> |
77 |
86 |
static/css/_variables.scss ¶
48 additions and 0 deletions.
View changes Hide changes
+ |
1 |
$uhasselt-color: #E73B2B; |
+ |
2 |
$fos-color: #0076BE; |
+ |
3 |
$fots-color: #C0D633; |
+ |
4 |
$foaaa-color: #F4802D; |
+ |
5 |
$fobe-color: #00ACEE; |
+ |
6 |
$fomals-color: #9C3591; |
+ |
7 |
$foet-color: #5BC4BA; |
+ |
8 |
$fol-color: #E41F3A; |
+ |
9 |
|
+ |
10 |
$colors: ( |
+ |
11 |
"uhasselt": $uhasselt-color, |
+ |
12 |
"fos": $fos-color, |
+ |
13 |
"fots": $fots-color, |
+ |
14 |
"foaaa": $foaaa-color, |
+ |
15 |
"fobe": $fobe-color, |
+ |
16 |
"fomals": $fomals-color, |
+ |
17 |
"foet": $foet-color, |
+ |
18 |
"fol": $fol-color, |
+ |
19 |
); |
+ |
20 |
|
+ |
21 |
@each $color_name, $color_value in $colors { |
+ |
22 |
.#{$color_name} { |
+ |
23 |
background-color: $color_value; |
+ |
24 |
} |
+ |
25 |
.#{$color_name}-text { |
+ |
26 |
color: $color_value; |
+ |
27 |
} |
+ |
28 |
} |
+ |
29 |
|
+ |
30 |
|
+ |
31 |
// SIZING |
+ |
32 |
$small-screen-up: 601px !default; |
+ |
33 |
$medium-screen-up: 993px !default; |
+ |
34 |
$large-screen-up: 1201px !default; |
+ |
35 |
$small-screen: 600px !default; |
+ |
36 |
$medium-screen: 992px !default; |
+ |
37 |
$large-screen: 1200px !default; |
+ |
38 |
|
+ |
39 |
$medium-and-up: "only screen and (min-width : #{$small-screen-up})" !default; |
+ |
40 |
$large-and-up: "only screen and (min-width : #{$medium-screen-up})" !default; |
+ |
41 |
$extra-large-and-up: "only screen and (min-width : #{$large-screen-up})" !default; |
+ |
42 |
$small-and-down: "only screen and (max-width : #{$small-screen})" !default; |
+ |
43 |
$medium-and-down: "only screen and (max-width : #{$medium-screen})" !default; |
+ |
44 |
$medium-only: "only screen and (min-width : #{$small-screen-up}) and (max-width : #{$medium-screen})" !default; |
+ |
45 |
|
+ |
46 |
$header-padding: 1%; |
+ |
47 |
$header-width: 20%; |
+ |
48 |
static/css/classes.scss ¶
25 additions and 0 deletions.
View changes Hide changes
+ |
1 |
div.flex-container { |
+ |
2 |
display: flex; |
+ |
3 |
flex-direction: row; |
+ |
4 |
flex-wrap: wrap; |
+ |
5 |
justify-content: space-between; // Not too sure about this one, experiment if you want to |
+ |
6 |
align-items: stretch; |
+ |
7 |
//align-content: space-around; |
+ |
8 |
} |
+ |
9 |
|
+ |
10 |
.flex-items { |
+ |
11 |
color: white; |
+ |
12 |
font-family: ubuntu; |
+ |
13 |
text-decoration: none; |
+ |
14 |
flex-grow: 1; |
+ |
15 |
margin: .2em; |
+ |
16 |
text-decoration-style: none; |
+ |
17 |
padding: 1em; |
+ |
18 |
|
+ |
19 |
&:hover { |
+ |
20 |
text-decoration: underline solid white; |
+ |
21 |
color: red; |
+ |
22 |
} |
+ |
23 |
} |
+ |
24 |
|
+ |
25 |
static/css/footer.scss ¶
12 additions and 0 deletions.
static/css/global.scss ¶
11 additions and 0 deletions.
static/css/header.scss ¶
33 additions and 0 deletions.
View changes Hide changes
+ |
1 |
float: left; |
+ |
2 |
margin-right: 50px; |
+ |
3 |
position: fixed; |
+ |
4 |
//display: flow; |
+ |
5 |
//height: 100%; |
+ |
6 |
padding: $header-padding; |
+ |
7 |
top: 0; |
+ |
8 |
width: $header-width; |
+ |
9 |
height: 100%; |
+ |
10 |
//background-color: $uhasselt-color; |
+ |
11 |
color: white; |
+ |
12 |
img { |
+ |
13 |
height: 5em; |
+ |
14 |
} |
+ |
15 |
nav ul { |
+ |
16 |
//list-style: none; |
+ |
17 |
list-style: none; |
+ |
18 |
} |
+ |
19 |
a { |
+ |
20 |
text-decoration: none; |
+ |
21 |
color: white; |
+ |
22 |
&:hover { |
+ |
23 |
text-decoration: underline solid white; |
+ |
24 |
text-transform: uppercase; |
+ |
25 |
font-weight: bold; |
+ |
26 |
} |
+ |
27 |
} |
+ |
28 |
} |
+ |
29 |
/*header ul { |
+ |
30 |
display: inline; |
+ |
31 |
float: right; |
+ |
32 |
}*/ |
+ |
33 |
static/css/main.scss ¶
10 additions and 0 deletions.
static/css/stylesheet.scss ¶
10 additions and 0 deletions.
View changes Hide changes
+ |
1 |
by using sassc, put in one single file, stylesheet.css. However, that may not be |
+ |
2 |
what you want when using HTTP/2. In that case, edit the scripts and templates |
+ |
3 |
accordingly. */ |
+ |
4 |
@import 'variables'; |
+ |
5 |
@import 'classes.scss'; |
+ |
6 |
@import 'global.scss'; |
+ |
7 |
@import 'header.scss'; |
+ |
8 |
@import 'main.scss'; |
+ |
9 |
@import 'footer.scss'; |
+ |
10 |