0
# Configuration and Customization
1
2
Comprehensive configuration system for controlling build behavior, file handling, error processing, and output customization. Frozen-Flask automatically sets sensible defaults on your Flask application's configuration.
3
4
## Configuration Options
5
6
All configuration options are set on the Flask app's `config` object and prefixed with `FREEZER_`.
7
8
### Build Output
9
10
Control where and how static files are generated.
11
12
```python { .api }
13
# Build destination directory (relative to app.root_path)
14
app.config['FREEZER_DESTINATION'] = 'build' # default
15
16
# Files to ignore in destination directory
17
app.config['FREEZER_DESTINATION_IGNORE'] = [] # default
18
19
# Remove files from previous build not in current build
20
app.config['FREEZER_REMOVE_EXTRA_FILES'] = True # default
21
```
22
23
### URL and Path Handling
24
25
Configuration for URL generation and path processing.
26
27
```python { .api }
28
# Base URL for the site (affects url_for calls)
29
app.config['FREEZER_BASE_URL'] = None # default
30
31
# Use relative URLs in templates
32
app.config['FREEZER_RELATIVE_URLS'] = False # default
33
```
34
35
### Static File Processing
36
37
Control static file discovery and processing.
38
39
```python { .api }
40
# Static files to ignore during freezing
41
app.config['FREEZER_STATIC_IGNORE'] = [] # default
42
```
43
44
### MIME Type Handling
45
46
Configuration for content type processing and validation.
47
48
```python { .api }
49
# Default MIME type for files with unknown extensions
50
app.config['FREEZER_DEFAULT_MIMETYPE'] = 'application/octet-stream' # default
51
52
# Skip MIME type mismatch warnings
53
app.config['FREEZER_IGNORE_MIMETYPE_WARNINGS'] = False # default
54
```
55
56
### Error Handling
57
58
Control how errors and edge cases are processed.
59
60
```python { .api }
61
# Ignore 404 responses (useful during development)
62
app.config['FREEZER_IGNORE_404_NOT_FOUND'] = False # default
63
64
# How to handle redirects: 'follow' or 'ignore'
65
app.config['FREEZER_REDIRECT_POLICY'] = 'follow' # default
66
```
67
68
### Performance Optimization
69
70
Settings for build performance and incremental updates.
71
72
```python { .api }
73
# Skip files that haven't changed (boolean or callable)
74
app.config['FREEZER_SKIP_EXISTING'] = False # default
75
```
76
77
## Usage Examples
78
79
### Basic Configuration
80
81
```python
82
from flask import Flask
83
from flask_frozen import Freezer
84
85
app = Flask(__name__)
86
87
# Configure build destination
88
app.config['FREEZER_DESTINATION'] = 'dist'
89
app.config['FREEZER_REMOVE_EXTRA_FILES'] = True
90
91
freezer = Freezer(app)
92
```
93
94
### Production Build Configuration
95
96
```python
97
# Production build with relative URLs for CDN deployment
98
app.config.update({
99
'FREEZER_DESTINATION': 'public',
100
'FREEZER_RELATIVE_URLS': True,
101
'FREEZER_BASE_URL': 'https://mysite.com/subpath/',
102
'FREEZER_REMOVE_EXTRA_FILES': True,
103
'FREEZER_IGNORE_MIMETYPE_WARNINGS': True,
104
})
105
```
106
107
### Development Configuration
108
109
```python
110
# Development build with lenient error handling
111
app.config.update({
112
'FREEZER_DESTINATION': 'dev-build',
113
'FREEZER_IGNORE_404_NOT_FOUND': True,
114
'FREEZER_REDIRECT_POLICY': 'ignore',
115
'FREEZER_REMOVE_EXTRA_FILES': False,
116
})
117
```
118
119
### Custom File Ignoring
120
121
```python
122
# Ignore specific files and patterns
123
app.config.update({
124
'FREEZER_DESTINATION_IGNORE': [
125
'.DS_Store',
126
'*.log',
127
'temp/*',
128
'draft-*',
129
],
130
'FREEZER_STATIC_IGNORE': [
131
'*.scss',
132
'*.coffee',
133
'src/*',
134
'node_modules/*',
135
],
136
})
137
```
138
139
### Incremental Build Configuration
140
141
```python
142
# Skip unchanged files for faster rebuilds
143
def should_skip_file(url, filepath):
144
# Custom logic for determining if file should be skipped
145
import os
146
from datetime import datetime, timedelta
147
148
if not os.path.exists(filepath):
149
return False
150
151
# Skip if modified less than 1 hour ago
152
mtime = datetime.fromtimestamp(os.path.getmtime(filepath))
153
return datetime.now() - mtime < timedelta(hours=1)
154
155
app.config['FREEZER_SKIP_EXISTING'] = should_skip_file
156
```
157
158
## Advanced Configuration Patterns
159
160
### Environment-Based Configuration
161
162
```python
163
import os
164
165
class Config:
166
FREEZER_DESTINATION = 'build'
167
FREEZER_REMOVE_EXTRA_FILES = True
168
169
class DevelopmentConfig(Config):
170
FREEZER_IGNORE_404_NOT_FOUND = True
171
FREEZER_REDIRECT_POLICY = 'ignore'
172
173
class ProductionConfig(Config):
174
FREEZER_DESTINATION = 'public'
175
FREEZER_RELATIVE_URLS = True
176
FREEZER_IGNORE_MIMETYPE_WARNINGS = True
177
FREEZER_BASE_URL = os.environ.get('SITE_BASE_URL', 'https://example.com')
178
179
# Apply configuration based on environment
180
if app.config.get('ENV') == 'production':
181
app.config.from_object(ProductionConfig)
182
else:
183
app.config.from_object(DevelopmentConfig)
184
```
185
186
### CDN Configuration
187
188
```python
189
# Configuration for deploying to CDN with relative URLs
190
app.config.update({
191
'FREEZER_RELATIVE_URLS': True,
192
'FREEZER_BASE_URL': 'https://cdn.example.com/mysite/',
193
'FREEZER_DESTINATION': 'cdn-build',
194
'FREEZER_STATIC_IGNORE': [
195
'*.map', # Ignore source maps
196
'dev/*', # Ignore dev-only assets
197
],
198
})
199
```
200
201
### Multi-Site Configuration
202
203
```python
204
# Configuration for building multiple site variants
205
def configure_for_site(site_name):
206
site_configs = {
207
'main': {
208
'FREEZER_DESTINATION': 'build/main',
209
'FREEZER_BASE_URL': 'https://example.com',
210
},
211
'blog': {
212
'FREEZER_DESTINATION': 'build/blog',
213
'FREEZER_BASE_URL': 'https://blog.example.com',
214
},
215
'docs': {
216
'FREEZER_DESTINATION': 'build/docs',
217
'FREEZER_BASE_URL': 'https://docs.example.com',
218
'FREEZER_RELATIVE_URLS': True,
219
},
220
}
221
222
app.config.update(site_configs[site_name])
223
224
# Build different site variants
225
for site in ['main', 'blog', 'docs']:
226
configure_for_site(site)
227
freezer.freeze()
228
```
229
230
## Configuration Validation
231
232
Frozen-Flask validates configuration automatically, but you can add custom validation:
233
234
```python
235
def validate_freezer_config():
236
"""Validate Frozen-Flask configuration"""
237
config = app.config
238
239
# Ensure destination is set
240
assert config.get('FREEZER_DESTINATION'), "FREEZER_DESTINATION must be set"
241
242
# Validate redirect policy
243
policy = config.get('FREEZER_REDIRECT_POLICY', 'follow')
244
assert policy in ['follow', 'ignore'], f"Invalid redirect policy: {policy}"
245
246
# Warn about potentially problematic settings
247
if config.get('FREEZER_RELATIVE_URLS') and not config.get('FREEZER_BASE_URL'):
248
import warnings
249
warnings.warn("FREEZER_RELATIVE_URLS is True but FREEZER_BASE_URL is not set")
250
251
# Validate before freezing
252
validate_freezer_config()
253
freezer.freeze()
254
```