Twig QR Code Integration
Total CMS provides comprehensive QR code generation capabilities through Twig templates using the bacon/bacon-qr-code library, supporting various data types including URLs, contact information, WiFi credentials, and more.
Overview
The QR code integration allows you to:
- Generate QR codes for URLs, text, and structured data
- Create contact cards (vCard format) with QR codes
- Generate WiFi connection QR codes
- Create calendar events and SMS/email QR codes
- Support for location (GPS) coordinates
- Output as SVG for scalable, high-quality codes
Basic Usage
Simple Text and URLs
{# Basic text QR code #}
{{ qr.text('Hello World!') }}
{# Website URL #}
{{ qr.url('https://totalcms.io') }}
{# Any URL type #}
{{ qr.url('https://github.com/user/repo') }}
Communication QR Codes
{# Phone number (creates tel: link) #}
{{ qr.tel('555-123-4567') }}
{{ qr.tel('+1-555-123-4567') }}
{# Email with optional subject and body #}
{{ qr.mailto('support@totalcms.io') }}
{{ qr.mailto('contact@company.com', 'Support Request', 'Please help with...') }}
{# SMS with pre-filled message #}
{{ qr.sms('555-123-4567', 'Hello from Total CMS!') }}
Advanced QR Code Types
WiFi Network Credentials
{# WiFi connection QR code #}
{{ qr.wifi('WPA', 'MyNetwork', 'password123', 'false') }}
{# Different authentication types #}
{{ qr.wifi('WEP', 'OldNetwork', 'wepkey', 'false') }}
{{ qr.wifi('nopass', 'OpenNetwork', '', 'false') }}
{# Hidden network #}
{{ qr.wifi('WPA', 'HiddenNetwork', 'secretpass', 'true') }}
GPS Location Coordinates
{# Geographic coordinates #}
{{ qr.gps('40.7128', '-74.0060') }} {# New York City #}
{{ qr.gps('51.5074', '-0.1278') }} {# London #}
{# Using variables from collections #}
{{ qr.gps(location.latitude, location.longitude) }}
Contact Information (vCard)
{# Complete contact card #}
{{ qr.vcf({
'first': 'John',
'last': 'Doe',
'company': 'Total CMS Solutions',
'street': '123 Business Ave',
'city': 'Tech City',
'state': 'CA',
'zip': '90210',
'phone': '555-123-4567',
'mobile': '555-987-6543',
'email': 'john.doe@totalcms.io',
'website': 'https://totalcms.io'
}) }}
{# Minimal contact card #}
{{ qr.vcf({
'first': 'Jane',
'last': 'Smith',
'email': 'jane@example.com',
'mobile': '555-555-5555'
}) }}
Calendar Events
{# Meeting or event QR code #}
{{ qr.event({
'title': 'Team Meeting',
'desc': 'Weekly team sync and planning session',
'location': 'Conference Room A, Office Building',
'start': '2024-12-01T10:00:00+00:00',
'end': '2024-12-01T11:30:00+00:00'
}) }}
{# Conference or workshop #}
{{ qr.event({
'title': 'Total CMS Workshop',
'desc': 'Learn advanced Total CMS techniques and best practices',
'location': 'Tech Conference Center, Hall B',
'start': '2024-12-15T14:00:00+00:00',
'end': '2024-12-15T17:00:00+00:00'
}) }}
Real-World Template Examples
Business Card Template
{# business-card.twig #}
<div class="business-card">
<div class="card-front">
<h1>{{ person.first }} {{ person.last }}</h1>
<h2>{{ person.title }}</h2>
<p>{{ person.company }}</p>
<div class="contact-info">
<p>📧 {{ person.email }}</p>
<p>📱 {{ person.mobile }}</p>
<p>🌐 {{ person.website }}</p>
</div>
</div>
<div class="card-back">
<div class="qr-code">
{{ qr.vcf({
'first': person.first,
'last': person.last,
'company': person.company,
'email': person.email,
'mobile': person.mobile,
'website': person.website
}) }}
</div>
<p class="qr-label">Scan to save contact</p>
</div>
</div>
Event Information Page
{# event-details.twig #}
<div class="event-page">
<header class="event-header">
<h1>{{ event.title }}</h1>
<p class="event-date">{{ event.start|date('F j, Y g:i A') }}</p>
<p class="event-location">{{ event.location }}</p>
</header>
<div class="event-content">
<div class="event-description">
{{ event.description|markdown }}
</div>
<div class="event-qr-codes">
<div class="qr-section">
<h3>📅 Add to Calendar</h3>
{{ qr.event({
'title': event.title,
'desc': event.description,
'location': event.location,
'start': event.start,
'end': event.end
}) }}
<p>Scan to add event to your calendar</p>
</div>
{% if event.website %}
<div class="qr-section">
<h3>🌐 Event Website</h3>
{{ qr.url(event.website) }}
<p>Scan for more information</p>
</div>
{% endif %}
{% if event.location_lat and event.location_lng %}
<div class="qr-section">
<h3>📍 Event Location</h3>
{{ qr.gps(event.location_lat, event.location_lng) }}
<p>Scan for directions</p>
</div>
{% endif %}
</div>
</div>
</div>
Restaurant Menu with QR Codes
{# restaurant-table.twig #}
<div class="table-tent">
<div class="front-panel">
<h1>{{ restaurant.name }}</h1>
<p>Table {{ table.number }}</p>
<div class="qr-codes">
<div class="qr-code-section">
<h3>📱 View Menu</h3>
{{ qr.url(restaurant.menu_url) }}
<p>Scan to see our digital menu</p>
</div>
<div class="qr-code-section">
<h3>📶 Free WiFi</h3>
{{ qr.wifi('WPA', restaurant.wifi_name, restaurant.wifi_password, 'false') }}
<p>Scan to connect</p>
</div>
</div>
</div>
<div class="back-panel">
<h2>Contact Us</h2>
<div class="contact-qr">
{{ qr.vcf({
'company': restaurant.name,
'street': restaurant.address,
'city': restaurant.city,
'state': restaurant.state,
'zip': restaurant.zip,
'phone': restaurant.phone,
'email': restaurant.email,
'website': restaurant.website
}) }}
<p>Save our contact information</p>
</div>
</div>
</div>
Product Information
{# product-qr.twig #}
{% for product in cms.collection('products').list() %}
<div class="product-info">
<h2>{{ product.title }}</h2>
<div class="product-qr-codes">
{% if product.url %}
<div class="qr-section">
<h4>🛒 Product Page</h4>
{{ qr.url(product.url) }}
<p>View online</p>
</div>
{% endif %}
{% if product.manual_url %}
<div class="qr-section">
<h4>📖 User Manual</h4>
{{ qr.url(product.manual_url) }}
<p>Download manual</p>
</div>
{% endif %}
{% if product.support_email %}
<div class="qr-section">
<h4>🆘 Support</h4>
{{ qr.mailto(product.support_email, 'Support Request: ' ~ product.title) }}
<p>Contact support</p>
</div>
{% endif %}
</div>
</div>
{% endfor %}
WiFi Guest Access
{# wifi-access.twig #}
<div class="wifi-card">
<h1>🏨 {{ hotel.name }}</h1>
<h2>Guest WiFi Access</h2>
<div class="wifi-info">
<div class="wifi-details">
<p><strong>Network:</strong> {{ hotel.wifi_name }}</p>
<p><strong>Password:</strong> {{ hotel.wifi_password }}</p>
</div>
<div class="wifi-qr">
{{ qr.wifi('WPA', hotel.wifi_name, hotel.wifi_password, 'false') }}
<p>Scan to connect automatically</p>
</div>
</div>
<div class="additional-services">
<h3>Hotel Services</h3>
<div class="service-qr-codes">
<div class="qr-item">
<h4>🏨 Hotel Website</h4>
{{ qr.url(hotel.website) }}
</div>
<div class="qr-item">
<h4>🍽️ Restaurant Menu</h4>
{{ qr.url(hotel.menu_url) }}
</div>
<div class="qr-item">
<h4>🛎️ Concierge</h4>
{{ qr.tel(hotel.concierge_phone) }}
</div>
</div>
</div>
</div>
Contact Directory
{# staff-directory.twig #}
<div class="staff-directory">
<h1>{{ company.name }} - Staff Directory</h1>
{% for staff in cms.collection('staff').list() %}
<div class="staff-card">
<div class="staff-info">
<h3>{{ staff.first }} {{ staff.last }}</h3>
<p class="title">{{ staff.title }}</p>
<p class="department">{{ staff.department }}</p>
<div class="contact-details">
<p>📧 {{ staff.email }}</p>
<p>📱 {{ staff.mobile }}</p>
{% if staff.office_phone %}
<p>☎️ {{ staff.office_phone }}</p>
{% endif %}
</div>
</div>
<div class="staff-qr">
{{ qr.vcf({
'first': staff.first,
'last': staff.last,
'company': company.name,
'email': staff.email,
'mobile': staff.mobile,
'phone': staff.office_phone
}) }}
<p>Save contact</p>
</div>
</div>
{% endfor %}
</div>
Dynamic QR Code Generation
Collection-Based QR Codes
{# Dynamic contact cards from collection #}
{% for contact in cms.collection('contacts').list() %}
<div class="contact-card">
<h3>{{ contact.name }}</h3>
{{ qr.vcf({
'first': contact.first_name,
'last': contact.last_name,
'company': contact.company,
'email': contact.email,
'mobile': contact.phone
}) }}
</div>
{% endfor %}
{# Event QR codes from events collection #}
{% for event in cms.collection('events').list() %}
<div class="event-qr">
<h3>{{ event.title }}</h3>
{{ qr.event({
'title': event.title,
'desc': event.description,
'location': event.venue,
'start': event.start_date,
'end': event.end_date
}) }}
</div>
{% endfor %}
Conditional QR Codes
{# Show appropriate QR code based on data availability #}
{% if contact.website %}
{{ qr.url(contact.website) }}
{% elseif contact.email %}
{{ qr.mailto(contact.email) }}
{% elseif contact.phone %}
{{ qr.tel(contact.phone) }}
{% else %}
{{ qr.text(contact.name) }}
{% endif %}
CSS Styling for QR Codes
/* QR Code container styling */
.qr-code {
display: inline-block;
padding: 15px;
background: white;
border: 2px solid #000;
border-radius: 8px;
text-align: center;
margin: 10px;
}
.qr-code svg {
display: block;
margin: 0 auto;
max-width: 200px;
max-height: 200px;
}
.qr-label {
margin-top: 10px;
font-size: 12px;
color: #666;
text-align: center;
}
/* Business card QR codes */
.business-card .qr-code {
padding: 10px;
border: 1px solid #ccc;
}
.business-card .qr-code svg {
max-width: 100px;
max-height: 100px;
}
/* Print-friendly QR codes */
@media print {
.qr-code {
background: white !important;
border: 1px solid black;
page-break-inside: avoid;
}
}
/* Responsive QR codes */
@media (max-width: 768px) {
.qr-code svg {
max-width: 150px;
max-height: 150px;
}
}
Best Practices
- Data Validation: Always validate URLs and data before generating QR codes
- Size Appropriately: Ensure QR codes are large enough to scan reliably
- High Contrast: Use dark QR codes on light backgrounds
- Test Scanning: Test QR codes with various devices and apps
- Include Instructions: Add clear instructions for users
- Error Correction: QR codes have built-in error correction
- Keep It Simple: Don't overcrowd areas around QR codes
Security Considerations
{# Sanitize URLs before QR generation #}
{% set safe_url = url|trim|replace(' ', '') %}
{% if safe_url matches '/^https?:\\/\\/.+/' %}
{{ qr.url(safe_url) }}
{% endif %}
{# Validate email addresses #}
{% if email matches '/^[^@]+@[^@]+\\.[^@]+$/' %}
{{ qr.mailto(email) }}
{% endif %}
Common Use Cases
- Business Cards: Contact information sharing
- Events: Calendar integration and location sharing
- Restaurants: Menu access and WiFi sharing
- Hotels: Guest services and WiFi access
- Products: Manuals, support, and product information
- Marketing: Website links and promotional content
- Real Estate: Property information and virtual tours
- Education: Course materials and contact information
The QR code integration in Total CMS provides a comprehensive solution for creating interactive, scannable codes that enhance user experience and provide seamless digital connections.