Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nk-crew/visual-portfolio/llms.txt
Use this file to discover all available pages before exploring further.
Visual Portfolio provides extensive hooks and filters to customize and extend the plugin functionality. All hooks are prefixed with vpf_ to avoid conflicts.
Core Actions
Portfolio Output
vpf_before_get_output
Fires before portfolio output is generated.
do_action( 'vpf_before_get_output', $options );
Parameters:
$options (array) - Portfolio configuration options
Example:
add_action( 'vpf_before_get_output', function( $options ) {
// Custom logic before portfolio renders
error_log( 'Rendering portfolio ID: ' . $options['id'] );
}, 10, 1 );
vpf_after_get_output
Fires after portfolio output is generated.
do_action( 'vpf_after_get_output', $options, $style_options );
Parameters:
$options (array) - Portfolio configuration options
$style_options (array) - Item style specific options
Wrapper Actions
vpf_before_wrapper_start
Fires before the portfolio wrapper opens.
do_action( 'vpf_before_wrapper_start', $options, $style_options );
vpf_after_wrapper_start
Fires after the portfolio wrapper opens.
do_action( 'vpf_after_wrapper_start', $options, $style_options );
vpf_before_wrapper_end
Fires before the portfolio wrapper closes.
do_action( 'vpf_before_wrapper_end', $options, $style_options );
vpf_after_wrapper_end
Fires after the portfolio wrapper closes.
do_action( 'vpf_after_wrapper_end', $options, $style_options );
Items Wrapper Actions
vpf_before_items_wrapper_start
Fires before the items wrapper opens.
do_action( 'vpf_before_items_wrapper_start', $options, $style_options );
vpf_after_items_wrapper_start
Fires after the items wrapper opens.
do_action( 'vpf_after_items_wrapper_start', $options, $style_options );
vpf_before_items_wrapper_end
Fires before the items wrapper closes.
do_action( 'vpf_before_items_wrapper_end', $options, $style_options );
vpf_after_items_wrapper_end
Fires after the items wrapper closes.
do_action( 'vpf_after_items_wrapper_end', $options, $style_options );
Each Item Actions
vpf_before_each_item
Fires before each portfolio item is rendered.
do_action( 'vpf_before_each_item', $args );
Parameters:
$args (array) - Item arguments including post_id, url, title, image_id, etc.
vpf_each_item_start
Fires at the start of each item’s inner content.
do_action( 'vpf_each_item_start', $args );
vpf_each_item_end
Fires at the end of each item’s inner content.
do_action( 'vpf_each_item_end', $args );
vpf_after_each_item
Fires after each portfolio item is rendered.
do_action( 'vpf_after_each_item', $args );
Asset Actions
vpf_before_assets_enqueue
Fires before portfolio assets are enqueued.
do_action( 'vpf_before_assets_enqueue', $options, $layout_id );
Example:
add_action( 'vpf_before_assets_enqueue', function( $options, $layout_id ) {
// Enqueue custom styles for specific layout
if ( $layout_id === 123 ) {
wp_enqueue_style( 'my-custom-portfolio-style' );
}
}, 10, 2 );
vpf_after_assets_enqueue
Fires after portfolio assets are enqueued.
do_action( 'vpf_after_assets_enqueue', $options, $layout_id );
vpf_before_assets_register
Fires before assets are registered.
do_action( 'vpf_before_assets_register' );
vpf_after_assets_register
Fires after assets are registered.
do_action( 'vpf_after_assets_register' );
Core Filters
Layout & Items Style Registration
vpf_extend_layouts
Register custom portfolio layouts.
$layouts = apply_filters( 'vpf_extend_layouts', array() );
Example:
add_filter( 'vpf_extend_layouts', function( $layouts ) {
$layouts['custom_layout'] = array(
'title' => __( 'Custom Layout', 'text-domain' ),
'icon' => '<svg>...</svg>',
'controls' => array(
array(
'type' => 'number',
'label' => __( 'Columns', 'text-domain' ),
'name' => 'custom_layout_columns',
'default' => 3,
'min' => 1,
'max' => 6,
),
),
);
return $layouts;
}, 10 );
vpf_extend_layout__controls
Extend specific layout controls.
$controls = apply_filters( 'vpf_extend_layout_masonry_controls', $controls );
Example:
add_filter( 'vpf_extend_layout_masonry_controls', function( $controls ) {
$controls[] = array(
'type' => 'checkbox',
'label' => __( 'Custom Option', 'text-domain' ),
'name' => 'masonry_custom_option',
'default' => false,
);
return $controls;
}, 10 );
vpf_extend_items_styles
Register custom item styles.
$items_styles = apply_filters( 'vpf_extend_items_styles', array() );
Example:
add_filter( 'vpf_extend_items_styles', function( $items_styles ) {
$items_styles['custom_style'] = array(
'title' => __( 'Custom Style', 'text-domain' ),
'builtin_controls' => array(
'show_title' => true,
'show_categories' => true,
'show_date' => true,
'show_excerpt' => true,
),
'controls' => array(
array(
'type' => 'color',
'label' => __( 'Overlay Color', 'text-domain' ),
'name' => 'items_style_custom_style__overlay_color',
'default' => '#000000',
),
),
);
return $items_styles;
}, 10 );
vpf_extend_item_style__controls
Extend specific item style controls.
$controls = apply_filters( 'vpf_extend_item_style_fade_controls', $controls );
Template Filters
vpf_include_template
Filter template file path.
$template = apply_filters( 'vpf_include_template', $template, $template_name, $args );
Parameters:
$template (string) - Resolved template file path
$template_name (string) - Template name requested
$args (array) - Template arguments
Example:
add_filter( 'vpf_include_template', function( $template, $template_name, $args ) {
// Override specific template
if ( $template_name === 'items-list/items-style/fade/meta' ) {
$custom_template = get_stylesheet_directory() . '/vp-templates/custom-meta.php';
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
}
return $template;
}, 10, 3 );
vpf_include_template_args
Filter template arguments before template is included.
$args = apply_filters( 'vpf_include_template_args', $args, $template_name );
Example:
add_filter( 'vpf_include_template_args', function( $args, $template_name ) {
// Modify template arguments
if ( $template_name === 'items-list/item-parts/title' ) {
$args['custom_data'] = 'Custom value';
}
return $args;
}, 10, 2 );
vpf_allowed_template_dirs
Filter allowed template directories for security.
$allowed_dirs = apply_filters( 'vpf_allowed_template_dirs', $allowed_dirs, $real_path );
Example:
add_filter( 'vpf_allowed_template_dirs', function( $allowed_dirs, $real_path ) {
// Add custom plugin template directory
$allowed_dirs[] = MY_PLUGIN_PATH . 'templates/';
return $allowed_dirs;
}, 10, 2 );
vpf_include_template_style
Filter template style file path.
$path = apply_filters( 'vpf_include_template_style', $path, $template_name, $deps, $ver, $media );
Options & Configuration
vpf_get_options
Filter portfolio options.
$options = apply_filters( 'vpf_get_options', $options, $atts );
Example:
add_filter( 'vpf_get_options', function( $options, $atts ) {
// Modify portfolio options
if ( isset( $options['id'] ) && $options['id'] === 123 ) {
$options['items_gap'] = 20;
}
return $options;
}, 10, 2 );
vpf_extend_options_before_query_args
Filter options before query arguments are built.
$options = apply_filters( 'vpf_extend_options_before_query_args', $options, $layout_id );
vpf_extend_query_args
Filter WP_Query arguments.
$query_opts = apply_filters( 'vpf_extend_query_args', $query_opts, $options, $layout_id );
Example:
add_filter( 'vpf_extend_query_args', function( $query_opts, $options, $layout_id ) {
// Modify query arguments
if ( $layout_id === 123 ) {
$query_opts['meta_query'] = array(
array(
'key' => 'featured',
'value' => '1',
'compare' => '=',
),
);
}
return $query_opts;
}, 10, 3 );
Custom Output
vpf_custom_output
Replace entire portfolio output.
$custom_output = apply_filters( 'vpf_custom_output', false, $uid, $class, $options );
Example:
add_filter( 'vpf_custom_output', function( $custom_output, $uid, $class, $options ) {
// Return custom output for password protected portfolios
if ( post_password_required( $options['id'] ) ) {
return get_the_password_form( $options['id'] );
}
return $custom_output;
}, 10, 4 );
vpf_custom_query_result
Provide custom query result object for non-standard content sources.
$custom_query = apply_filters( 'vpf_custom_query_result', false, $query_opts, $options );
Example:
add_filter( 'vpf_custom_query_result', function( $custom_query, $query_opts, $options ) {
if ( $options['content_source'] === 'custom_api' ) {
// Return custom query-like object
return new Custom_Portfolio_Query( $query_opts );
}
return $custom_query;
}, 10, 3 );
vpf_custom_items
Provide custom items array for non-standard content sources.
$custom_items = apply_filters( 'vpf_custom_items', false, $each_item_args, $query_opts, $options );
Example:
add_filter( 'vpf_custom_items', function( $custom_items, $item_args, $query_opts, $options ) {
if ( $options['content_source'] === 'custom_api' ) {
$api_items = fetch_from_custom_api();
$items = array();
foreach ( $api_items as $api_item ) {
$items[] = array_merge( $item_args, array(
'uid' => $api_item['id'],
'title' => $api_item['title'],
'url' => $api_item['link'],
'image_id' => $api_item['image_id'],
) );
}
return $items;
}
return $custom_items;
}, 10, 4 );
Item Arguments
vpf_each_item_args
Filter item arguments before rendering.
$args = apply_filters( 'vpf_each_item_args', $args );
Example:
add_filter( 'vpf_each_item_args', function( $args ) {
// Add custom data to each item
if ( $args['post_id'] ) {
$args['custom_field'] = get_post_meta( $args['post_id'], 'custom_field', true );
}
return $args;
}, 10 );
vpf_post_item_args
Filter post-based item arguments.
$args = apply_filters( 'vpf_post_item_args', $args, $post_id );
vpf_image_item_args
Filter image-based item arguments.
$args = apply_filters( 'vpf_image_item_args', $args, $img );
vpf_each_item_tag_name
Filter item wrapper tag name.
$tag_name = apply_filters( 'vpf_each_item_tag_name', $tag_name, $args );
Example:
add_filter( 'vpf_each_item_tag_name', function( $tag_name, $args ) {
// Use article tag for blog posts
if ( isset( $args['post_id'] ) && get_post_type( $args['post_id'] ) === 'post' ) {
return 'article';
}
return $tag_name;
}, 10, 2 );
vpf_each_item_tag_attrs
Filter item wrapper tag attributes.
$attrs = apply_filters( 'vpf_each_item_tag_attrs', $attrs, $args );
Example:
add_filter( 'vpf_each_item_tag_attrs', function( $attrs, $args ) {
// Add custom data attribute
if ( isset( $args['post_id'] ) ) {
$attrs['data-post-type'] = get_post_type( $args['post_id'] );
}
return $attrs;
}, 10, 2 );
Data Attributes & Classes
vpf_extend_portfolio_data_attributes
Filter portfolio wrapper data attributes.
$data_attrs = apply_filters( 'vpf_extend_portfolio_data_attributes', $data_attrs, $options, $style_options );
Example:
add_filter( 'vpf_extend_portfolio_data_attributes', function( $data_attrs, $options, $style_options ) {
// Add custom data attribute
$data_attrs['data-custom-attr'] = 'custom-value';
return $data_attrs;
}, 10, 3 );
vpf_extend_portfolio_class
Filter portfolio wrapper CSS classes.
$class = apply_filters( 'vpf_extend_portfolio_class', $class, $options, $style_options );
Example:
add_filter( 'vpf_extend_portfolio_class', function( $class, $options, $style_options ) {
// Add custom class
if ( $options['layout'] === 'masonry' ) {
$class .= ' custom-masonry-class';
}
return $class;
}, 10, 3 );
vpf_extend_portfolio_items_class
Filter portfolio items wrapper CSS classes.
$items_class = apply_filters( 'vpf_extend_portfolio_items_class', $items_class, $options, $style_options );
Filter & Sort
vpf_allow_taxonomy_for_filter
Determine if taxonomy should be available in filter.
$allowed = apply_filters( 'vpf_allow_taxonomy_for_filter', $default_allowed, $taxonomy );
Example:
add_filter( 'vpf_allow_taxonomy_for_filter', function( $allowed, $taxonomy ) {
// Allow custom taxonomy in filter
if ( $taxonomy === 'custom_taxonomy' ) {
return true;
}
return $allowed;
}, 10, 2 );
vpf_custom_filter_terms
Provide custom filter terms.
$terms = apply_filters( 'vpf_custom_filter_terms', false, $query_opts, $active_item, $vp_options );
vpf_extend_filter_items
Filter the filter items array.
$items = apply_filters( 'vpf_extend_filter_items', $items, $vp_options );
Filter popup gallery data output.
$popup_output = apply_filters( 'vpf_popup_output', $popup_output, $args );
Provide custom popup image data.
$popup_image = apply_filters( 'vpf_popup_custom_image_data', false, $image_id );
Lazy Loading
vpf_images_lazyload
Enable or disable lazy loading.
$lazyload = apply_filters( 'vpf_images_lazyload', true );
Example:
add_filter( 'vpf_images_lazyload', function( $lazyload ) {
// Disable lazy loading on specific pages
if ( is_front_page() ) {
return false;
}
return $lazyload;
}, 10 );
vpf_lazyload_images_blocked_classes
Filter CSS classes that should prevent lazy loading.
$blocked_classes = apply_filters( 'vpf_lazyload_images_blocked_classes', $blocked_classes );
vpf_lazyload_images_blocked_src
Filter image sources that should prevent lazy loading.
$blocked_src = apply_filters( 'vpf_lazyload_images_blocked_src', $blocked_src );
Controls & Settings
vpf_register_control
Filter control arguments when registering.
$args = apply_filters( 'vpf_register_control', $args, $name );
vpf_registered_controls
Filter all registered controls.
$controls = apply_filters( 'vpf_registered_controls', $controls );
vpf_control_value
Filter control value when retrieved.
$value = apply_filters( 'vpf_control_value', $value, $name, $post_id );
Example:
add_filter( 'vpf_control_value', function( $value, $name, $post_id ) {
// Modify specific control value
if ( $name === 'items_gap' && $post_id === 123 ) {
return 30;
}
return $value;
}, 10, 3 );
Breakpoints
vpf_breakpoint_xs
Filter extra small breakpoint value.
$breakpoint = apply_filters( 'vpf_breakpoint_xs', 576 );
vpf_breakpoint_sm
Filter small breakpoint value.
$breakpoint = apply_filters( 'vpf_breakpoint_sm', 768 );
vpf_breakpoint_md
Filter medium breakpoint value.
$breakpoint = apply_filters( 'vpf_breakpoint_md', 992 );
vpf_breakpoint_lg
Filter large breakpoint value.
$breakpoint = apply_filters( 'vpf_breakpoint_lg', 1200 );
vpf_breakpoint_xl
Filter extra large breakpoint value.
$breakpoint = apply_filters( 'vpf_breakpoint_xl', 1400 );
Plugin Assets
vpf_enqueue_plugin_isotope
Control Isotope library enqueue.
$enqueue = apply_filters( 'vpf_enqueue_plugin_isotope', true );
vpf_enqueue_plugin_photoswipe
Control PhotoSwipe library enqueue.
$enqueue = apply_filters( 'vpf_enqueue_plugin_photoswipe', true );
vpf_enqueue_plugin_fancybox
Control Fancybox library enqueue.
$enqueue = apply_filters( 'vpf_enqueue_plugin_fancybox', true );
vpf_enqueue_plugin_swiper
Control Swiper library enqueue.
$enqueue = apply_filters( 'vpf_enqueue_plugin_swiper', true );
Common Use Cases
Adding Custom Portfolio Layout
add_filter( 'vpf_extend_layouts', function( $layouts ) {
$layouts['custom_carousel'] = array(
'title' => __( 'Custom Carousel', 'text-domain' ),
'icon' => '<svg width="20" height="20">...</svg>',
'controls' => array(
array(
'type' => 'number',
'label' => __( 'Slides Per View', 'text-domain' ),
'name' => 'custom_carousel_slides',
'default' => 3,
'min' => 1,
'max' => 10,
),
array(
'type' => 'checkbox',
'label' => __( 'Auto Play', 'text-domain' ),
'name' => 'custom_carousel_autoplay',
'default' => true,
),
),
);
return $layouts;
}, 10 );
Modifying Item Output
// Add custom field to item args
add_filter( 'vpf_post_item_args', function( $args, $post_id ) {
$args['rating'] = get_post_meta( $post_id, 'product_rating', true );
return $args;
}, 10, 2 );
// Display custom field in template
add_action( 'vpf_each_item_end', function( $args ) {
if ( ! empty( $args['rating'] ) ) {
echo '<div class="custom-rating">' . esc_html( $args['rating'] ) . '</div>';
}
}, 10 );
Custom Content Source
// Provide custom query
add_filter( 'vpf_custom_query_result', function( $custom_query, $query_opts, $options ) {
if ( $options['content_source'] === 'woocommerce_products' ) {
$query_opts['post_type'] = 'product';
return new WP_Query( $query_opts );
}
return $custom_query;
}, 10, 3 );
// Modify custom items
add_filter( 'vpf_post_item_args', function( $args, $post_id ) {
if ( get_post_type( $post_id ) === 'product' ) {
$product = wc_get_product( $post_id );
$args['price'] = $product->get_price_html();
}
return $args;
}, 10, 2 );
Override Template Location
add_filter( 'vpf_include_template', function( $template, $template_name, $args ) {
// Check custom location first
$custom_template = get_stylesheet_directory() . '/visual-portfolio-templates/' . $template_name . '.php';
if ( file_exists( $custom_template ) ) {
return $custom_template;
}
return $template;
}, 10, 3 );
Best Practices
- Always check parameters - Verify options and IDs before modifying data
- Return original value - Always return the original value if your conditions aren’t met
- Use appropriate priority - Default is 10, use lower for earlier execution
- Sanitize and escape - Always sanitize input and escape output for security
- Check dependencies - Verify required data exists before accessing it
- Use namespacing - Prefix your function names to avoid conflicts
- Document your code - Add comments explaining custom logic
Security Considerations
- Always use
wp_verify_nonce() when handling form submissions
- Sanitize user input with appropriate WordPress functions
- Escape output using
esc_html(), esc_attr(), esc_url(), etc.
- Check user capabilities with
current_user_can()
- Validate file paths when working with templates
Related Resources