Skip to content

46 document how to do frontend bootstrap styling in customization docs #88

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ __pycache__
_docs/
.pytest_cache/
.mypy_cache/
.cursorrules
node_modules
package-lock.json
package.json
.specstory
.cursorrules
97 changes: 97 additions & 0 deletions docs/customization.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ We have also exposed the full Markdown-formatted project documentation as a [sin
- Organization management endpoints: `organization.py`
- Role management endpoints: `role.py`
- Jinja2 templates: `templates/`
- Bootstrap Sass Files: `scss/`
- Static assets: `static/`
- Unit tests: `tests/`
- Test database configuration: `docker-compose.yml`
Expand Down Expand Up @@ -116,6 +117,101 @@ To generate the HTML pages to be returned from our GET routes, we use Jinja2 tem

With Jinja2, we can use the `{% block %}` tag to define content blocks, and the `{% extends %}` tag to extend a base template. We can also use the `{% include %}` tag to include a component in a parent template. See the [Jinja2 documentation on template inheritance](https://jinja.palletsprojects.com/en/stable/templates/#template-inheritance) for more details.

### Custom theming with Bootstrap Sass

[Install Node.js](https://nodejs.org/en/download/) on your local machine if it is not there already.

Install `bootstrap`, `sass`, `gulp`, and `gulp-sass` in your project:

```bash
npm install --save-dev bootstrap sass gulp gulp-cli gulp-sass
```

This will create a `node_modules` folder, a `package-lock.json` file, and a `package.json` file in the root directory of the project.

Create an `scss` folder and a basic `scss/styles.scss` file:

```bash
mkdir scss
touch scss/styles.scss
```

Your custom styles will go in `scss/styles.scss`, along with `@import` statements to include the Bootstrap components you want. For example, the default CSS for the template was compiled from the following configuration, which imports all of Bootstrap and overrides the `$theme-colors` and `$font-family-base` variables:

```scss
// styles.scss

// Include any default variable overrides here (functions won't be available)

// State colors
$primary: #7464a1;
$secondary: #64a19d;
$success: #67c29c;
$info: #1cabc4;
$warning: #e4c662;
$danger: #a16468;
$light: #f8f9fa;
$dark: #343a40;

// Bootstrap color map
$theme-colors: (
"primary": $primary,
"secondary": $secondary,
"success": $success,
"info": $info,
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
);

$font-family-base: (
"Nunito",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif,
"Apple Color Emoji",
"Segoe UI Emoji",
"Segoe UI Symbol",
"Noto Color Emoji"
);

// Include all of Bootstrap

@import "../node_modules/bootstrap/scss/bootstrap";
```

The most common use case for `styles.scss` is to define a custom color scheme and fonts, but it's also possible to other visual details such as border radius and box shadow depth. See the [Bootstrap Sass customization instructions](https://getbootstrap.com/docs/5.3/customize/sass/) and the many free templates available at [Start Bootstrap](https://startbootstrap.com) for examples.

To compile the Sass files, we use `gulp`. In the project root directory, create a `gulpfile.js` file with the following content:

```javascript
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));

// Define a task to compile Sass
gulp.task('sass', function() {
return gulp.src('scss/**/*.scss') // Source folder containing Sass files
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('static/css')); // Destination folder for compiled CSS
});

// Define a default task
gulp.task('default', gulp.series('sass'));
```

To compile the Sass file to `static/css`, run this command:

```bash
npx gulp
```

Note that this will overwrite the existing `static/css/styles.css` file, so if you want to define any custom CSS styles, you should do so in either the `scss/styles.scss` file or in `static/css/extras.css`.

#### Context variables

Context refers to Python variables passed to a template to populate the HTML. In a FastAPI GET route, we can pass context to a template using the `templates.TemplateResponse` method, which takes the request and any context data as arguments. For example:
Expand All @@ -136,6 +232,7 @@ In this example, the `welcome.html` template will receive two pieces of context:
While this template includes comprehensive server-side validation through Pydantic models and custom validators, it's important to note that server-side validation should be treated as a fallback security measure. If users ever see the `validation_error.html` template, it indicates that our client-side validation has failed to catch invalid input before it reaches the server.

Best practices dictate implementing thorough client-side validation via JavaScript and/or HTML `input` element `pattern` attributes to:

- Provide immediate feedback to users
- Reduce server load
- Improve user experience by avoiding round-trips to the server
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ If you use VSCode with Docker to develop in a container, the following VSCode De
{
"name": "Python 3",
"image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm",
"postCreateCommand": "sudo apt update && sudo apt install -y python3-dev libpq-dev graphviz libwebp-dev && uv venv && uv sync",
"postCreateCommand": "sudo apt update && sudo apt install -y python3-dev libpq-dev graphviz libwebp-dev && npm install [email protected] && npm install -g sass && npm install -g gulp && uv venv && uv sync",
"features": {
"ghcr.io/va-h/devcontainers-features/uv:1": {
"version": "latest"
Expand Down
File renamed without changes.
Loading