Extended the README, removed BASEURL, used keyword arguments for templates in the application rather than a context dictionary.

main
Gijs 2 years ago
parent 9ec312bdec
commit 42a0f9dbc0

@ -1,84 +1,249 @@
# # Pagedjs Flask boilerplate / recipe
The boilerplate uses the python framework flask to run the webinterface and to generate the HTML of the book. To generate the PDF it uses the javascript library pagedjs together with the chromium webbrowser in headless mode. The boilerplate uses the python framework [Flask](https://palletsprojects.com/p/flask/) to run the webinterface and to generate the HTML of the book. To generate the PDF it uses the javascript library [paged.js](https://pagedjs.org/) together with the chromium webbrowser in headless mode.
# Installation The
First [download](https://gitlab.constantvzw.org/anais_berck/pagedjs-flask-boilerplate/-/archive/main/pagedjs-flask-boilerplate-main.zip) it on gitlab. ## Index
Or clone the repository: - [Installation](#installation)
- [Contents of the boilerplate](#contents-of-the-boilerplate)
- [Usage](#usage)
- [Deployment](#deployment)
- [Furter reading](#further-reading)
`git clone git@gitlab.constantvzw.org:anais_berck/pagedjs-flask-boilerplate.git` ## Installation
This boilerplate uses Python 3 and the framework [Flask](https://palletsprojects.com/p/flask/). > This installation guide assumes a basic understanding of the shell or terminal. If you are not familiar with it there are many [introduction tutorials](https://www.digitalocean.com/community/tutorials/an-introduction-to-the-linux-terminal) online. During the summerschool relearn this [short introduction](http://relearn.be/2013/r/cheat-sheet::git-and-the-command-line.html) was written.
Find information on how to [install python here](https://www.python.org/downloads/) ### Getting the boilerplate
To install the requirements, move to the directory this readme is located in, and then run. Optionally create a virtual environment: The easiest way to get this boilerplate is to [download](https://gitlab.constantvzw.org/anais_berck/pagedjs-flask-boilerplate/-/archive/main/pagedjs-flask-boilerplate-main.zip) a copy of it on gitlab.
`pip install -r requirements.txt` You can also clone the repository using git. Make sure you execute the command in the folder where you want to place the boilerplate:
Then install [pagedjs-cli](https://gitlab.coko.foundation/pagedjs/pagedjs-cli), with the command: ```bash
git clone git@gitlab.constantvzw.org:anais_berck/pagedjs-flask-boilerplate.git
```
`npm install -g pagedjs-cli`
___ in case pagedjs-cli does not show up, follow these instructions: ### Python3
check the version of node (this should be: v16.17.0) The boilerplate uses Python 3. If you know you have it installed this step can be skipped. If you are not sure it's installed on your computer, run the following command in the terminal:
'$ node --version'
check if nvm is installed ```bash
'$ nvm' python3 --version
```
if nvm does not show up, install nvm with the following command: It should output the version number of the copy of Python you have installed, something like:
'$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash'
copy the following code into the terminal: ```
'export NVM_DIR="$HOME/.nvm" 3.10.7
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm ```
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion'
install the latest version of nvm: If the terminal instead prints something like:
'$ nvm install --lts'
check the version of node (this should be: v16.17.0) ```
'$ node --version' Command 'python3' not found...
```
now install paged.js: It is most likely Python isn't installed. You can [download it, and find installation instructions here](https://www.python.org/downloads/).
$ npm install -g pagedjs-cli
check if it is installed: ### Flask
$ whereis pagedjs-cli
> It is advised to install Flask in a virtual environment, how to use and install them isn't covered here. Please find more information on virtual environments in the [Python documentation](https://docs.python.org/3/tutorial/venv.html)
Extensive installation instructions for Flask can be found [here](https://flask.palletsprojects.com/en/latest/installation/), but it is easiest to install it with the python package manager (pip), with the command:
```bash
pip3 install flask
```
### Node
Pagedjs-cli uses `node.js`, and it is installed with the node pakacge manager `npm` if you know you have installed a (recent) version of `node.js` and `npm`, you can skip this step. First check `npm` is installed using the command:
```bash
npm --version
```
It should output the version number of the copy of npm you have installed, something like:
```
8.15.1
```
If the terminal instead prints something like:
```
Command 'npm' not found...
```
It is most likely npm (and node) arent't installed. There are several ways on how to do it. The easiest is with nvm, the [node virtual manage](https://github.com/nvm-sh/nvm). You can find extensive instructions on it [here](https://github.com/nvm-sh/nvm#installing-and-updating). But it can be installed with the following command, it downloads and executes the install script:
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
```
Then, to avoid having to restart your terminal, run:
```bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```
Then install the latest Long Term Support release of node and npm:
```bash
nvm install --lts
```
### pagedjs-cli
Finally install [pagedjs-cli](https://gitlab.coko.foundation/pagedjs/pagedjs-cli), with the command:
```bash
npm install -g pagedjs-cli
```
It is quite likely you'll get some warning messages during installation. This doesn't mean it failed though!
To verify `pagedjs-cli` was correctly installed, run:
```bash
pagedjs-cli --help
```
This should print out the usage instructions. When it produces an error it is quite likely your version of `node` and or `npm` was too old. In the [previous step](#node) you'll find instructions on how to install a more recent version of `node` using `nvm`.
### Starting the boilerplate
Now that all the pieces are in place you can start the boilerplate by running:
```bash
./run.sh
```
This command should start the Flask application. If you open a browser and load the url: <http://localhost:5000> you should see the index of the boiler plate. When you click the link 'generate' a PDF-file should be downloaded 🤞.
<!--
### in case pagedjs-cli does not show up, follow these instructions:
check the version of node (this should be: v16.17.0)
```sh
node --version
```
check if nvm is installed
```bash
nvm
```
if nvm does not show up, install nvm with the following command:
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
```
copy the following code into the terminal:
'export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion'
install the latest version of nvm:
```bash
nvm install --lts'
```
check the version of node (this should be: v16.17.0)
```bash
node --version'
```
now install paged.js:
```bash
npm install -g pagedjs-cli
```
check if it is installed:
```bash
whereis pagedjs-cli
```
add this path to settings.py add this path to settings.py
/home/ana/.nvm/versions/node/v16.17.0/bin/pagedjs-cli /home/ana/.nvm/versions/node/v16.17.0/bin/pagedjs-cli
Finally edit a copy of `settings.example.py` and save it as `settings.py`. Finally edit a copy of `settings.example.py` and save it as `settings.py`.
It is important to set the `PAGEDJS_BINARY_PATH`, you should be able to find it It is important to set the `PAGEDJS_BINARY_PATH`, you should be able to find it
by running: `whereis pagedjs-cli`. by running: `whereis pagedjs-cli`. -->
Now you should be able to start the interface with: `./run.sh`.
# Contents of the boilerplate ## Contents of the boilerplate
- `app.py` the flask webapp, generating the views - `app.py` the flask webapp, generating the views
- `pagedjs.py` helper functions to run pagedjs-cli from python - `pagedjs.py` helper functions to run pagedjs-cli from python
- `utils.py` utitilities for generative books - `utils.py` utitilities for generative books
- `templates/index.html` template for the index - `templates/index.html` jinja template for the index
- `templates/book.html` template for the book itself - `templates/book.html` jinja template for the book itself
- `static/style.css` css style rules for the index and book (it's possible to split them up, also adjust the templates then) - `static/style.css` css style rules for the index and book (it's possible to split them up, also adjust the templates then)
- `static/pagedjs.interface.css` css style rules provided by paged.js to have a more rich preview in debug mode - `static/pagedjs.interface.css` css style rules provided by paged.js to have a more rich preview in debug mode
# Usage
The boilerplate essentially has two views: `index` and `generate`. The `index` shows the homepage and a link to the `generate` function. In this example the generated book is downloaded as a PDF. ## Usage
### Running the boilerplate
The boilerplate can be started with the bash script `run.sh`. This script starts the application in development mode. Which is practical during development as it reloads whenever it detects a change to the code.
### Debug mode
The boilerplate has a debug mode. In debug mode the generate function doesn't generate a PDF but instead returns an HTML preview with the help of paged.js. This should be slightly quicker, but also allows to inspect the generated HTML. Activate the debug mode by setting the `DEBUG` variable in `settings.py` to `True`:
```python
DEBUG = True
```
### Adjusting the boilerplate
The boilerplate uses a Flask app to generate the html for the index and book, the code of the application is in the file `app.py`. You can find more information on Flask [here](https://flask.palletsprojects.com/en/2.2.x/quickstart/). Summarised very shortly, Flask is a light frame work for web applications. Flask applications are written in python, these applcations consist of functions generating HTML using the [`route()` decorator](https://flask.palletsprojects.com/en/2.2.x/quickstart/#routing) these functions are linked to a url, in `app.py` the index is defined like so:
```python
@app.route('/')
def index():
return render_template('index.html')
```
On line 1 of this snippet the url is defined, and on line 3 the html is generated and returned to the browser of the visitor. Flask uses the [Jinja](https://jinja.palletsprojects.com/en/3.1.x/) templating engine. You can find extensive documentation on it [here](https://jinja.palletsprojects.com/en/3.1.x/templates/).
The application has two views, defined by similarly named functions: `index` and `generate`. The function `index` generates and shows the homepage. The function `generate` generates the HTML book. You can insert the code for your book in this function.
The application uses Jinja templates to generate the HTML of the book. It is advised to generate your data in the application and to then use this data in the template to generate the HTML. The data can be forwarded to the tempate by extending the `render_template` call in the python script using keyword arguments. Where you define the name of the argument before the equal sign, and assign the value after it:
```python
generated_data = function_call()
html = render_template('book.html', DEBUG=DEBUG, generated_data=generated_data)
```
The variable will be available in the template under the name that you set before the equal sign (=):
```jinja
<section>
{{ generated_data }}
</section>
```
It is possible to generate HTML in the python script and to forward this HTML as a variable to the template, it is important though to mark it in the template as a snippet of HTML that shouldn't be escaped. You do this with the `safe` filter:
```jinja
{{ variable_containing_html|safe }}
```
The template `templates/book.html` is used with for the book, the template `templates/index.html` is used for the index-page of the application. The styles are set in `static/style.css`.
The template `templates/book.html` is used with styles from `static/style.css` to generate the PDF, adjust them to adjust your book. In `app.py` the function generate loads the template, adjust that function to generate context and / or HTML. ## Deployment
In the [documentation of paged.js](https://pagedjs.org/documentation/) a lot of information on print specific functionality in CSS can be found. To do: instructions on how to install it on a server and make it publicly accessible. It should be noted this boilerplate does not make any effort at rate-limiting.
# Deployment ## Further reading
Todo
Note: this boilerplate does not make any effort at rate-limiting. - In the [documentation of paged.js](https://pagedjs.org/documentation/) a lot of information on print specific functionality in CSS can be found.
- [Jinja documentation](https://jinja.palletsprojects.com/en/3.1.x/templates/)
- [Flask documentation](https://flask.palletsprojects.com/en/2.2.x/)

@ -2,7 +2,7 @@ from flask import Flask, render_template, Response, abort, url_for
# from weasyprint import HTML # from weasyprint import HTML
import os import os
from pagedjs import make_pdf_from_url from pagedjs import make_pdf_from_url
from settings import BASEURL, DEBUG, HTML_TMP_DIR, SITEURL from settings import DEBUG, HTML_TMP_DIR, SITEURL
import tempfile import tempfile
from werkzeug.security import safe_join from werkzeug.security import safe_join
@ -11,10 +11,9 @@ app = Flask(__name__)
""" """
Shows the index page of the application Shows the index page of the application
""" """
@app.route('{}/'.format(BASEURL)) @app.route('/')
def index(): def index():
context = {} return render_template('index.html')
return render_template('index.html', **context)
""" """
@ -22,13 +21,18 @@ def index():
Possibly adjust the allowed methods. Possibly adjust the allowed methods.
""" """
@app.route('{}/generate'.format(BASEURL), methods=['GET', 'POST']) @app.route('/generate', methods=['GET', 'POST'])
def generate (): def generate ():
context = {
'DEBUG': DEBUG
}
html = render_template('book.html', **context) """
Insert your own Python code in this function.
"""
# Rendering of the template. Forward generated data to the template
# using named arguments, for example, if a variable chapters was generated
# you can add it to the function like so:
# html = render_template('book.html', DEBUG=DEBUG, chapters=chapters)
html = render_template('book.html', DEBUG=DEBUG)
if (DEBUG): if (DEBUG):
return html return html
@ -69,7 +73,7 @@ def make_pdf (html):
""" """
View for pagedjs. It loads the generated HTML from the tmp dir and returns it. View for pagedjs. It loads the generated HTML from the tmp dir and returns it.
""" """
@app.route('{}/book/<string:bookname>'.format(BASEURL)) @app.route('/book/<string:bookname>')
def show_book (bookname): def show_book (bookname):
bookpath = safe_join(HTML_TMP_DIR, bookname) bookpath = safe_join(HTML_TMP_DIR, bookname)

@ -6,9 +6,6 @@ DEBUG = False
# When set to true, the application doesn't generate a PDF, # When set to true, the application doesn't generate a PDF,
# but uses the pagedjs-polyfill to show a preview of the document # but uses the pagedjs-polyfill to show a preview of the document
SITEURL = 'http://localhost:5000' SITEURL = 'http://localhost:5000'
# The url pagedjs-cli tries to connect to, to retrieve the HTML of
# the book, default if the default url of the Flask development server
BASEURL = ''
# Baseurl on the server. For now only in devployment # Baseurl on the server. For now only in devployment
HTML_TMP_DIR = '/tmp/publishing_house/' HTML_TMP_DIR = '/tmp/publishing_house/'
# Location where the temporary html files are stored # Location where the temporary html files are stored

Loading…
Cancel
Save