Overview
Visual Portfolio supports three primary content sources for building galleries and portfolios. Each source type has its own configuration options and use cases.
Content sources are defined in the content_source control at classes/class-admin.php:1309
Content Source Types
Post-Based Content
Display WordPress posts, pages, custom post types, or portfolio items.
Configuration:
// Located in: classes/class-admin.php:1313
'post-based' => array (
'value' => 'post-based' ,
'title' => esc_html__ ( 'Posts' , 'visual-portfolio' ),
'icon' => '<svg>...</svg>' ,
)
Post Source Options:
Post Types
Post Types Set
Manual Selection
Current Query
Custom Query
Select from available WordPress post types: 'posts_source' => 'post' , // Standard posts
'posts_source' => 'page' , // Pages
'posts_source' => 'portfolio' , // Portfolio items
'posts_source' => 'product' , // WooCommerce products
Query multiple post types simultaneously: 'posts_source' => 'post_types_set' ,
'post_types_set' => array ( 'post' , 'portfolio' , 'page' ),
Hand-pick specific posts by ID: 'posts_source' => 'ids' ,
'posts_ids' => array ( 123 , 456 , 789 ),
Use the current WordPress query (for archives): 'posts_source' => 'current_query' ,
Used in Archive Mapping at classes/class-archive-mapping.php
Build advanced custom queries: 'posts_source' => 'custom_query' ,
'posts_custom_query' => 'post_type=post&posts_per_page=12&orderby=date' ,
Query Controls:
// Taxonomy filters
'posts_taxonomies_' . $taxonomy => array ( term_ids ),
// Author filter
'posts_author' => array ( author_ids ),
// Keyword search
'posts_keyword' => 'search term' ,
// Exclude posts
'posts_excluded_ids' => array ( post_ids ),
'posts_order_by' => 'date' , // date, title, rand, menu_order
'posts_order_direction' => 'DESC' , // DESC or ASC
// Avoid duplicates across multiple portfolios
'posts_avoid_duplicate' => false ,
// Post meta query
'posts_meta_query' => array (
array (
'key' => 'featured' ,
'value' => 'yes' ,
),
),
// Date query
'posts_date_query' => array (
'after' => '2023-01-01' ,
),
Images Content
Display a custom gallery from WordPress Media Library images.
Configuration:
// Located in: classes/class-admin.php:1319
'images' => array (
'value' => 'images' ,
'title' => esc_html__ ( 'Images' , 'visual-portfolio' ),
'icon' => '<svg>...</svg>' ,
)
Image Options:
// Select images from media library
'images' => array (
array (
'id' => 123 ,
'url' => 'https://example.com/image.jpg' ,
'title' => 'Image Title' ,
'description' => 'Image Description' ,
'caption' => 'Image Caption' ,
'alt' => 'Alt Text' ,
),
),
Images source is ideal for creating standalone galleries without requiring post content.
Image Attributes:
id - WordPress attachment ID
url - Full image URL
title - Image title from media library
description - Full image description
caption - Short caption text
alt - Alternative text for accessibility
focal_point - Custom focal point (Pro feature)
Social Stream Content
Display content from social media platforms (Pro feature).
Configuration:
// Located in: classes/class-admin.php:1325
'social-stream' => array (
'value' => 'social-stream' ,
'title' => esc_html__ ( 'Social' , 'visual-portfolio' ),
'icon' => '<svg>...</svg>' ,
)
Social Stream is a premium feature available in Visual Portfolio Pro. See the Pro documentation for details.
Implementation Details
Content Source Registration
// Located in: classes/class-admin.php:1305
Visual_Portfolio_Controls :: register (
array (
'category' => 'content-source' ,
'type' => 'icons_selector' ,
'name' => 'content_source' ,
'setup_wizard' => true ,
'default' => '' ,
'options' => array (
'post-based' => array ( /* ... */ ),
'images' => array ( /* ... */ ),
'social-stream' => array ( /* ... */ ),
),
)
);
Query Building
The Visual_Portfolio_Get class handles query building:
// Located in: classes/class-get-portfolio.php
class Visual_Portfolio_Get {
/**
* Get portfolio query based on options
*/
public static function get_options ( $atts = array () ) {
$id = isset ( $atts [ 'id' ] ) ? $atts [ 'id' ] : false ;
$block_id = isset ( $atts [ 'block_id' ] ) ? $atts [ 'block_id' ] : false ;
// Get registered controls and their values
$registered = Visual_Portfolio_Controls :: get_registered_array ();
// Build result array with attribute values
foreach ( $registered as $item ) {
if ( isset ( $atts [ $item [ 'name' ] ] ) ) {
$result [ $item [ 'name' ] ] = $atts [ $item [ 'name' ] ];
} else {
$result [ $item [ 'name' ] ] = Visual_Portfolio_Controls :: get_registered_value (
$item [ 'name' ],
$block_id ? false : $id
);
}
}
return $result ;
}
}
Archive Mapping
Visual Portfolio can automatically replace WordPress archive pages with portfolio layouts:
// Located in: classes/class-archive-mapping.php
$is_archive_query =
'post-based' === $options [ 'content_source' ] &&
'current_query' === $options [ 'posts_source' ];
Archive Page Setup:
Enable Portfolio Post Type
Enable the Portfolio post type in Settings > General 'register_portfolio_post_type' => 'on' ,
Select Archive Page
Choose a page to serve as your portfolio archive 'portfolio_archive_page' => 42 , // Page ID
Configure Items Per Page
Set pagination for archive: 'archive_page_items_per_page' => 6 ,
Extending Content Sources
Developers can add custom content sources:
add_filter ( 'vpf_extend_posts_source' , function ( $sources ) {
$sources [ 'my_custom_source' ] = array (
'value' => 'my_custom_source' ,
'title' => __ ( 'My Custom Source' , 'text-domain' ),
'icon' => '<svg>...</svg>' ,
);
return $sources ;
});
Content Source Filters
Key filter hooks for content sources:
// Extend available post sources
apply_filters ( 'vpf_extend_posts_source' , array () );
// Filter portfolio options
apply_filters ( 'vpf_get_options' , $result , $atts );
// Filter taxonomy availability for filters
apply_filters ( 'vpf_allow_taxonomy_for_filter' , $allow , $taxonomy );
Related AJAX Endpoints
Content source controls use these REST endpoints:
// Find available post types
class Visual_Portfolio_Admin {
public function find_post_types_options () {
// Returns: array of post type options
}
public function find_posts_select_control ( $attributes , $control ) {
// Returns: array of posts for selection
}
public function find_taxonomies_select_control ( $attributes , $control ) {
// Returns: array of taxonomy terms
}
}
Performance Considerations
Large queries can impact performance. Consider:
Using pagination for post-based content
Limiting items per page
Enabling caching mechanisms
Avoiding complex custom queries when possible
See Also
Portfolio Post Type Learn about the custom Portfolio post type
Layouts Choose the right layout for your content
REST API Query content via REST API
Filters Reference View all available filter hooks