0
# JSON Serialization
1
2
Custom JSON serialization system designed to handle the complex template context data in Sphinx themes, including non-serializable Jinja2 functions and theme-specific objects. This module provides a robust serialization layer for JSON output builders and theme data persistence.
3
4
## Capabilities
5
6
### Custom JSON Encoder
7
8
Specialized JSON encoder that handles theme-specific objects and non-serializable template data.
9
10
```python { .api }
11
class AwesomeJSONEncoder(json.JSONEncoder):
12
"""
13
Custom JSON encoder for everything in the template context.
14
15
Provides safe serialization by returning empty strings for
16
non-serializable objects instead of raising exceptions.
17
"""
18
19
def default(self, obj: Any) -> str:
20
"""
21
Return an empty string for anything that's not serializable by default.
22
23
This prevents JSON serialization errors when template context
24
contains Jinja2 functions or other non-serializable objects.
25
26
Parameters:
27
- obj (Any): Object to serialize
28
29
Returns:
30
str: Empty string for non-serializable objects
31
"""
32
```
33
34
### JSON File Operations
35
36
Enhanced JSON file operations that automatically use the custom encoder.
37
38
```python { .api }
39
def dump(obj: Any, fp: IO[str], *args: Any, **kwargs: Any) -> None:
40
"""
41
Dump JSON into file using the custom encoder.
42
43
Automatically applies AwesomeJSONEncoder to handle theme-specific
44
objects and non-serializable template context data.
45
46
Parameters:
47
- obj (Any): Object to serialize
48
- fp (IO[str]): File-like object to write to
49
- *args: Additional positional arguments for json.dump
50
- **kwargs: Additional keyword arguments for json.dump
51
"""
52
53
def dumps(obj: Any, *args: Any, **kwargs: Any) -> str:
54
"""
55
Convert object to JSON string using the custom encoder.
56
57
Parameters:
58
- obj (Any): Object to serialize
59
- *args: Additional positional arguments for json.dumps
60
- **kwargs: Additional keyword arguments for json.dumps
61
62
Returns:
63
str: JSON string representation
64
"""
65
```
66
67
### JSON Deserialization
68
69
Standard JSON deserialization functions for completeness.
70
71
```python { .api }
72
def load(*args: Any, **kwargs: Any) -> Any:
73
"""
74
De-serialize JSON from file.
75
76
Standard JSON loading with consistent interface.
77
78
Parameters:
79
- *args: Positional arguments for json.load
80
- **kwargs: Keyword arguments for json.load
81
82
Returns:
83
Any: Deserialized Python object
84
"""
85
86
def loads(*args: Any, **kwargs: Any) -> Any:
87
"""
88
De-serialize JSON from string.
89
90
Parameters:
91
- *args: Positional arguments for json.loads
92
- **kwargs: Keyword arguments for json.loads
93
94
Returns:
95
Any: Deserialized Python object
96
"""
97
```
98
99
## Integration with Sphinx
100
101
### JSON Builder Configuration
102
103
The JSON serialization system integrates with Sphinx's JSON HTML builder:
104
105
```python
106
# In theme setup
107
JSONHTMLBuilder.out_suffix = ".json"
108
JSONHTMLBuilder.implementation = jsonimpl
109
JSONHTMLBuilder.indexer_format = jsonimpl
110
```
111
112
This configuration:
113
- Sets proper file extension for JSON output
114
- Uses custom serialization implementation
115
- Applies custom formatting for search indexing
116
117
### Template Context Serialization
118
119
The custom encoder handles common non-serializable objects in Sphinx template contexts:
120
121
```python
122
# Example template context objects that need custom handling
123
context = {
124
"theme_options": {...}, # Serializable
125
"pathto": <function pathto>, # Non-serializable - becomes ""
126
"hasdoc": <function hasdoc>, # Non-serializable - becomes ""
127
"sidebar_links": [...], # Serializable
128
"custom_jinja_filter": <filter>, # Non-serializable - becomes ""
129
}
130
```
131
132
## Usage Examples
133
134
### Basic JSON Serialization
135
136
```python
137
import sphinxawesome_theme.jsonimpl as json
138
139
# Serialize theme data
140
theme_data = {
141
"version": "5.3.2",
142
"options": theme_options,
143
"non_serializable": some_function
144
}
145
146
# Safe serialization - non-serializable objects become empty strings
147
json_string = json.dumps(theme_data)
148
```
149
150
### File-Based Serialization
151
152
```python
153
# Write theme configuration to file
154
with open("theme_config.json", "w") as f:
155
json.dump(theme_options, f, indent=2)
156
```
157
158
### Integration with Sphinx Builders
159
160
```python
161
# The JSON builder automatically uses this implementation
162
# when configured in the theme setup function
163
```
164
165
## Error Handling
166
167
### Non-Serializable Objects
168
169
The custom encoder provides graceful handling of problematic objects:
170
171
```python
172
# Instead of raising TypeError
173
try:
174
json.dumps(non_serializable_object)
175
except TypeError:
176
# This would happen with standard json module
177
pass
178
179
# With custom encoder - returns empty string safely
180
result = jsonimpl.dumps(non_serializable_object) # Returns '""'
181
```
182
183
### Consistent Interface
184
185
All functions maintain the same interface as the standard `json` module:
186
187
```python
188
# Drop-in replacement for standard json module
189
import sphinxawesome_theme.jsonimpl as json
190
191
# All standard json operations work identically
192
data = json.loads('{"key": "value"}')
193
text = json.dumps(data)
194
```
195
196
## Performance Considerations
197
198
### Encoder Efficiency
199
200
The custom encoder is optimized for template context serialization:
201
- Minimal overhead for serializable objects
202
- Fast fallback for non-serializable objects
203
- No exception handling overhead during serialization
204
205
### Memory Usage
206
207
The encoder design minimizes memory usage:
208
- No object introspection for standard types
209
- Immediate string return for non-serializable objects
210
- No intermediate object creation
211
212
## Use Cases
213
214
### Theme Configuration Export
215
216
Export complete theme configuration for debugging or transfer:
217
218
```python
219
# Export all theme settings
220
config_data = {
221
"theme_options": theme_options,
222
"html_context": filtered_context,
223
"build_info": build_metadata
224
}
225
226
json.dump(config_data, config_file, indent=2)
227
```
228
229
### Search Index Generation
230
231
Generate JSON data for client-side search functionality:
232
233
```python
234
# Create search index data
235
search_data = {
236
"pages": page_metadata,
237
"sections": section_data,
238
"keywords": keyword_index
239
}
240
241
search_json = json.dumps(search_data, separators=(',', ':'))
242
```
243
244
### API Documentation
245
246
Serialize API documentation data for external tools:
247
248
```python
249
# Export documentation structure
250
api_data = {
251
"modules": module_info,
252
"classes": class_definitions,
253
"functions": function_signatures
254
}
255
256
json.dump(api_data, api_file)
257
```