'light',
'is_directory' => false, //as in, a membership directory
'has_membership' => false,
'has_map' => true,
'dashboard' => true,
'has_support' => true,
'use_feed_block' => true,
'email_notifications' => true,
'integrations' => [
'bluesky' => true,
'cloudflare' => true,
'facebook' => false,
'maps' => true,
'gmb' => true,
'helcim' => false,
'instagram' => false,
'square' => true,
'umami' => true,
],
// 'is_restaurant' => false,
// 'limit_hours' => false,
// 'enthusiast' => true,
// 'favourites' => true, //optional flag to allow enthusiasts, but not favourites
];
}
/**
* JVB_MEMBERSHIP defines the structure of the directory
* Options include:
* - membership_expires = useful if members pay a yearly membership fee
* - hide_expired = removes users once membership expired; only used if membership_expires is true
* - clip_expired = keeps users once membership expires, but limits the information shown; only used if membership_expires is true
* - membership_approval = verified users can approve other users
* - term_approval = (bool) verified users can create new terms, but needs approval
* - member_only = (array) if empty, open to any registered user. otherwise an array of registered user roles
*/
//add_filter('jvb_membership', 'altr_setup_membership');
//function altr_setup_membership():array
//{
// return [
// 'member_content' => true,
// 'can_invite' => ['artist' => ['artist']],
// 'member_verified' => true,
// 'notifications' => true,
// 'forum' => true,
// 'member_only' => [ 'artist' ],
// 'member_expires' => false,
// 'hide_expired' => false,
// 'clip_expired' => false,
// 'term_approval' => true,
// 'can_approve' => [ 'artist' ]
// ];
//}
add_filter('jvbLoadingQuips', 'altr_loading_quips');
function altr_loading_quips(array $quips): array
{
return [];
}
// /content/art.php
function altr_art(): array
{
return [
'singular' => 'Art',
'plural' => 'Art',
'dash_title' => 'Art',
'dash_description' => 'Manage your art posts',
'breadcrumb' => 'Art',
'hide_single' => false,
'show_feed' => true,
'favouritable' => true,
'karma' => false,
'icon' => 'artwork',
'rewrite' => [
'slug' => 'art',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'featured_image' => [
'type' => 'image',
'label' => 'Image',
],
'gallery' => [
'type' => 'gallery',
'label' => 'Gallery',
],
'price' => [
'type' => 'number',
'label' => 'Price',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Notes'
]
],
'single_image' => false,
'upload_title' => 'Upload Artwork',
];
}
// /content/design.php
function altr_design(): array
{
return [
'singular' => 'Graphic Design',
'plural' => 'Designs',
'hide_single' => false,
'redirectToAuthor' => false,
'show_feed' => true,
'favouritable' => true,
'karma' => false,
'icon' => 'artwork',
'rewrite' => [
'slug' => 'design',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'featured_image' => [
'type' => 'image',
'label' => 'Image',
],
'gallery' => [
'type' => 'gallery',
'label' => 'Gallery',
],
'price' => [
'type' => 'number',
'label' => 'Price',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Notes'
]
],
'single_image' => false,
'upload_title' => 'Upload Artwork',
];
}
// /content/development.php
function altr_development(): array
{
return [
'singular' => 'Development',
'plural' => 'Developments',
'hide_single' => false,
'redirectToAuthor' => false,
'show_feed' => true,
'favouritable' => true,
'karma' => false,
'icon' => 'brackets-angle',
'rewrite' => [
'slug' => 'development',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'featured_image' => [
'type' => 'image',
'label' => 'Image',
],
'gallery' => [
'type' => 'gallery',
'label' => 'Gallery',
],
'price' => [
'type' => 'number',
'label' => 'Price',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Notes'
]
],
'single_image' => false,
'upload_title' => 'Upload Artwork',
];
}
// /content/setup.php
/**
* JVB_CONTENT: Base post type definitions
* Structure: [ 'slug' => [$options], ]
* Note: slug is prepended with BASE in registration
* $options includes:
* - any $args from register_post_type
* - single and plural labels (string)
* - hide_single = (bool) if true, only show posts on author page, not on is_singular() view
* - show_feed = (bool) if true, becomes one of the content types shown in feed block
* - show_directory= (bool) if true, creates an alphabetical list directory page
* - karma = (bool) if true, sets up upvotes/downvotes system
* - favouritable = (bool)
* - responses = (bool) if true, sets up comments and replies
* - is_calendar = (bool) if true, sets up default calendar functionality
* - single_image = (bool) if true, and dashboard is setup, each image becomes its own post
* - upload_title = (string)),
* - rewrites = (array) key = associated taxonomy; value = what to append to rewrite base
* - description = (array) strings for login description of type
* -dash_title = (string) customize the title for custom dashboard
* - dash_description = (string) customize the description for custom dashboard
* - directory_extra = (array) of BASEless slugs of taxonomies to link in directory
* - sections = (array) 'slug' => $options, where options include ['label' => $label, 'icon' => $iconSlug]; used to split large groups of fields into tabs on the edit page
* - fields = (array) of fields, as defined in MetaManager.php, as well as additional options:
* - 'quickEdit' => (bool) whether this field can be edited in the custom administrator dashboard (best for text fields)
* - 'section' => (string) the slug of the section, as defined above
*/
require(AJV_DIR . '/content/art.php');
require(AJV_DIR . '/content/design.php');
require(AJV_DIR . '/content/development.php');
require(AJV_DIR . '/content/strategy.php');
require(AJV_DIR . '/content/support.php');
require(AJV_DIR . '/content/writing.php');
add_filter('jvb_content', 'altr_content');
function altr_content($content): array
{
return [
'design' => altr_design(),
'development' => altr_development(),
'strategy' => altr_strategy(),
'art' => altr_art(),
'writing' => altr_writing(),
'support' => altr_support(),
];
}
// /content/strategy.php
function altr_strategy(): array
{
return [
'singular' => 'Strategy',
'plural' => 'Strategies',
'hide_single' => false,
'redirectToAuthor' => false,
'show_feed' => true,
'favouritable' => true,
'karma' => false,
'icon' => 'brain',
'rewrite' => [
'slug' => 'strategy',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'featured_image' => [
'type' => 'image',
'label' => 'Image',
],
'gallery' => [
'type' => 'gallery',
'label' => 'Gallery',
],
'price' => [
'type' => 'number',
'label' => 'Price',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Notes'
]
],
'single_image' => false,
'upload_title' => 'Upload Artwork',
];
}
// /content/support.php
function altr_support(): array
{
return [
'singular' => 'Support',
'plural' => 'Support',
'hide_single' => false,
'show_feed' => false,
'icon' => 'life-ring',
'rewrite' => [
'slug' => 'support',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Content'
]
],
];
}
// /content/writing.php
function altr_writing(): array
{
return [
'singular' => 'Writing',
'plural' => 'Writings',
'hide_single' => false,
'redirectToAuthor' => false,
'show_feed' => true,
'favouritable' => true,
'karma' => false,
'icon' => 'pen-nib',
'rewrite' => [
'slug' => 'writing',
'with_front' => false,
],
'fields' => [
'post_title' => [
'type' => 'text',
'label' => 'Title',
],
'featured_image' => [
'type' => 'image',
'label' => 'Image',
],
'gallery' => [
'type' => 'gallery',
'label' => 'Gallery',
],
'price' => [
'type' => 'number',
'label' => 'Price',
],
'post_content' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Notes'
]
],
'single_image' => false,
'upload_title' => 'Upload Artwork',
];
}
// /login/setup.php
add_filter('jvb_login', 'altr_setup_login');
function altr_setup_login(): array
{
return [
'login_from_favourite_header' => 'Join the scene; keep your collection.',
'login_header' => 'Log in',
'join_header' => 'Join in',
'from_favourites_benefits' => [
'Save designs you love',
'Get personalized recommendations',
'Connect with artists',
'Build your inspiration collection',
'Bonus: It\'s all free!'
]
];
}
// /taxonomies/city.php
function altr_city(): array
{
return [
'singular' => 'City',
'plural' => 'Cities',
'icon' => 'city',
'description' => [
'From Edmonton, yes - but also throughout Alberta.'
],
'show_feed' => true,
'show_directory' => true,
'approve_new' => false,
'rewrite' => [
'slug' => 'in',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art',
'design',
'development',
'strategy',
'writing',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki']
]
];
}
// /taxonomies/form.php
function altr_form(): array
{
return [
'singular' => 'Form',
'plural' => 'Forms',
'description' => [
'From paintings to sculptures.'
],
'icon' => 'shapes',
'show_feed' => true,
'show_directory' => false,
'approve_new' => false,
'rewrite' => [
'slug' => 'form',
'with_front' => false,
],
'for_content' => [
'art',
'design',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki']
]
];
}
// /taxonomies/media.php
function altr_media(): array
{
return [
'singular' => 'Medium',
'plural' => 'Media',
'description' => [
'What it\'s made of.',
'From clay to oil paints'
],
'icon' => 'media',
'show_feed' => true,
'show_directory' => true,
'approve_new' => true,
'rewrite' => [
'slug' => 'media',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art'
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki']
]
];
}
// /taxonomies/progress.php
function altr_progress(): array
{
return [
'singular' => 'Progress',
'plural' => 'Progress',
'icon' => 'circle-notch',
'show_feed' => true,
'show_directory' => true,
'approve_new' => false,
'rewrite' => [
'slug' => 'progress',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art',
'design',
'development',
'strategy',
'writing',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki']
]
];
}
// /taxonomies/setup.php
/**
* JVB_TAXONOMY : defines the custom taxonomies
* structure: slug => [$options]
* Note: slug is prepended with BASE
* $options includes:
* - any $args from register_taxonomy
* - (string) singular and plural labels
* - show_feed = (bool) whether to show in feed block
* - show_directory = (bool) whether to output a directory for this taxonomy
* - is_content = (bool) if true, sets it up to be more like a content type, but collects other content types
* - is_ownable = (bool) if true, allows defined users to manage
* - karma = (bool) if true, sets up upvotes/downvotes system
* - verify_entry = (bool) if true, users not already attached to this taxonomy need to be approved before entry.
* - approve_new = (bool) if true, admin/verified users need to approve before 'live'
* - track_changes = (bool) if true, table is created to track historical changes
* - for_content = (array) of post type slugs, as defined in JVB_CONTENT
* - fields = (array) of custom field definitions, from inc/managers/MetaManager.php
* -> add use_in_stats (bool) to use the field in user statistics
*/
require(AJV_DIR . '/taxonomies/city.php');
require(AJV_DIR . '/taxonomies/form.php');
require(AJV_DIR . '/taxonomies/media.php');
require(AJV_DIR . '/taxonomies/progress.php');
require(AJV_DIR . '/taxonomies/style.php');
require(AJV_DIR . '/taxonomies/target.php');
require(AJV_DIR . '/taxonomies/theme.php');
add_filter('jvb_taxonomy', 'altr_taxonomy');
function altr_taxonomy(): array
{
return [
'city' => altr_city(),
'style' => altr_style(),
'theme' => altr_theme(),
'form' => altr_form(),
'medium' => altr_media(),
'target' => altr_target(),
'progress' => altr_progress(),
];
}
// /taxonomies/style.php
function altr_style(): array
{
return [
'directory' => 'Styles',
'description' => [
'From American Traditional to Japanese.'
],
'singular' => 'Style',
'plural' => 'Styles',
'show_directory' => true,
'approve_new' => false,
'icon' => 'folder',
'favouritable' => true,
'show_feed' => true,
'rewrite' => [
'slug' => 'style',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art',
'design',
'development',
'strategy',
'writing',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki', 'alternate_name', 'keywords']
]
];
}
// /taxonomies/target.php
function altr_target(): array
{
return [
'singular' => 'Target Audience',
'plural' => 'Target Audiences',
'icon' => 'crosshair-simple',
'show_feed' => false,
'rewrite' => [
'slug' => 'target',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art',
'design',
'development',
'strategy',
'writing',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'common' => ['wiki']
]
];
}
// /taxonomies/theme.php
function altr_theme(): array
{
return [
'directory' => 'Themes',
'show_directory' => true,
'isGrouped' => true,
'description' => [
'What makes up the tattoo, asides from style.',
'From bees to ideas to carrots.'
],
'singular' => 'Theme',
'plural' => 'Themes',
'icon' => 'hash',
'favouritable' => true,
'show_feed' => true,
'approve_new' => false,
'rewrite' => [
'slug' => 'themes',
'with_front' => false,
'hierarchical' => true,
],
'hierarchical' => true,
'for_content' => [
'art',
'design',
'development',
'strategy',
'writing',
],
'fields' => [
'term_name' => [
'label' => 'Name',
'type' => 'text',
'quickEdit' => true,
],
'similar' => [
'type' => 'taxonomy',
'taxonomy_type' => 'reference',
'taxonomy' => 'theme',
'label' => 'Similar Themes',
],
'description' => [
'type' => 'textarea',
'quill' => true,
'label' => 'Description',
],
'archive_title' => [
'type' => 'text',
'label' => 'Archive Title',
'description' => 'If the generated title does not jive, set it here',
],
'common' => ['wiki', 'alternate_name', 'keywords']
]
];
}
// /users/client.php
function altr_user_client(): array
{
return [
'label' => 'Client',
'has_dashboard' => true,
'can_create' => ['support'],
'can_register' => true,
'keep_stats' => true,
'join_text' => 'Save your favourites. Get Notified.',
'join_title' => 'Welcome to the Scene.',
'join_description' => [
'Save your favourites for easy access',
'Get notified when your favourite artists add new content',
'Stay in the loop with local flash days and events',
'Discover styles and artists that match your vision'
],
'join_bonus' => 'BONUS: Everything\'s free. And always will be. We work with partners vetted by the community to keep the lights on.',
];
}
// /users/enthusiast.php
function altr_user_enthusiast(): array
{
return [
'label' => 'Enthusiast',
'has_dashboard' => true,
'can_create' => [],
'can_register' => true,
'keep_stats' => true,
'join_text' => 'Save your favourites. Get Notified.',
'join_title' => 'Welcome to the Scene.',
'join_description' => [
'Save your favourites for easy access',
'Get notified when your favourite artists add new content',
'Stay in the loop with local flash days and events',
'Discover styles and artists that match your vision'
],
'join_bonus' => 'BONUS: Everything\'s free. And always will be. We work with partners vetted by the community to keep the lights on.',
];
}
// /users/setup.php
/**
* JVB_USER -> defines user roles. Mainly for Dashboard/Directory sites
* Structure: slug => $options
* Note: slug is prepended with BASE
* $options includes:
* - has_dashboard = user has access to custom dashboard
* - can_create = (array) of post types and taxonomies they can create
* --> Optionally, if the user is split between types (example: tattoo artist vs piercer), you can define types here.
* ex: [
* ['tattoo-artist' => ['tattoo', 'artwork']],
* ['piercer' => ['piercing', 'artwork']],
* ]
* - manage_others = (array) of post types this role can manage other users items
* - can_register = (bool) if true, this user can self register
* - profile = (string) associated post type to treat as archive page, as registered in JVB_CONTENT
* - register_fields = (array) of field names available in registration, as defined in settings OR associated profile JVB_CONTENT
* - approve_new = (bool) if true, user content is hidden until verified by admin/other verified users
* - keep_stats = (bool) if true, creates a statistics table that tracks how much content is created per user per day
* - settings = (array) of fields users can modify
* - admin = (array) of fields admin/moderators can modify, attached to user
* - register = (array) of field names as defined in settings that are on registration, if can_register === true
* - description = (array|string) if an array, each item in array will be it's own paragraph
* -> description of the user role. Used in the registration page
*/
require(AJV_DIR . '/users/client.php');
require(AJV_DIR . '/users/enthusiast.php');
add_filter('jvb_user', 'altr_user');
function altr_user():array
{
return [
'enthusiast' => altr_user_enthusiast(),
'client' => altr_user_client(),
];
}