You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: extras/css.md
+12-13Lines changed: 12 additions & 13 deletions
Original file line number
Diff line number
Diff line change
@@ -17,11 +17,10 @@ CSS Frameworks make it easier to manage styles for these larger, more complicate
17
17
18
18
Here is an example of a two-column layout:
19
19
20
-
21
-
<div class="row">
22
-
<div class="column-3">Left sidebar</div>
23
-
<div class="column-9">Main content</div>
24
-
</div>
20
+
<div class="row">
21
+
<div class="column-3">Left sidebar</div>
22
+
<div class="column-9">Main content</div>
23
+
</div>
25
24
26
25
**Typographical reset**. This is a font reset that looks a little more pleasing to the eye. It sets things like line spacing and font size.
27
26
@@ -46,18 +45,18 @@ There are in fact a few entire languages that are dedicated to CSS. These langua
46
45
47
46
A common problem is how to deal with colours. For example if you had a corporate colour scheme of `#3311FF` your CSS would be littered with `#3311FF` references:
48
47
49
-
.nav { background-color: #3311FF; }
50
-
.button { border-color: #3311FF; }
51
-
.cake .icing { color: #3311FF; }
48
+
.nav { background-color: #3311FF; }
49
+
.button { border-color: #3311FF; }
50
+
.cake .icing { color: #3311FF; }
52
51
53
52
In a CSS language you would be able to use a variable instead:
54
53
55
-
$corporate_color: #3311FF;
56
-
.nav { background-color: $corporate_color; }
57
-
.button { border-color: $corporate_color; }
58
-
.cake .icing { color: $corporate_color; }
54
+
$corporate_color: #3311FF;
55
+
.nav { background-color: $corporate_color; }
56
+
.button { border-color: $corporate_color; }
57
+
.cake .icing { color: $corporate_color; }
59
58
60
-
Use of a CSS language is very common in large websites these days. Here are some of the more popular ones in use today:
59
+
And if you later decided that the colour needed to be #3311EE instead, there would only be one place you needed to change it! Use of a CSS language is very common in large websites these days. Here are some of the more popular ones in use today:
61
60
62
61
*[SASS](http://sass-lang.com/) is one of the original CSS languages. It uses the Ruby programming language under the hood. You might like to try the [Python](https://pypi.python.org/pypi/pyScss/1.1.5) port which is compatible with SASS 3.2. You can also take a look at [Compass](http://compass-style.org/) which pushes SASS even further.
63
62
*[LESS](http://lesscss.org/) has a very similar philosophy. It is written in JavaScript, so it can either be run in the browser or, using Node, on the server.
Copy file name to clipboardExpand all lines: extras/databases.md
+22-22Lines changed: 22 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -5,22 +5,22 @@ title: Databases
5
5
6
6
There is a reason why we haven't used a more permanent method for storing our email addresses, and that's because _databases are complicated_. Seriously.
7
7
8
-
But fortunately they are not that difficult once you get the hang of it. Since the 1970s many databases have standardised on using the **SQL** language. It defines how to store and search data in _tables_, which contain _columns_. If you learn SQL then you can use quite a lot of different databases.
8
+
But fortunately they are not that difficult once you get the hang of it. Since the 1970s many databases have standardised on using the **SQL** language. It defines how to store and search data in _tables_, which contain _columns_, and rows of data usually referred to as _records_. If you learn SQL then you can use quite a lot of different databases.
9
9
10
-
Because of their size and complexity databases are generally written as their own separate servers that run in addition to your web server. That comes with additional work that we probably don't need at this moment. For now we'll use [SQLite](http://www.sqlite.org/) which is a very widely used database engine that just happens to come bundled in Python.
10
+
Because of their size and complexity databases are generally written as their own separate servers that run in addition to your web server. That comes with additional work that we probably don't need at this moment. For now we'll use [SQLite](http://www.sqlite.org/) which is a simple and very widely used database engine that just happens to come bundled in Python.
11
11
12
12
## Creating the database
13
13
14
14
Since Python 2.5 the SQLite library has shipped in the standard distribution. This means it should be available already. You can import the `sqlite3` library in a Python shell to see if it works:
15
15
16
-
>>> import sqlite3
16
+
>>> import sqlite3
17
17
18
18
We are going to start by creating a database in a file called `emails.db`. It will have one table called `email_addresses` which will keep all our emails. Make sure your Python shell started in the same directory as your website code.
19
19
20
-
>>> conn = sqlite3.connect("emails.db")
21
-
>>> cursor = conn.cursor()
22
-
>>> cursor.execute("CREATE TABLE email_addresses ( email TEXT );")
23
-
<sqlite3.Cursor object at 0xb7467ce0>
20
+
>>> conn = sqlite3.connect("emails.db")
21
+
>>> cursor = conn.cursor()
22
+
>>> cursor.execute("CREATE TABLE email_addresses ( email TEXT );")
23
+
<sqlite3.Cursor object at 0xb7467ce0>
24
24
25
25
Here you can see we connected to `emails.db` (this file didn't exist, so SQLite created it). We opened a _cursor_, which is what allows us to send commands, and executed a _CREATE TABLE_ statement to create the email addresses table. It has one column, _email_, which can just be a string of text.
26
26
@@ -30,21 +30,21 @@ The Flask documentation has a [section](http://flask.pocoo.org/docs/patterns/sql
30
30
31
31
We'll need to import the `g` object from Flask, as well as `sqlite3`:
32
32
33
-
from flask import g
34
-
import sqlite3
33
+
from flask import g
34
+
import sqlite3
35
35
36
36
Now we use `@app.before_request` to run a function before every request from the browser:
37
37
38
-
@app.before_request
39
-
def before_request():
40
-
g.db = sqlite3.connect("emails.db")
38
+
@app.before_request
39
+
def before_request():
40
+
g.db = sqlite3.connect("emails.db")
41
41
42
42
Likewise we use `@app.teardown_request` to close the database connection after every request.
43
43
44
-
@app.teardown_request
45
-
def teardown_request(exception):
46
-
if hasattr(g, 'db'):
47
-
g.db.close()
44
+
@app.teardown_request
45
+
def teardown_request(exception):
46
+
if hasattr(g, 'db'):
47
+
g.db.close()
48
48
49
49
## Adding a new email address
50
50
@@ -65,15 +65,15 @@ Now that we have all our emails stored in a database we have to use a _SELECT_ s
65
65
66
66
@app.route('/emails.html')
67
67
def emails():
68
-
email_addresses = g.db.execute("SELECT email FROM email_addresses").fetchall()
You might notice that the list of emails now looks a little strange on the web page. This is because the `g.db.execute()` statement returns an entire tuple for _every_ email address. In the Python console it looks like this:
72
72
73
-
>>> db.execute('select * from email_addresses').fetchall()
So every email is actually a list. The email itself is at position 0 in the list. So update the emails template to use position 0:
76
+
So every item in the list is actually a tuple (a non-modifiable list). The email itself is at position 0 in each tuple. So update the emails template to print just the first element:
77
77
78
78
{% raw %}
79
79
@@ -85,7 +85,7 @@ So every email is actually a list. The email itself is at position 0 in the list
85
85
86
86
{% endraw %}
87
87
88
-
And that's it! You can now restart the web server as many times as you like! All the emails are now stored directly in the database.
88
+
And that's it! You can now restart the web server as many times as you like, and your list of emails will remain! All the emails are now stored directly in the database.
Copy file name to clipboardExpand all lines: extras/sessions.md
+5-1Lines changed: 5 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,7 @@ It sure does, and they're very simple to use. Firstly, **add `session` as anothe
21
21
22
22
Then you need to give flask a secret key to use, to make sure the session is secure. To get a nice secret key, **run this at a command prompt**:
23
23
24
-
python -c "import os; print repr(os.urandom(24))"
24
+
python -c "import os; print repr(os.urandom(24))"
25
25
26
26
and copy the string you get. To set this as the flask app's secret key, just **add the following line** after you initialize your `app` (use your own key!):
27
27
@@ -69,4 +69,8 @@ Here, we use a few `if` checks to make sure that our user added an email address
69
69
70
70
* Allow the app to remember when a user has already registered their email, and not show them an email input form when they have (maybe say Thanks! for signing up). Check out the [Jinja2 template documentation](http://jinja.pocoo.org/docs/templates/) if you'd like to use a little template logic to help with this. You could change the above button so that it also only shows after registering an email.
71
71
72
+
Extra points:
73
+
72
74
* Add a "protected" page which allows you to delete any email address, and a very simple admin login system (with just a single password) to access it. You can use a session to determine whether someone is currently logged in or not. This might be a little more difficult, but any challengers are welcome to try it out! You can check out the code sample [here](http://flask.pocoo.org/docs/quickstart/#sessions) for some hints on how to go about that.
75
+
76
+
* Integrate these features into using your databases as needed
0 commit comments