Theme Integration Guide

Theme Integration Guide

Customize WP Sell Services appearance to match your WordPress theme through template overrides, CSS customization, and template hooks.

Template Override System

The plugin uses TemplateLoader (src/Frontend/TemplateLoader.php) to load templates with theme override support. When a template is requested, the loader checks locations in this order:

  1. Child theme: wp-content/themes/child-theme/wp-sell-services/{template}.php
  2. Parent theme: wp-content/themes/parent-theme/wp-sell-services/{template}.php
  3. Plugin default: wp-content/plugins/wp-sell-services/templates/{template}.php

Setting Up Overrides

  1. Create wp-sell-services/ directory in your theme
  2. Copy the template you want to customize from wp-sell-services/templates/
  3. Edit the copied file in your theme directory
  4. Clear page cache and refresh

Only copy templates you need to change. Uncopied templates continue using plugin defaults.

Available Templates

Top-Level Templates

TemplatePurpose
single-service.phpSingle service page
archive-service.phpService archive/listing page
single-request.phpSingle buyer request page
archive-request.phpBuyer request archive page
content-service-card.phpService card in grids and listings
content-request-card.phpBuyer request card in listings
content-no-services.phpEmpty state when no services found
content-no-requests.phpEmpty state when no requests found

Partial Templates (templates/partials/)

TemplatePurpose
partials/service-gallery.phpImage gallery on single service page
partials/service-packages.phpPricing packages (Basic/Standard/Premium)
partials/service-reviews.phpReviews section on single service page
partials/service-faqs.phpFAQ accordion on single service page
partials/vendor-card.phpVendor info card on service page sidebar

Order Templates (templates/order/)

TemplatePurpose
order/order-view.phpOrder details page
order/order-requirements.phpRequirements submission page
order/order-confirmation.phpOrder confirmation/thank you page
order/requirements-form.phpRequirements form template
order/conversation.phpOrder messaging/conversation view

Order URLs route as: /service-order/{id}/ (view), /service-order/{id}/requirements/, /service-order/{id}/delivery/, /service-order/{id}/review/.

Dashboard Templates (templates/dashboard/sections/)

TemplatePurpose
dashboard/sections/orders.phpOrders section
dashboard/sections/sales.phpSales section (vendor)
dashboard/sections/services.phpServices management
dashboard/sections/earnings.phpEarnings section
dashboard/sections/messages.phpMessages section
dashboard/sections/profile.phpProfile editing
dashboard/sections/requests.phpBuyer requests
dashboard/sections/create.phpService creation
dashboard/sections/create-request.phpBuyer request creation

WooCommerce Account Templates (templates/myaccount/)

TemplatePurpose
myaccount/service-orders.phpService orders in WooCommerce My Account
myaccount/vendor-dashboard.phpVendor dashboard in My Account
myaccount/vendor-services.phpVendor services list
myaccount/service-disputes.phpDisputes tab
myaccount/notifications.phpNotifications tab

Other Templates

  • Vendor: vendor/profile.php — Public vendor profile page (served at /vendor/{username}/)
  • Disputes: disputes/dispute-view.php — Dispute details view
  • Emails: emails/ directory contains 13 HTML templates (new-order, order-completed, order-cancelled, order-in-progress, delivery-ready, dispute-opened, new-message, requirements-submitted, requirements-reminder, revision-requested, seller-level-promotion, email-header, email-footer) plus emails/plain/ for plain text variants

Template Functions

// Load a template part (like WP get_template_part but with plugin fallback)
wpss_get_template_part( 'content', 'service-card' );
// Searches: theme/wp-sell-services/content-service-card.php then plugin/templates/

// With arguments
wpss_get_template_part( 'partials/vendor-card', '', [ 'vendor_id' => 42 ] );

// Load a specific template file
wpss_get_template( 'order/order-view.php', [ 'order' => $order ] );

Template Filters

// Redirect template loading without copying files
add_filter( 'wpss_locate_template', function( $template, $template_name, $template_path ) {
    if ( 'single-service.php' === $template_name ) {
        return '/path/to/my/custom-single-service.php';
    }
    return $template;
}, 10, 3 );

// Override a dashboard section template
add_filter( 'wpss_dashboard_section_template', function( $template_path, $section ) {
    if ( 'earnings' === $section ) {
        return get_stylesheet_directory() . '/my-earnings-template.php';
    }
    return $template_path;
}, 10, 2 );

Single Service Page Hooks

The SingleServiceView class (src/Frontend/SingleServiceView.php) renders each section via action hooks. You can add, remove, or reorder sections without overriding the entire template.

Default Hook Registration

HookCallbackPriority
wpsssingleservice_headerrender_breadcrumb5
wpsssingleservice_headerrender_title10
wpsssingleservice_headerrender_meta15
wpsssingleservice_galleryrender_gallery10
wpsssingleservice_contentrender_description10
wpsssingleservice_contentrenderaboutvendor20
wpsssingleservice_faqsrender_faqs10
wpsssingleservice_reviewsrender_reviews10
wpsssingleservice_sidebarrender_packages10
wpsssingleservice_sidebarrendervendorcard20
wpsssingleservice_relatedrenderrelatedservices10
wpssaftersingle_servicerenderordermodal10
wpssaftersingle_servicerendercontactmodal20

Customizing Sections

// Add content after service title (priority 12 = after title at 10, before meta at 15)
add_action( 'wpss_single_service_header', function( $service ) {
    if ( get_post_meta( $service->id, '_wpss_featured', true ) ) {
        echo '<span class="wpss-featured-badge">Featured</span>';
    }
}, 12 );

// Remove FAQ section
remove_action( 'wpss_single_service_faqs', [ wpss()->get_single_service_view(), 'render_faqs' ], 10 );

// Show vendor card before packages (move from priority 20 to 5)
$view = wpss()->get_single_service_view();
remove_action( 'wpss_single_service_sidebar', [ $view, 'render_vendor_card' ], 20 );
add_action( 'wpss_single_service_sidebar', [ $view, 'render_vendor_card' ], 5 );

Dashboard Customization

// Control section access
add_filter( 'wpss_can_access_dashboard_section', function( $allowed, $section, $user_id ) {
    if ( 'earnings' === $section ) {
        return (bool) get_user_meta( $user_id, '_wpss_vendor_verified', true );
    }
    return $allowed;
}, 10, 3 );

// Add custom dashboard sections
add_filter( 'wpss_dashboard_sections', function( $sections, $user_id, $is_vendor ) {
    if ( $is_vendor ) {
        $sections['analytics'] = [ 'label' => 'Analytics', 'icon' => 'chart' ];
    }
    return $sections;
}, 10, 3 );

// Rename section titles
add_filter( 'wpss_dashboard_section_titles', function( $titles ) {
    $titles['orders'] = 'My Purchases';
    $titles['sales']  = 'My Sales';
    return $titles;
} );

CSS Classes Reference

The plugin uses wpss- prefixed CSS classes. Verified classes from SingleServiceView.php:

.wpss-breadcrumb / .wpss-breadcrumb-list / .wpss-breadcrumb-item / .wpss-breadcrumb-current
.wpss-service-title / .wpss-service-meta / .wpss-meta-item
.wpss-meta-vendor / .wpss-meta-rating / .wpss-meta-orders / .wpss-meta-queue
.wpss-vendor-mini-avatar / .wpss-vendor-name / .wpss-verified-badge
.wpss-rating-link / .wpss-rating-value / .wpss-rating-count
.wpss-star / .wpss-star.filled

Enqueued Stylesheets

HandleFilePurpose
wpss-design-systemassets/css/design-system.cssCSS custom properties and tokens
wpss-frontendassets/css/frontend.cssBase frontend styles
wpss-single-serviceassets/css/single-service.cssSingle service page
wpss-unified-dashboardassets/css/unified-dashboard.cssDashboard styles

Overriding Styles

// Enqueue a custom stylesheet after plugin styles
add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_style( 'mytheme-wpss', get_stylesheet_directory_uri() . '/css/wpss-custom.css', [ 'wpss-frontend' ], '1.0.0' );
}, 20 );

// Or dequeue plugin styles entirely
add_action( 'wp_enqueue_scripts', function() {
    wp_dequeue_style( 'wpss-frontend' );
    wp_deregister_style( 'wpss-frontend' );
}, 100 );

JavaScript Integration

HandleFileDependencies
alpinejsassets/js/vendor/alpine.min.jsNone (defer)
wpss-frontendassets/js/frontend.jsalpinejs
wpss-single-serviceassets/js/single-service.jsjquery, wpss-frontend
wpss-unified-dashboardassets/js/unified-dashboard.jsjquery

JavaScript Data Objects

wpss: ajaxUrl, restUrl, nonce

wpssData: ajaxUrl, apiUrl, nonce, orderNonce, restNonce, pollingInterval (10000ms), currencyFormat, i18n

wpssService (single service page only): serviceId, ajaxUrl, nonce, checkoutUrl, cartUrl, i18n

// Add custom scripts after plugin JS
add_action( 'wp_enqueue_scripts', function() {
    wp_enqueue_script( 'mytheme-wpss-js', get_stylesheet_directory_uri() . '/js/wpss-custom.js', [ 'wpss-frontend' ], '1.0.0', true );
}, 20 );

URL Structure

PatternTemplate
/vendor/{username}/vendor/profile.php
/service-order/{id}/order/order-view.php
/service-order/{id}/{action}/order/order-{action}.php
/service/ (default CPT slug)archive-service.php
/buyer-request/ (default CPT slug)archive-request.php

CPT slugs are filterable via wpssserviceslug and wpssbuyerrequest_slug. After adding template overrides, flush rewrite rules by visiting Settings > Permalinks and clicking Save.

Related Documentation

Last updated: February 14, 2026