generated from pascalmartineau/wp-skeleton
343 lines
18 KiB
Markdown
343 lines
18 KiB
Markdown
# ARCHITECTURE.md - CCAT Data Structure Reference
|
|
|
|
## Table of Contents
|
|
|
|
- [Custom Post Types Overview](#custom-post-types-overview)
|
|
- [Taxonomies Overview](#taxonomies-overview)
|
|
- [Custom Post Type Fields](#custom-post-type-fields)
|
|
- [Abstract Field Groups](#abstract-field-groups)
|
|
- [Field Relationships](#field-relationships)
|
|
- [Technical Implementation](#technical-implementation)
|
|
|
|
---
|
|
|
|
## Custom Post Types Overview
|
|
|
|
| CPT Name | Label | GraphQL Single | Rewrite Slug | Hierarchical | Description |
|
|
|----------|--------|----------------|--------------|--------------|-------------|
|
|
| `contributor` | Contributor | `Contributor` | -- | No | Artist/organization profiles |
|
|
| `event` | Event | `Event` | `evenement` | Yes | Base event descriptions without specific dates |
|
|
| `listing` | Listing | `Listing` | `offre` | No | Job offers and opportunities |
|
|
| `location` | Location | `Location` | `lieu` | Yes | Venue information with hierarchical structure |
|
|
| `page` | Page | `Page` | `page` | Yes | WordPress default pages with flexible content |
|
|
| `profile` | Profile | `Profile` | `profil` | No | User cultural profiles for members |
|
|
| `project` | Project | `Project` | `projet` | No | CCAT projects and initiatives |
|
|
| `representation` | Representation | `Representation` | -- | No | Specific event instances with dates/times/locations |
|
|
| `resource` | Resource | `Resource` | `ressource` | No | Document/link repository |
|
|
| `template` | Template | `Template` | -- | No | Reusable content blocks for flexible layouts |
|
|
|
|
---
|
|
|
|
## Taxonomies Overview
|
|
|
|
| Taxonomy Name | Label | Associated CPTs | Hierarchical | GraphQL Single | Description |
|
|
|---------------|--------|----------------|--------------|----------------|-------------|
|
|
| `discipline` | Discipline | `contributor`, `event` | Yes | `Discipline` | Artistic/cultural categories |
|
|
| `listing-category` | Listing Category | `listing` | Yes | `ListingCategory` | Job/proposal types |
|
|
| `project-category` | Project Category | `project` | Yes | `ProjectCategory` | CCAT project types |
|
|
| `resource-category` | Resource Category | `resource` | Yes | `ResourceCategory` | Resource organization categories |
|
|
|
|
---
|
|
|
|
## Custom Post Type Fields
|
|
|
|
### Contributor (`group_post_contributor`)
|
|
**Purpose:** Artist/organization profiles that can be linked to events
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `contributor_type` | Contributor type | select | Yes | Type of contributor (individual, organisation) |
|
|
| `alternative_titles` | Alternative titles | repeater | No | Alternative names for the contributor |
|
|
| `alternative_titles.name` | Name | text | Yes | Alternative name entry |
|
|
| `description` | Description | wysiwyg | No | Rich text description of contributor |
|
|
| `localities` | Localities | repeater | No | Physical locations associated with contributor |
|
|
| `localities.address` | Address | clone | Yes | Clones city address field for location |
|
|
| `disciplines` | Discipline(s) | taxonomy | No | Links to discipline taxonomy terms |
|
|
| `entity` | Entity | clone | No | External identifiers |
|
|
| `gallery` | Gallery | clone | No | Media gallery |
|
|
| `social` | Social | clone | No | Social media profiles |
|
|
|
|
### Event (`group_post_event`)
|
|
**Purpose:** Base event information without specific dates/times
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `event_type` | Event type | select | Yes | Type of event (Exposition, Festival, Spectacle) |
|
|
| `target_audience` | Target audience | select | Yes | Age group (Tout public, Enfants, Familial, Adultes 18+) |
|
|
| `description` | Description | wysiwyg | No | Rich text event description |
|
|
| `disciplines` | Discipline(s) | taxonomy | No | Links to discipline taxonomy terms |
|
|
| `is_wordless` | Wordless | true_false | No | Indicates if event is wordless |
|
|
| `languages` | Language(s) | acfe_languages | No | Event languages (conditional: shown if not wordless) |
|
|
| `entity` | Entity | clone | No | Clones abstract entity group (external identifiers) |
|
|
| `social` | Social | clone | No | Clones abstract social group (social media profiles) |
|
|
| `gallery` | Gallery | clone | No | Clones abstract gallery group (images/videos) |
|
|
| `credits` | Credits | clone | No | Clones abstract credits group (contributors and roles) |
|
|
|
|
### Listing (`group_post_listing`)
|
|
**Purpose:** Job offers and opportunities
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `listing_category` | Listing category | taxonomy | Yes | Links to listing_category taxonomy |
|
|
| `deadline` | Application deadline | date_picker | No | Application deadline date |
|
|
| `external_link` | External link | url | No | Link to external application |
|
|
|
|
### Location (`group_post_location`)
|
|
**Purpose:** Venue information for events
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `location_type` | Location type | select | Yes | Type of location (virtual, Bar, Salle de spectacle) |
|
|
| `description` | Description | wysiwyg | No | Rich text description of location |
|
|
| `address` | Address | clone | No | Clones geo address field (conditional: not shown for virtual) |
|
|
| `configurations` | Possible configurations | repeater | No | Different setup configurations for venue |
|
|
| `configurations.name` | Configuration name | text | Yes | Name of the configuration |
|
|
| `universal_access` | Universal access | checkbox | No | Accessibility features available |
|
|
| `entity` | Entity | clone | No | External identifiers |
|
|
| `social` | Social | clone | No | Social media profiles |
|
|
| `gallery` | Gallery | clone | No | Media gallery |
|
|
|
|
### Page (`group_post_page`)
|
|
**Purpose:** WordPress default pages with flexible content capabilities
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `builder` | Builder | clone | No | Clones abstract builder group (flexible content sections) |
|
|
|
|
**Note:** This field group extends WordPress's default `page` post type with flexible content capabilities. The default content editor is hidden (`hide_on_screen: the_content`) in favor of the flexible builder system.
|
|
|
|
### Profile (`group_post_profile`)
|
|
**Purpose:** User profile information for members
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `contact` | Contact | clone | Yes | Clones abstract contact group (personal info & address) |
|
|
| `billing_same` | Same as contact | true_false | No | Whether billing matches contact info |
|
|
| `billing` | Billing | clone | No | Separate billing contact info (conditional: shown if billing_same is false) |
|
|
| `profile_type` | Profile type | select | Yes | Type of profile (individual, collective, organization, institution) |
|
|
| `email_preferences` | Email preferences | group | No | Group containing email subscription preferences |
|
|
| `email_preferences.categories` | Categories | checkbox | No | Email categories to subscribe to |
|
|
| `email_preferences.disciplines` | Disciplines | checkbox | No | Discipline-based email preferences |
|
|
| `email_preferences.event_types` | Event types | checkbox | No | Event type email preferences |
|
|
| `email_preferences.mrc` | MRC | checkbox | No | Regional email preferences |
|
|
|
|
### Project (`group_post_project`)
|
|
**Purpose:** CCAT projects and initiatives
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `project_categories` | Project categories | taxonomy | Yes | Links to project_category taxonomy |
|
|
| `period` | Period | group | No | Project timeline |
|
|
| `period.start_month` | Start month | date_picker | Yes | Project start (month/year format) |
|
|
| `period.end_month` | End month | date_picker | No | Project end (month/year format) |
|
|
| `builder` | Builder | clone | No | Clones abstract builder group (flexible content sections) |
|
|
|
|
### Representation (`group_post_representation`)
|
|
**Purpose:** Specific event instances with dates/times
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `event` | Event | post_object | Yes | Links to base Event post |
|
|
| `description` | Description | wysiwyg | No | Specific description for this representation |
|
|
| `schedule_type` | Schedule type | select | Yes | Type of scheduling (range, days, multiple) |
|
|
| `range` | Range | group | No | Date range fields (conditional: when schedule_type = range) |
|
|
| `range.start_date` | Start date | date_picker | Yes | Range start date |
|
|
| `range.end_date` | End date | date_picker | Yes | Range end date |
|
|
| `days` | Days | repeater | No | Individual days (conditional: when schedule_type = days/multiple) |
|
|
| `days.start_date_time` | Start date/time | date_time_picker | Yes | Event start with time |
|
|
| `days.end_time` | End time | time_picker | No | Event end time |
|
|
| `offer` | Offer | clone | No | Clones abstract offer group (pricing, location, registration) |
|
|
|
|
### Resource (`group_post_resource`)
|
|
**Purpose:** Document repository
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `resource_category` | Resource category | taxonomy | Yes | Links to resource_category taxonomy |
|
|
| `documents` | Documents | repeater | No | List of documents |
|
|
| `documents.title` | Title | text | Yes | Document title |
|
|
| `documents.document_type` | Document type | select | Yes | Type of document (file, url) |
|
|
| `documents.file` | File | file | Yes | File upload (conditional: when document_type = file) |
|
|
| `documents.url` | URL | url | Yes | External URL (conditional: when document_type = url) |
|
|
|
|
### Template (`group_post_template`)
|
|
**Purpose:** Reusable content templates
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `builder` | Builder | clone | No | Clones abstract builder group (flexible content sections) |
|
|
|
|
---
|
|
|
|
## Abstract Field Groups
|
|
|
|
### Address City (`group_abstract_address_city`)
|
|
**Purpose:** City-level address information
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `address` | Address | acfe_address | Yes | Address with city-level search, Canada only |
|
|
|
|
### Address Contact (`group_abstract_address_contact`)
|
|
**Purpose:** Full contact address information
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `address` | Address | acfe_address | Yes | Complete address with street details, Canada only |
|
|
|
|
### Address Geo (`group_abstract_address_geo`)
|
|
**Purpose:** Geographic address with coordinates
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `address` | Address | acfe_address | Yes | Address with establishment search and lat/lng coordinates |
|
|
|
|
### Builder (`group_abstract_builder`)
|
|
**Purpose:** Flexible content builder with layout sections
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `sections` | Sections | flexible_content | No | Flexible content with layouts: |
|
|
| `sections.text_block` | Text block | layout | - | WYSIWYG content block |
|
|
| `sections.text_block.content` | Content | wysiwyg | Yes | Rich text content |
|
|
| `sections.template` | Template | layout | - | Reference to template post |
|
|
| `sections.template.template` | Template | post_object | Yes | Links to Template post type |
|
|
|
|
### Contact (`group_abstract_contact`)
|
|
**Purpose:** Personal contact information
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `first_name` | First name | text | Yes | Contact's first name |
|
|
| `last_name` | Last name | text | Yes | Contact's last name |
|
|
| `email` | Email | email | Yes | Contact email address |
|
|
| `phone` | Phone | acfe_phone_number | Yes | Phone number (Canada format) |
|
|
| `address` | Address | clone | Yes | Clones contact address field |
|
|
|
|
### Credits (`group_abstract_credits`)
|
|
**Purpose:** Attribution and contributor roles
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `contributions` | Contributions | repeater | No | List of contributor roles |
|
|
| `contributions.contributionTypes` | Contribution types | checkbox | Yes | Types of contribution (Auteur, Compositeur, Interprète) |
|
|
| `contributions.contributor` | Contributor | post_object | Yes | Links to Contributor post |
|
|
|
|
### Entity (`group_abstract_entity`)
|
|
**Purpose:** External entity identifiers
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `identifiers` | Identifiers | repeater | No | External identifier URLs |
|
|
| `identifiers.uri` | URI | url | Yes | External identifier URL |
|
|
|
|
### Gallery (`group_abstract_gallery`)
|
|
**Purpose:** Media gallery with images and videos
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `medias` | Medias | repeater | No | List of media items |
|
|
| `medias.mediaType` | Media type | select | Yes | Type of media (image, youtube) |
|
|
| `medias.image` | Image | image | Yes | Image upload (conditional: when mediaType = image) |
|
|
| `medias.youtube_url` | YouTube URL | url | Yes | YouTube video URL (conditional: when mediaType = youtube) |
|
|
|
|
### Offer (`group_abstract_offer`)
|
|
**Purpose:** Event offering details (pricing, registration, location)
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `attendance_mode` | Attendance mode | select | Yes | How event is attended (offline, online, mixed) |
|
|
| `is_async` | Is asynchronous | true_false | No | Whether online event is asynchronous |
|
|
| `offer_status` | Offer status | select | Yes | Event status (upcoming, confirmed, complete, cancelled, postponed) |
|
|
| `where` | Where | group | No | Location details (conditional: for offline/mixed events) |
|
|
| `where.location` | Location | post_object | Yes | Links to Location post |
|
|
| `where.configuration` | Configuration | select | No | Venue configuration |
|
|
| `pricing` | Pricing | group | No | Price information |
|
|
| `pricing.is_free` | Free | true_false | No | Whether event is free |
|
|
| `pricing.min_price` | Minimum price | number | Yes | Minimum price (conditional: if not free) |
|
|
| `registration` | Registration | group | No | Registration details |
|
|
| `registration.form` | Form | select | No | Registration form |
|
|
| `registration.url` | URL | url | No | Registration URL |
|
|
| `registration.email` | Email | email | No | Registration email |
|
|
| `registration.phone` | Phone | acfe_phone_number | No | Registration phone |
|
|
| `notifications` | Notifications | repeater | No | Scheduled notifications |
|
|
| `notifications.date_time` | Date/time | date_time_picker | Yes | When to send notification |
|
|
| `notifications.subject` | Subject | text | Yes | Email subject |
|
|
| `notifications.message` | Message | wysiwyg | Yes | Email message content |
|
|
| `notifications.sent_status` | Sent status | select | Yes | Notification status (planned, sent, failed) |
|
|
|
|
### Social (`group_abstract_social`)
|
|
**Purpose:** Social media profiles
|
|
|
|
| Field Name | Label | Type | Required | Description |
|
|
|------------|-------|------|----------|-------------|
|
|
| `profiles` | Profiles | repeater | No | List of social media profiles |
|
|
| `profiles.url` | URL | url | Yes | Social media profile URL |
|
|
|
|
---
|
|
|
|
## Field Relationships
|
|
|
|
### Post Object Relationships
|
|
- **Event → Representation**: Base events are instantiated through representations
|
|
- **Representation → Event**: Each representation references one base event
|
|
- **Representation → Location**: Event instances specify venue through offer.where.location
|
|
- **Contributor → Credits**: Contributors are linked to events through credits system
|
|
- **Template → Builder**: Templates contain flexible content sections that can be referenced
|
|
|
|
### Taxonomy Relationships
|
|
- **Discipline**: Applied to both `event` and `contributor` CPTs
|
|
- **Resource Category**: Applied to `resource` CPTs only
|
|
- **Project Category**: Applied to `project` CPTs only
|
|
- **Listing Category**: Applied to `listing` CPTs only
|
|
|
|
### Clone Field Usage
|
|
| Abstract Group | Used By CPTs |
|
|
|----------------|--------------|
|
|
| Address City | Contributor (locality) |
|
|
| Address Contact | Profile (contact, billing) |
|
|
| Address Geo | Location (address) |
|
|
| Builder | Project, Template, Page |
|
|
| Contact | Profile (contact, billing) |
|
|
| Credits | Event |
|
|
| Entity | Event, Contributor, Location |
|
|
| Gallery | Event, Contributor, Location |
|
|
| Offer | Representation |
|
|
| Social | Event, Contributor, Location, Options Page |
|
|
|
|
---
|
|
|
|
## Technical Implementation
|
|
|
|
### GraphQL Integration
|
|
- All CPTs enabled for GraphQL with custom single/plural names
|
|
- All fields set `show_in_graphql: 1` for API exposure
|
|
- Required fields use `graphql_non_null: 1` for schema validation
|
|
- Custom GraphQL field names follow camelCase convention
|
|
|
|
### ACF Extended Pro Features
|
|
- **Advanced Address Fields**: Google Places integration, Canada-specific
|
|
- **Phone Number Fields**: Country-specific formatting (Canada)
|
|
- **Language Selection**: Multi-language support with conditional logic
|
|
- **Flexible Content**: Modal editing, preview capabilities
|
|
- **Template System**: Reusable content blocks with clone functionality
|
|
|
|
### Conditional Logic Patterns
|
|
- Address fields hidden for virtual locations (`location_type != 'virtual'`)
|
|
- Language fields hidden for wordless events (`is_wordless != 1`)
|
|
- Billing fields conditional on "same as contact" toggle
|
|
- Pricing fields conditional on free/paid status
|
|
- Schedule layouts vary based on schedule type selection
|
|
|
|
### WordPress Integration
|
|
- Custom rewrite slugs in French for public-facing URLs
|
|
- Hierarchical structure for events and locations
|
|
- Thumbnail and excerpt support for content display
|
|
- Page attributes for ordering and parent-child relationships
|
|
- Translation-ready with `__()` functions and 'ccat' text domain
|
|
|
|
### Performance Considerations
|
|
- Clone fields reduce field duplication and maintain consistency
|
|
- Taxonomy relationships indexed for efficient querying
|
|
- GraphQL schema optimized with proper field exposure
|
|
- Conditional field loading reduces unnecessary data transfer |