Local Development
Complete reference for local development, build commands, and troubleshooting.
Prerequisites
Required Software
- Ruby 3.0+: Jekyll runtime
- Bundler: Ruby dependency management
- Python 3.9+: IIIF generation and CSV processing
- Node.js 18+: JavaScript bundling (esbuild)
- Git: Version control
Installation Guides
macOS (Homebrew):
brew install ruby python node git
gem install bundler
Ubuntu/Debian:
sudo apt-get install ruby-full python3 python3-pip nodejs npm git build-essential
gem install bundler
Windows:
- Install RubyInstaller
- Install Python
- Install Node.js (LTS version recommended)
- Install Git for Windows
Optional (Recommended)
- libvips: Fast image processing for IIIF tile generation. Telar falls back to pure Python if not installed, but libvips is roughly 28x faster.
macOS:
brew install vips
Ubuntu/Debian:
sudo apt-get install libvips-dev
Project Setup
Initial Setup
# Clone repository
git clone https://github.com/username/your-telar-site.git
cd your-telar-site
# Install Ruby dependencies
bundle install
# Install Python dependencies
pip install -r requirements.txt
# Install Node.js dependencies
npm install
Configuration
Edit _config.yml for local development:
baseurl: "" # Empty for local development
url: "http://localhost:4001"
Build Commands
Quick Start: Build Script (Recommended)
The easiest way to build and serve your Telar site locally is with the all-in-one build script:
# Build and serve on port 4001 (default)
python3 scripts/build_local_site.py
# Build only, don't start server
python3 scripts/build_local_site.py --build-only
# Use a different port
python3 scripts/build_local_site.py --port 4000
# Skip IIIF tile generation (faster rebuilds when images haven't changed)
python3 scripts/build_local_site.py --skip-iiif
# Skip Google Sheets fetch (use existing CSV files)
python3 scripts/build_local_site.py --skip-fetch
This script runs all necessary build steps in sequence, mimicking what GitHub Actions does during deployment. It automatically kills any running Jekyll instances before starting.
Core Commands (Manual)
If you prefer to run individual scripts:
# 1. Fetch data from Google Sheets (if enabled)
python3 scripts/fetch_google_sheets.py
# 2. Convert CSVs to JSON
python3 scripts/csv_to_json.py
# 3. Generate Jekyll collection files
python3 scripts/generate_collections.py
# 4. Generate IIIF tiles
python3 scripts/generate_iiif.py --base-url http://localhost:4001
# 5. Serve with live reload
bundle exec jekyll serve --livereload --port 4001
# Build only (output to _site/)
bundle exec jekyll build
# Clean build artifacts
bundle exec jekyll clean
Command Options
Jekyll Serve Options:
# Serve on custom port
bundle exec jekyll serve --port 4001
# Serve on local network
bundle exec jekyll serve --host 0.0.0.0
# Incremental build (faster)
bundle exec jekyll serve --incremental
# Disable live reload
bundle exec jekyll serve
IIIF Generation Options:
# Specify different source directory
python3 scripts/generate_iiif.py --source-dir path/to/images
# Specify custom base URL
python3 scripts/generate_iiif.py --base-url https://mysite.org
# Process specific image only
python3 scripts/generate_iiif.py --image textile-001.jpg
Development Workflow
Daily Workflow
Using the build script (recommended):
# First time or after CSV/image changes: full build
python3 scripts/build_local_site.py
# Quick rebuild (no IIIF regeneration)
python3 scripts/build_local_site.py --skip-iiif --skip-fetch
# The script handles everything and starts the server
# Make changes to content, then Ctrl+C and rerun to rebuild
Manual workflow:
# 1. Start Jekyll server
bundle exec jekyll serve --livereload
# 2. Make changes to content
# - Edit CSVs in telar-content/spreadsheets/
# - Edit markdown in telar-content/texts/
# - Add images to telar-content/objects/
# 3. Rebuild data (when CSVs change)
python3 scripts/csv_to_json.py
python3 scripts/generate_collections.py
# 4. Regenerate tiles (when images change)
python3 scripts/generate_iiif.py
# 5. Jekyll auto-reloads browser
# Site updates automatically
Working with Google Sheets Locally
For local development with Google Sheets:
- Configure in
_config.yml:google_sheets: enabled: true published_url: "YOUR_PUBLISHED_URL" - Use the build script (fetches automatically if enabled):
python3 scripts/build_local_site.pyOr fetch manually:
python3 scripts/fetch_google_sheets.py python3 scripts/csv_to_json.py python3 scripts/generate_collections.py bundle exec jekyll serve
See docs/google_sheets_integration/README.md in the main Telar repository for details.
Directory Structure
your-telar-site/
├── _config.yml # Site configuration
├── _data/ # Generated JSON data
│ ├── objects.json
│ ├── project.json
│ └── stories/
├── _jekyll-files/ # Auto-generated collections
│ ├── _stories/
│ ├── _objects/
│ └── _glossary/
├── _layouts/ # Page templates
│ ├── default.html
│ ├── story.html
│ └── object.html
├── _includes/ # Reusable components
│ ├── header.html
│ └── footer.html
├── assets/ # Static assets
│ ├── css/
│ ├── js/
│ └── images/
├── telar-content/ # SOURCE CONTENT (edit here!)
│ ├── structures/ # CSV files
│ ├── images/ # Source images
│ └── texts/ # Markdown files
├── iiif/ # Generated IIIF tiles
├── scripts/ # Build scripts
│ ├── build_local_site.py # All-in-one local build
│ ├── fetch_google_sheets.py
│ ├── csv_to_json.py
│ ├── generate_collections.py
│ └── generate_iiif.py
└── _site/ # Built site (don't edit!)
Troubleshooting
Common Issues
Jekyll won’t start:
# Update dependencies
bundle update
# Clean and retry
bundle exec jekyll clean
bundle exec jekyll serve
Changes not appearing:
# Restart Jekyll (Ctrl+C, then restart)
bundle exec jekyll serve --livereload
# Hard refresh browser (Cmd+Shift+R or Ctrl+Shift+R)
IIIF tiles not generating:
# Check Python dependencies
pip install -r requirements.txt
# Verify image files exist
ls -la telar-content/objects/
# Check for error messages
python3 scripts/generate_iiif.py
CSV to JSON conversion fails:
# Check CSV syntax
cat telar-content/spreadsheets/story-1.csv
# Verify markdown files exist
ls -la telar-content/texts/stories/
# Run with verbose output
python3 scripts/csv_to_json.py --verbose
Dependency Issues
Bundle install fails:
# Update RubyGems
gem update --system
# Clear bundle cache
bundle clean --force
bundle install
Pip install fails:
# Upgrade pip
pip install --upgrade pip
# Use virtualenv
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
Performance Issues
Slow build times:
# Use incremental builds
bundle exec jekyll serve --incremental
# Disable IIIF regeneration if images haven't changed
# (Just don't run generate_iiif.py)
# Reduce file watching
echo "_site" >> .gitignore
High memory usage:
# Clean build artifacts
bundle exec jekyll clean
rm -rf _site/
# Restart Jekyll server
Embedding Issues
Navigation buttons not working in iframe:
Check if embed mode is properly detected:
- Open browser DevTools in the iframe (right-click iframe content)
- Check console for JavaScript errors
- Verify
?embed=trueparameter in URL - Confirm
body.embed-modeclass is applied:document.body.classList.contains('embed-mode')
If embed mode is not detected, verify the URL parameter is correct.
Images not loading in embedded view:
IIIF tiles fail to load in iframe:
- Check browser console for CORS errors
- Verify your site is deployed and publicly accessible:
# Test IIIF manifest URL curl https://yoursite.com/iiif/objects/object-1/info.json - Ensure GitHub Pages deployment completed successfully
- For external IIIF manifests, verify the source institution allows CORS
“View full site” banner not appearing:
The embed banner should appear automatically:
- Verify
?embed=trueparameter in URL - Check browser console for JavaScript errors in
embed.js - Confirm
window.telarLang.embedBanneris defined:console.log(window.telarLang.embedBanner) - Check if banner exists in DOM but is hidden by CSS:
document.querySelector('.embed-banner')
If banner is missing, verify assets/js/embed.js is loading.
Scroll issues in LMS:
Telar uses button navigation in embed mode, not scrolling:
- Verify navigation buttons are visible
- Check if buttons are clickable (not behind other elements)
- Test keyboard navigation (arrow keys, Page Up/Down)
- Ensure iframe height is adequate (minimum 600px recommended)
If buttons are not visible, check that body.embed-mode class is applied.
IIIF viewer not displaying:
Tify fails to load in iframe:
- Check if Tify scripts are loading:
// In browser console typeof Tify - Verify IIIF manifest URL is accessible
- Check for Content Security Policy (CSP) restrictions in host site
- Test the story URL directly (not in iframe) to isolate the issue
Share panel not opening:
Share button should be hidden in embed mode:
- Verify this is expected behavior (share button intentionally hidden)
- If you need sharing in embed mode, users can dismiss the embed banner and click “View full site”
- For custom behavior, modify
body.embed-mode .share-buttonCSS
Embed code not generating:
In the share panel, embed code textarea is empty:
On homepage:
- Select a story from the dropdown first
- Verify story data JSON is present in page source
- Check browser console for JavaScript errors in
share-panel.js
On story page:
- Refresh the page to reset the share panel
- Check console for errors
- Verify
currentStoryUrlis set:// Should be set when page loads console.log(window.location.href)
Dimensions not updating:
When changing width/height inputs:
- Click the input field and type the value
- Press Enter or click outside the field to trigger update
- Check if preset dropdown is interfering (select “Custom” preset)
- Verify JavaScript is running without errors
Testing
Local Testing Checklist
Before deploying:
- All pages load without errors
- Stories scroll smoothly
- IIIF viewer zooms correctly
- Object thumbnails display
- Navigation works
- Links are correct
- Mobile responsive
- Cross-browser compatible
Browser Testing
Test in:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
Validation
# Check HTML validity
bundle exec htmlproofer ./_site --disable-external
# Check for broken links
bundle exec jekyll doctor
Automated Tests
Telar includes automated tests for Python scripts and JavaScript modules. Running tests is optional for storytellers but recommended for developers contributing to the framework.
Python Unit Tests:
# Run all Python unit tests
python3 -m pytest tests/unit/ -v
# Run with coverage report
python3 -m pytest tests/unit/ --cov=scripts/telar
JavaScript Unit Tests:
# Run JavaScript tests
npm run test:js
# Run in watch mode (re-runs on file changes)
npm run test:js:watch
End-to-End Tests (Playwright):
E2E tests require a running Jekyll server and Playwright browsers:
# Install Playwright browsers (one-time setup)
playwright install chromium
# Start Jekyll server in one terminal
bundle exec jekyll serve --port 4001
# Run E2E tests in another terminal
python3 -m pytest tests/e2e/ -v
Tests run automatically on GitHub via the telar-tests.yml workflow whenever you push to main or open a pull request.
Publishing
Prepare for Publishing
# 1. Test locally
bundle exec jekyll serve
# 2. Update _config.yml for production
baseurl: "/your-repo-name"
url: "https://username.github.io"
# 3. Commit changes
git add .
git commit -m "Update content"
# 4. Push to GitHub
git push origin main
# 5. GitHub Actions builds automatically
Manual Publishing
If not using GitHub Actions:
# Build for production
JEKYLL_ENV=production bundle exec jekyll build
# Publish _site/ directory to your host
Best Practices
- Commit frequently: Small, focused commits
- Test locally first: Always preview before pushing
- Use branches: Feature branches for major changes
- Document changes: Clear commit messages
- Backup content: Keep copies of important files
- Version control: Track all content in git
- Clean builds: Periodic
jekyll cleanhelps