Skip to content

Commit 8e8ee1a

Browse files
committed
add an example project for demo/testing purposes
1 parent 0f915f1 commit 8e8ee1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1541
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,8 @@ ENV/
4242
# OS
4343
.DS_Store
4444
Thumbs.db
45+
46+
# Example project
47+
.venv
48+
venv
49+
db.sqlite3

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ The widget includes default CSS that can be customized by overriding these class
225225
- Django >= 4.2
226226
- Wagtail >= 5.0
227227

228+
## Example Project
229+
230+
An example Wagtail project demonstrating various uses of ThumbnailChoiceBlock is included in the repository. The example shows best practices including dynamic choices, template-based thumbnails, and different thumbnail configurations.
231+
232+
See [example/README.md](example/README.md) for setup instructions and details.
233+
228234
## Development
229235

230236
```bash

example/README.md

Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
# Thumbnail Choice Block Demo
2+
3+
This is a demonstration project showing how to use the `wagtail-thumbnail-choice-block` package in a real Wagtail site.
4+
5+
## Features Demonstrated
6+
7+
This demo showcases multiple use cases for `ThumbnailChoiceBlock`:
8+
9+
1. **Page-level fields** - Theme and layout selectors using `ThumbnailRadioSelect` widget
10+
2. **Icon selector** - Using template-based thumbnails for icon choices
11+
3. **Color scheme selector** - Using SVG gradient thumbnails
12+
4. **Button style selector** - Using PNG thumbnails with different button styles
13+
5. **Custom thumbnail sizes** - Different blocks use different thumbnail sizes (40px, 60px, 80px, 100px)
14+
15+
## Quick Start
16+
17+
### Prerequisites
18+
19+
- Python 3.9 or higher
20+
- pip (Python package manager)
21+
22+
### Installation
23+
24+
1. **Create and activate a virtual environment:**
25+
26+
```bash
27+
python -m venv venv
28+
source venv/bin/activate # On Windows: venv\Scripts\activate
29+
```
30+
31+
2. **Install dependencies:**
32+
33+
```bash
34+
pip install -r requirements.txt
35+
```
36+
37+
3. **Install the wagtail-thumbnail-choice-block package:**
38+
39+
From the parent directory:
40+
```bash
41+
pip install -e ..
42+
```
43+
44+
Or if you want to install from PyPI:
45+
```bash
46+
pip install wagtail-thumbnail-choice-block
47+
```
48+
49+
4. **Run migrations:**
50+
51+
```bash
52+
python manage.py migrate
53+
```
54+
55+
5. **Set up the demo site:**
56+
57+
```bash
58+
python manage.py setup_demo
59+
```
60+
61+
This command will:
62+
- Create a superuser (username: `admin`, password: `admin`)
63+
- Create the home page with example content
64+
- Configure the Wagtail site
65+
66+
6. **Start the development server:**
67+
68+
```bash
69+
python manage.py runserver
70+
```
71+
72+
7. **Visit the site:**
73+
74+
- **Frontend:** http://localhost:8000/
75+
- **Admin:** http://localhost:8000/admin/ (login with `admin`/`admin`)
76+
77+
## Using the Demo
78+
79+
### In the Wagtail Admin
80+
81+
1. Go to http://localhost:8000/admin/ and log in
82+
2. Click on "Pages" in the sidebar
83+
3. Click on the home page to edit it
84+
4. You'll see several examples of `ThumbnailChoiceBlock`:
85+
86+
**Page Settings (top of the page):**
87+
- **Theme** - Choose between Light, Dark, or Auto theme with visual thumbnails
88+
- **Layout** - Select Grid, List, or Masonry layout with preview thumbnails
89+
90+
**Content Blocks (StreamField):**
91+
- **Icon Block** - Select from 4 different icons (Star, Heart, Check, Info) using SVG templates
92+
- **Color Scheme** - Choose from 4 gradient color schemes
93+
- **Button Style** - Pick from 4 different button styles (Solid, Outline, Ghost, Gradient)
94+
95+
5. Try adding and editing different blocks to see how the thumbnails help you make visual choices
96+
6. Save and publish the page to see your changes on the frontend
97+
98+
### Code Examples
99+
100+
The demo includes several patterns you can copy for your own projects:
101+
102+
#### 1. Page Field with Custom Widget
103+
104+
```python
105+
from wagtail_thumbnail_choice_block.widgets import ThumbnailRadioSelect
106+
107+
class MyPage(Page):
108+
theme = models.CharField(max_length=50, choices=[...])
109+
110+
content_panels = [
111+
FieldPanel('theme', widget=ThumbnailRadioSelect(
112+
choices=[...],
113+
thumbnails={...},
114+
thumbnail_size=60,
115+
)),
116+
]
117+
```
118+
119+
#### 2. StreamField Block
120+
121+
```python
122+
from wagtail_thumbnail_choice_block import ThumbnailChoiceBlock
123+
124+
content = StreamField([
125+
('icon', ThumbnailChoiceBlock(
126+
choices=[...],
127+
thumbnail_templates={...},
128+
thumbnail_size=60,
129+
)),
130+
])
131+
```
132+
133+
#### 3. Using Image Thumbnails
134+
135+
```python
136+
ThumbnailChoiceBlock(
137+
choices=[
138+
('option1', 'Option 1'),
139+
('option2', 'Option 2'),
140+
],
141+
thumbnails={
142+
'option1': '/static/thumbnails/option1.png',
143+
'option2': '/static/thumbnails/option2.png',
144+
},
145+
thumbnail_size=80,
146+
)
147+
```
148+
149+
#### 4. Using Template-based Thumbnails
150+
151+
```python
152+
ThumbnailChoiceBlock(
153+
choices=[
154+
('icon1', 'Icon 1'),
155+
('icon2', 'Icon 2'),
156+
],
157+
thumbnail_templates={
158+
'icon1': 'icons/icon1.html',
159+
'icon2': {
160+
'template': 'icons/icon2.html',
161+
'context': {'color': 'blue'},
162+
},
163+
},
164+
thumbnail_size=50,
165+
)
166+
```
167+
168+
## Project Structure
169+
170+
```
171+
example/
172+
├── manage.py # Django management script
173+
├── generate_thumbnails.py # Script to generate thumbnail images
174+
├── demo/ # Django project
175+
│ ├── settings.py # Django settings
176+
│ ├── urls.py # URL configuration
177+
│ ├── wsgi.py # WSGI application
178+
│ ├── templates/ # Base templates
179+
│ │ └── base.html
180+
│ ├── static/ # Static files
181+
│ │ └── thumbnails/ # Generated thumbnails
182+
│ │ ├── themes/ # Theme thumbnails (PNG)
183+
│ │ ├── layouts/ # Layout thumbnails (PNG)
184+
│ │ ├── colors/ # Color scheme thumbnails (SVG)
185+
│ │ └── buttons/ # Button style thumbnails (PNG)
186+
│ └── home/ # Home app
187+
│ ├── models.py # Page models with examples
188+
│ ├── templates/ # App templates
189+
│ │ └── home/
190+
│ │ ├── home_page.html
191+
│ │ └── icons/ # Icon templates
192+
│ └── management/ # Management commands
193+
│ └── commands/
194+
│ └── setup_demo.py
195+
```
196+
197+
## Customization
198+
199+
### Adding Your Own Examples
200+
201+
1. **Edit `demo/home/models.py`** to add new field or block examples
202+
2. **Create thumbnails** in `demo/static/thumbnails/`
203+
3. **Update templates** in `demo/home/templates/` if needed
204+
4. **Run migrations:** `python manage.py makemigrations && python manage.py migrate`
205+
206+
### Creating Custom Thumbnails
207+
208+
You can create thumbnails using any image editor or programmatically:
209+
210+
- **PNG images:** Use Pillow, Photoshop, GIMP, etc.
211+
- **SVG images:** Use Inkscape, Illustrator, or write SVG XML directly
212+
- **Templates:** Create Django template files that render HTML/SVG
213+
214+
The `generate_thumbnails.py` script shows how to create PNG images programmatically using Pillow.
215+
216+
## Troubleshooting
217+
218+
### Import Error for wagtail_thumbnail_choice_block
219+
220+
Make sure you've installed the package:
221+
```bash
222+
pip install -e .. # From the example directory
223+
```
224+
225+
### Missing Thumbnails
226+
227+
The thumbnails are included in the repository. If you need to regenerate them:
228+
```bash
229+
python generate_thumbnails.py
230+
```
231+
232+
### Database Errors
233+
234+
Delete the database and start over:
235+
```bash
236+
rm db.sqlite3
237+
python manage.py migrate
238+
python manage.py setup_demo
239+
```
240+
241+
### Static Files Not Loading
242+
243+
Collect static files:
244+
```bash
245+
python manage.py collectstatic --noinput
246+
```
247+
248+
## Learn More
249+
250+
- **Main Package:** See the parent directory for the full package documentation
251+
- **Wagtail Documentation:** https://docs.wagtail.org/
252+
- **Django Documentation:** https://docs.djangoproject.com/
253+
254+
## License
255+
256+
This demo project is provided as an example and is not meant for production use.

example/demo/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Demo project package

example/demo/home/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Home app package

example/demo/home/apps.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.apps import AppConfig
2+
3+
4+
class HomeConfig(AppConfig):
5+
default_auto_field = "django.db.models.BigAutoField"
6+
name = "demo.home"
7+
label = "home"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Management commands package
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Commands package
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
"""
2+
Management command to set up the demo site with initial data.
3+
"""
4+
5+
from django.core.management.base import BaseCommand
6+
from django.contrib.auth import get_user_model
7+
from wagtail.models import Site, Page
8+
9+
from demo.home.models import HomePage
10+
11+
12+
class Command(BaseCommand):
13+
help = "Set up the demo site with initial data"
14+
15+
def handle(self, *args, **options):
16+
self.stdout.write(self.style.SUCCESS("Setting up demo site..."))
17+
self.stdout.write("")
18+
19+
# Create superuser
20+
User = get_user_model()
21+
if not User.objects.filter(username="admin").exists():
22+
self.stdout.write("Creating superuser (admin/admin)...")
23+
User.objects.create_superuser(
24+
username="admin", email="[email protected]", password="admin"
25+
)
26+
self.stdout.write(self.style.SUCCESS("✓ Superuser created"))
27+
else:
28+
self.stdout.write(self.style.WARNING("! Superuser already exists"))
29+
30+
# Get the root page
31+
try:
32+
root_page = Page.objects.get(depth=1)
33+
except Page.DoesNotExist:
34+
self.stdout.write(
35+
self.style.ERROR("Root page not found. Please run migrations first.")
36+
)
37+
return
38+
39+
# Delete the default Wagtail page if it exists
40+
home_pages = Page.objects.filter(slug="home", depth=2)
41+
for page in home_pages:
42+
if not isinstance(page.specific, HomePage):
43+
page.delete()
44+
self.stdout.write("Removed default Wagtail home page")
45+
break
46+
47+
# Create HomePage if it doesn't exist
48+
if not HomePage.objects.exists():
49+
self.stdout.write("Creating home page...")
50+
home_page = HomePage(
51+
title="Thumbnail Choice Block Demo",
52+
slug="home",
53+
theme="light",
54+
layout="grid",
55+
)
56+
root_page.add_child(instance=home_page)
57+
home_page.save_revision().publish()
58+
59+
# Update site root page or create new site
60+
try:
61+
site = Site.objects.get(is_default_site=True)
62+
site.root_page = home_page
63+
site.save()
64+
except Site.DoesNotExist:
65+
Site.objects.create(
66+
hostname="localhost",
67+
port=8000,
68+
root_page=home_page,
69+
is_default_site=True,
70+
site_name="Demo Site",
71+
)
72+
73+
self.stdout.write(self.style.SUCCESS("✓ Home page created"))
74+
else:
75+
self.stdout.write(self.style.WARNING("! Home page already exists"))
76+
77+
self.stdout.write("")
78+
self.stdout.write(self.style.SUCCESS("=" * 70))
79+
self.stdout.write(self.style.SUCCESS("Demo site setup complete!"))
80+
self.stdout.write(self.style.SUCCESS("=" * 70))
81+
self.stdout.write("")
82+
self.stdout.write("You can now:")
83+
self.stdout.write(" 1. Run the development server:")
84+
self.stdout.write(" python manage.py runserver")
85+
self.stdout.write("")
86+
self.stdout.write(" 2. Visit the site:")
87+
self.stdout.write(" http://localhost:8000/")
88+
self.stdout.write("")
89+
self.stdout.write(" 3. Log in to Wagtail admin:")
90+
self.stdout.write(" http://localhost:8000/admin/")
91+
self.stdout.write(" Username: admin")
92+
self.stdout.write(" Password: admin")
93+
self.stdout.write("")

0 commit comments

Comments
 (0)