Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a full community template system to PubPub. Templates are reusable blueprints that capture an entire community configuration: pages, collections, navigation, appearance, starter pubs, default members, and facet overrides. When a user creates a new community through a hub, a template can be applied to scaffold the community with pre-configured content and settings.
What's New
Data Model
CommunityTemplate — A new Sequelize model storing template configuration as structured JSONB fields:
communityOverrides— partial community appearance settings (hero, colors, header, footer branding, social links)pages— array of page blueprints with title, slug, description, visibility, and optional layout blockscollections— array of collection blueprints with kind, visibility, and optional layoutnavigation— slug-based navigation entries (resolved to real IDs at application time)footerLinks— simple title + URL pairsstarterPubs— pub blueprints with optional content (ProseMirror DocJSON) and collection assignmentdefaultMembers— users automatically added to communities with specified permission levelsfacetOverrides— license, citation style, and other facet settingsslug,title,description,avatar,isActive,sourceCommunityId,createdById,hubIdEach template has an optional
hubIdFK establishing a simple one-to-many relationship: a hub owns zero or more templates, and each template belongs to at most one hub. Hub managers have full edit access to their hub's templates.API Routes
Template CRUD
GET/POST /api/communityTemplates— list all / create blank template (superadmin)POST /api/communityTemplates/from-community— clone a template from an existing community by ID or URLGET/PUT/DELETE /api/communityTemplates/:id— read / update / delete a templateHub Integration
GET /api/hubs/:hubId/templates— list templates owned by a hubPOST /api/hubs/:hubId/templates— create a template owned by a hubPOST /api/hubs/:hubId/templates/from-community— clone from community, set hub ownershipGET /api/hubs/:hubId/activeTemplates— public endpoint for active templates (used by community creation flow)Utility
POST /api/communityTemplates/fetch-pub-content— fetch a pub's latest release DocJSON by URL for starter pub content authoringTemplate Application Engine
applyTemplate(template, communityId, actorId)runs after the base community is created and applies the blueprint in order:Template application is non-fatal — errors are caught and logged but the community is always created.
Cloning from Existing Communities
createTemplateFromCommunityloads a community and extracts:communityOverridesThis enables quickly bootstrapping a template from a well-configured community.
Community Creation Integration
The community
createendpoint now accepts an optionaltemplateId:isActiveskipEmail: true) and are auto-approvedEditor UI
TemplateEditorDialog — a large (90vw) Blueprint dialog with 9 tabs:
Features:
SuperAdmin Dashboard (
/dash/super-admin) — table view of all templates with filtering, create/clone actions, and click-to-edit.Hub Manager Dashboard — card-based view of hub templates with create/clone, active toggle, and edit capabilities.
Design Decisions
Circular FK avoidance:
sourceCommunityIdis a plain UUID column (not a Sequelize FK) becauseCommunity.templateIdalready points atCommunityTemplate. A helper function manually fetches the source community data.Slug-based navigation: Templates store nav entries as slug references rather than IDs. At application time, slugs are resolved to newly-created entity IDs. Unresolvable entries are silently dropped.
Simple hub ownership: Each template belongs to at most one hub via a
hubIdFK. No join table — hub managers have direct edit access to all their hub's templates.Lazy imports: Starter pub creation uses dynamic
await import()to avoid circular dependencies with the pub and Firebase modules.Permission upgrade: When a default member is already a community member (e.g. the creator), permissions are only upgraded, never downgraded.
Content resilience: DraftCheckpoint writes for starter pub content are individually try/caught — a failure writing one pub's content doesn't affect others or the overall template application.
Files Changed
New Files
server/communityTemplate/model.ts— Sequelize modelserver/communityTemplate/api.ts— Express routesserver/communityTemplate/queries.ts— Database queries and helpersserver/communityTemplate/applyTemplate.ts— Template application engineclient/components/TemplateEditor/TemplateEditorDialog.tsx— Main editor dialogclient/components/TemplateEditor/TemplateEditorParts.tsx— Editor sub-componentsclient/components/TemplateEditor/templateEditor.scss— Stylesclient/containers/SuperAdminDashboard/CommunityTemplates/CommunityTemplates.tsx— SuperAdmin pageclient/containers/HubData/HubTemplatesTab.tsx— Hub manager tabModified Files
server/community/api.ts— Template application during community creation, hub auto-approvalserver/community/model.ts— AddedtemplateIdFK toCommunityTemplateserver/spamTag/communityQueries.ts— AddedskipEmailoptionserver/models.ts— Registered new modelsserver/apiRoutes.ts— Registered template routes