### Install Core Webasyst Applications Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Bash commands to clone essential Webasyst applications into the development environment. These applications provide core functionality like Site, Shop, CRM, etc. ```bash # Clone required applications git clone https://github.com/webasyst/shop-script.git wa-apps/shop git clone https://github.com/webasyst/helpdesk.git wa-apps/helpdesk git clone https://github.com/webasyst/crm.git wa-apps/crm git clone https://github.com/webasyst/mailer.git wa-apps/mailer git clone https://github.com/webasyst/hub.git wa-apps/hub ``` -------------------------------- ### PHP Controller for Product Data Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Example PHP code demonstrating a controller action in Webasyst. It fetches product data and assigns it to the Smarty view for rendering. ```php // PHP Controller (handles business logic) class shopFrontendProductAction extends waViewAction { public function execute() { $product_id = waRequest::get('id', 0, waRequest::TYPE_INT); $product = new shopProduct($product_id); $this->view->assign([ 'product' => $product, 'categories' => $product->getCategories(), 'features' => $product->getFeatures(), ]); } } ``` -------------------------------- ### Configure Apache Virtual Host Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Example Apache configuration for setting up a local virtual host for Webasyst development. Ensures correct routing to the framework's document root. ```apache ServerName webasyst.local DocumentRoot /path/to/webasyst-dev AllowOverride All Require all granted ``` -------------------------------- ### Clone Webasyst Framework Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Instructions to download the Webasyst framework using Git. This is the first step in setting up a local development environment. ```bash git clone https://github.com/webasyst/webasyst-framework.git webasyst-dev cd webasyst-dev ``` -------------------------------- ### Create Webasyst Theme Directory Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Command-line instructions to create the necessary directory structure for a new Webasyst theme. ```bash mkdir wa-data/public/yourdomain.com/themes/mytheme cd wa-data/public/yourdomain.com/themes/mytheme ``` -------------------------------- ### Smarty Template for Product Display Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Example Smarty template code for displaying product details. It uses variables assigned from the PHP controller to render product name, price, and features. ```smarty {* Smarty Template (handles presentation) *}

{$product.name|escape}

{shop_currency}{$product.price}
{foreach $product.features as $feature}
{$feature.name}: {$feature.value}
{/foreach}
``` -------------------------------- ### Basic Webasyst Theme Files Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Essential files for a minimal Webasyst theme, including a simplified theme manifest, layout template, index page, CSS, and JavaScript. ```xml My First Theme Learning Webasyst theme development Your Name 1.0.0 ``` ```smarty {$wa->title()} {$wa->meta()} {$wa->header()}

My First Theme

{$content}
{$wa->js()} ``` ```smarty

Welcome to My Website

This is the homepage content.

{* Display available applications *}
{foreach $wa->apps() as $app} {if $app.available}

{$app.name}

{$app.description}

Open {$app.name}
{/if} {/foreach}
``` ```css /* Basic theme styles */ body { font-family: Arial, sans-serif; margin: 0; padding: 0; line-height: 1.6; } header { background: #333; color: white; padding: 1rem; } nav a { color: white; text-decoration: none; margin-right: 1rem; } main { padding: 2rem; min-height: 60vh; } .apps-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1rem; margin-top: 2rem; } .app-card { border: 1px solid #ddd; padding: 1rem; border-radius: 4px; } .btn { display: inline-block; background: #007cba; color: white; padding: 0.5rem 1rem; text-decoration: none; border-radius: 4px; } footer { background: #f8f9fa; text-align: center; padding: 1rem; } ``` ```javascript document.addEventListener('DOMContentLoaded', function() { console.log('My First Theme loaded'); // Add any interactive functionality here const appCards = document.querySelectorAll('.app-card'); appCards.forEach(card => { card.addEventListener('mouseenter', function() { this.style.transform = 'scale(1.02)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'scale(1)'; }); }); }); ``` -------------------------------- ### Webasyst Theme Manifest (theme.xml) Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md Defines the metadata and structure for a Webasyst theme, including its ID, name, description, author, version, and required applications. ```xml My Custom Theme Моя Тема A custom theme for Webasyst Your Name Your Company 1.0.0 ``` -------------------------------- ### Create and Grant Database Privileges Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/01-getting-started.md SQL commands to create a new database for Webasyst development and grant necessary privileges to a user. Essential for application data storage. ```sql CREATE DATABASE webasyst_dev CHARACTER SET utf8 COLLATE utf8_general_ci; GRANT ALL PRIVILEGES ON webasyst_dev.* TO 'webasyst'@'localhost' IDENTIFIED BY 'password'; ``` -------------------------------- ### Shop-Script Product Functions Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Provides examples for accessing and displaying product information from the Shop-Script application. Includes fetching products, formatting prices, displaying images, variants, and features. ```smarty {* Get product by ID *} {$product = $wa->shop->getProduct($product_id)} {* Product price formatting *} {$product.price|wa_currency} {$product.price|wa_currency:$product.currency} {* Product images *} {$product.name|escape} {* Product variants *} {foreach $product.skus as $sku}
{$sku.price|wa_currency} {$sku.count} in stock
{/foreach} {* Product features *} {foreach $product.features as $feature}
{$feature.name}: {$feature.value}
{/foreach} ``` -------------------------------- ### Webasyst theme.xml Configuration Example Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/02-template-structure-organization.md This XML snippet demonstrates a complete `theme.xml` file for a Webasyst theme. It includes metadata, application requirements, file inclusions, and customizable settings. ```xml Professional Business Theme Профессиональная Бизнес Тема A comprehensive business theme for Webasyst applications Комплексная бизнес-тема для приложений Webasyst Your Company Your Company Ltd. 2.1.0 2024010301 Color Scheme Layout Width Show Breadcrumbs preview.jpg icon.png ``` -------------------------------- ### Check Application Existence Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Checks if a specific application is installed and available in the Webasyst environment. Used for conditionally displaying links or features. ```smarty {if $wa->appExists('shop')} Shop {/if} {if $wa->appExists('blog')} Blog {/if} ``` -------------------------------- ### Webasyst Smarty URL Generation Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Demonstrates how to generate application and dynamic URLs within Webasyst themes using Smarty. Includes examples for linking to applications, products, categories, and search results with URL encoding. ```smarty {* Application URLs *} {_w('Shop')} {_w('Home')} {_w('Blog')} {* Dynamic URLs *} {$product.name} {$category.name} {* URLs with parameters *} {_w('Search results')} ``` -------------------------------- ### Webasyst Smarty Route Information Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Shows how to retrieve and utilize current route information in Webasyst themes. Examples include getting the current route object, its parameters, and checking specific route IDs for conditional rendering. ```smarty {* Current route *} {$current_route = $wa->currentRoute()} {* Route parameters *} {$route_params = $wa->currentRoute('params')} {* Check specific route *} {if $wa->currentRoute('id') == 'product'}
Product page content
{/if} ``` -------------------------------- ### Get Page Title Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Retrieves the page title for the current context. Can be used directly or with a fallback using the default modifier. ```smarty {$wa->title()} {* Custom title with fallback *} {$wa->title()|default:"Welcome to My Store"} ``` -------------------------------- ### Complete Product Page Template Example (Smarty) Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md This Smarty template demonstrates a full product page structure. It includes sections for breadcrumbs, product images, pricing, descriptions, features, an add-to-cart form with variants, and social sharing links. It assumes availability of variables like $breadcrumbs, $product, and $wa. ```smarty {* Complete product page template example *}
{* Breadcrumbs *} {if $breadcrumbs} {/if}
{$product.name|escape}
{if $product.images} {/if}

{$product.name}

{$product.price|wa_currency:$product.currency}
{if $product.description}
{$product.description}
{/if} {* Product features *} {if $product.features}

{_w('Specifications')}

{foreach $product.features as $feature}
{$feature.name}:
{$feature.value}
{/foreach}
{/if} {* Add to cart form *}
{$wa->csrf()} {* Product variants *} {if $product.skus}
{foreach $product.skus as $sku} {/foreach}
{/if}
{* Social sharing *}

{_w('Share this product:')}

``` -------------------------------- ### Theme Development Project Structure Example Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/08-hypermarket-theme-analysis.md Illustrates a standard project directory structure for theme development. It separates source files (SCSS, JS, templates), compiled distribution files, and build tools like Webpack and Gulp. This structure promotes organization and maintainability. ```Shell theme-development/ ├── src/ # Source files │ ├── scss/ # SCSS source files │ ├── js/ # JavaScript source files │ └── templates/ # Template source files ├── dist/ # Compiled theme files │ ├── css/ │ ├── js/ │ └── templates/ ├── tools/ # Build tools │ ├── webpack.config.js │ ├── package.json │ └── gulpfile.js └── README.md ``` -------------------------------- ### Get Theme Settings Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/08-hypermarket-theme-analysis.md Retrieves the current theme settings stored in the application's storage. If no settings are found, it returns an empty array. ```PHP return wa()->storage()->read('theme_settings') ?: array(); ``` -------------------------------- ### Get Current Locale Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Returns the current locale code (e.g., 'en_US', 'ru_RU'). Essential for internationalization and displaying content in the correct language. ```smarty {* Conditional content based on locale *} {if $wa->locale() == 'ru_RU'}
Русский контент
{else}
English content
{/if} ``` -------------------------------- ### Product Tabs Navigation and Content Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/05-shop-script-themes.md Manages the navigation and display of product-specific information through tabs. Includes sections for Description, Specifications, Reviews, and Shipping & Returns. Tab visibility and content are dynamically controlled using Smarty conditionals and loops. ```HTML/Smarty {* Product tabs *}
{if $product.features} {/if}
{if $product.description}
{$product.description}
{else}

{_w('No description available.')}

{/if}
{if $product.features}
{foreach $product.features as $feature} {if $feature.value} {/if} {/foreach}
{$feature.name|escape} {$feature.value|escape}
{/if}
{include file="includes/product-reviews.html"}

{_w('Shipping Information')}

{_w('Free shipping on orders over $50. Standard delivery takes 3-5 business days.')}

{_w('Returns & Exchanges')}

{_w('30-day return policy. Items must be in original condition.')}

``` -------------------------------- ### Get Webasyst Version Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Returns the version number of the Webasyst framework. Commonly used for cache-busting assets like CSS and JavaScript files. ```smarty {* Cache busting for assets *} ``` -------------------------------- ### Get Current Application ID Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Returns the ID of the currently active application. Useful for conditional rendering of content or applying specific styles. ```smarty {if $wa->app() == 'shop'} {* Shop-specific content *} {elseif $wa->app() == 'site'} {* Site-specific content *} {/if} ``` -------------------------------- ### Webasyst Theme Inheritance Example (PHP) Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/08-hypermarket-theme-analysis.md This PHP class, `HypermarketTheme`, extends the core `waTheme` class to create a custom theme for Webasyst. It demonstrates how to initialize theme variables, register frontend event hooks, and manage theme-specific logic for displaying content and integrating with other applications. ```PHP setupThemeVariables(); $this->registerEventHandlers(); } /** * Setup theme-specific variables */ protected function setupThemeVariables() { // Get theme settings $settings = $this->getSettings(); // Assign theme variables to view $this->view->assign('theme_settings', $settings); $this->view->assign('color_scheme', $settings['color_scheme'] ?? 'blue'); $this->view->assign('layout_width', $settings['layout_width'] ?? 'fixed'); // Mobile detection $this->view->assign('is_mobile', wa()->isMobile()); // Current application info $this->view->assign('current_app', array( 'id' => wa()->app(), 'name' => wa()->appName(), 'url' => wa()->appUrl() )); } /** * Register event handlers for theme customization */ protected function registerEventHandlers() { // Hook into head section wa()->event('frontend_head', array($this, 'frontendHead')); // Hook into body classes wa()->event('frontend_body_class', array($this, 'frontendBodyClass')); // Hook into navigation wa()->event('frontend_nav', array($this, 'frontendNav')); } /** * Add custom CSS and JavaScript to head */ public function frontendHead() { $settings = $this->getSettings(); $output = ''; // Color scheme CSS if (!empty($settings['color_scheme']) && $settings['color_scheme'] !== 'blue') { $output .= '' . "\n"; } // Custom CSS if (!empty($settings['custom_css'])) { $output .= '' . "\n"; } // Facebook Pixel if (!empty($settings['facebook_pixel'])) { $output .= $this->getFacebookPixelCode($settings['facebook_pixel']); } return $output; } /** * Add custom body classes */ public function frontendBodyClass() { $settings = $this->getSettings(); $classes = array(); // Color scheme class $classes[] = 'theme-' . ($settings['color_scheme'] ?? 'blue'); // Layout width class $classes[] = 'layout-' . ($settings['layout_width'] ?? 'fixed'); // Application-specific class $classes[] = 'app-' . wa()->app(); // Mobile class if (wa()->isMobile()) { $classes[] = 'mobile'; } return implode(' ', $classes); } /** * Customize navigation menu */ public function frontendNav() { $nav_items = array(); // Get shop categories for navigation if (wa()->appExists('shop')) { $nav_items['shop_categories'] = $this->getShopCategories(); } // Get site pages for navigation if (wa()->appExists('site')) { $nav_items['site_pages'] = $this->getSitePages(); } return $nav_items; } /** * Get shop categories for navigation */ protected function getShopCategories() { if (!wa()->appExists('shop')) { return array(); } try { $category_model = new shopCategoryModel(); $categories = $category_model->getTree(0, 2); // 2 levels deep // Add featured products to categories foreach ($categories as &$category) { if ($category['count'] > 0) { $category['featured_products'] = $this->getFeaturedProducts($category['id'], 3); } } return $categories; } catch (Exception $e) { return array(); } } /** * Get featured products for a category */ protected function getFeaturedProducts($category_id, $limit = 3) { if (!wa()->appExists('shop')) { return array(); } try { $product_model = new shopProductModel(); $products = $product_model->select('id, name, url, price, currency') ->where('status = 1 AND category_id = ?', $category_id) ->order('sort ASC, id DESC') ->limit($limit) ->fetchAll(); // Add image URLs foreach ($products as &$product) { $product['image_url'] = $this->getShopProductImageUrl($product['id']); } return $products; } catch (Exception $e) { return array(); } } /** * Get image URL for a shop product */ protected function getShopProductImageUrl($product_id) { if (!wa()->appExists('shop')) { return null; } try { $product_images_model = new shopProductImagesModel(); $image = $product_images_model->getPrimary( $product_id ); if ($image) { return $product_images_model->getPublicUrl($image['id'], '100x100'); } } catch (Exception $e) { // Handle error, e.g., log it } return null; } /** * Get site pages for navigation */ protected function getSitePages() { if (!wa()->appExists('site')) { return array(); } try { $page_model = new sitePageModel(); // Fetch pages, potentially filtered by layout or other criteria $pages = $page_model->getTree(null, 1); // Fetch all pages, 1 level deep return $pages; } catch (Exception $e) { return array(); } } /** * Get Facebook Pixel code */ protected function getFacebookPixelCode($pixel_id) { if (empty($pixel_id)) { return ''; } return "\n"; } } ``` -------------------------------- ### Get Meta Tag Content Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Retrieves meta tag content for SEO purposes, such as 'description' or 'keywords'. It's recommended to escape the output. ```smarty {* Check if meta exists *} {if $wa->meta('description')} {/if} ``` -------------------------------- ### Get Current URL Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/09-api-reference-functions.md Retrieves the URL of the current page. Useful for canonical links, social sharing meta tags, or displaying the current location. ```smarty {* Social sharing *} {* Print current URL *}
Current page: {$wa->currentUrl()}
``` -------------------------------- ### PHP Product Display Controller for Webasyst Shop Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/03-php-smarty-integration.md Demonstrates a PHP controller (`shopFrontendProductAction`) for displaying product details in a Webasyst shop. It fetches product data, processes pricing and stock, loads reviews, and assigns data to the template for rendering. Requires Webasyst framework components. ```PHP getById($product_id); if (!$product || !$product['status']) { throw new waException('Product not found', 404); } // Load additional product data $product_service = new shopProductService(); $product_data = $product_service->getProductData($product_id, [ 'images' => true, 'features' => true, 'reviews' => true, 'related' => true, 'categories' => true, 'tags' => true ]); // Process pricing $this->processProductPricing($product_data); // Handle stock information $this->processStockInfo($product_data); // Load reviews $reviews = $this->getProductReviews($product_id); // Assign data to template $this->view->assign([ 'product' => $product_data, 'reviews' => $reviews, 'breadcrumbs' => $this->getBreadcrumbs($product_data), 'meta_title' => $product_data['meta_title'] ?: $product_data['name'], 'meta_description' => $product_data['meta_description'] ?: $product_data['summary'], 'canonical_url' => wa()->getRouteUrl('shop/frontend/product', ['id' => $product_id]) ]); // Set page metadata $this->setPageMeta($product_data); } private function processProductPricing($product) { $currency = wa('shop')->getConfig()->getCurrency(); $product['formatted_price'] = waCurrency::format('%{h}', $product['price'], $currency); if ($product['compare_price'] > $product['price']) { $product['formatted_compare_price'] = waCurrency::format('%{h}', $product['compare_price'], $currency); $product['discount_percent'] = round((1 - $product['price'] / $product['compare_price']) * 100); } return $product; } private function processStockInfo($product) { $stock_model = new shopProductStocksModel(); $stocks = $stock_model->getByProduct($product['id']); $product['in_stock'] = array_sum(array_column($stocks, 'count')) > 0; $product['stock_count'] = array_sum(array_column($stocks, 'count')); return $product; } private function getProductReviews($product_id, $limit = 10) { $review_model = new shopProductReviewsModel(); return $review_model->getByProduct($product_id, [ 'limit' => $limit, 'approved' => true, 'order' => 'datetime DESC' ]); } private function getBreadcrumbs($product) { $breadcrumbs = []; // Add category breadcrumbs if (!empty($product['categories'])) { $category = current($product['categories']); $category_model = new shopCategoryModel(); $category_path = $category_model->getPath($category['id']); foreach ($category_path as $cat) { $breadcrumbs[] = [ 'name' => $cat['name'], 'url' => wa()->getRouteUrl('shop/frontend/category', ['category_url' => $cat['url']]) ]; } } // Add product name $breadcrumbs[] = [ 'name' => $product['name'], 'url' => '' ]; return $breadcrumbs; } private function setPageMeta($product) { // Set page title wa()->getResponse()->setTitle($product['meta_title'] ?: $product['name']); // Set meta description if ($product['meta_description']) { wa()->getResponse()->setMeta('description', $product['meta_description']); } // Set Open Graph tags wa()->getResponse()->setMeta('og:title', $product['name']); wa()->getResponse()->setMeta('og:description', $product['summary']); wa()->getResponse()->setMeta('og:type', 'product'); if (!empty($product['images'])) { $image = current($product['images']); wa()->getResponse()->setMeta('og:image', $image['url_big']); } } } ``` -------------------------------- ### Display Product Details with Smarty Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/05-shop-script-themes.md This Smarty template (`product.html`) renders a product's details, including its gallery, badges, pricing, and stock status. It uses variables like `$product` and `$wa_theme_url` to populate content and includes schema.org markup for product information. The template handles conditional display of elements like multiple images, zoom buttons, and stock indicators. ```smarty
{* Product gallery *} {* Product information *}

{$product.name|escape}

{if $product.sku}
{_w('SKU')}: {$product.sku|escape}
{/if} {if $product.brand}
{$product.brand|escape}
{/if}
{* Product pricing *}
{if $product.compare_price > $product.price} {shop_currency}{$product.compare_price} {/if} {shop_currency}{$product.price}
{* Stock status *}
{if $product.count > 0} {if $product.count > 10} {_w('In Stock')} {else} {_w('%d left in stock', $product.count)} {/if} {else} {_w('Out of Stock')} {/if}
{* Product summary *} {if $product.summary}
{$product.summary|nl2br}
{/if} {* Product variants (size, color, etc.) *} {if $product.skus} ``` -------------------------------- ### Site Theme Directory Structure Source: https://github.com/adgooroo/webasyst-themes-api/blob/main/06-site-app-themes.md Illustrates the standard file and directory organization for a Webasyst Site app theme. This structure includes the theme manifest, base layout, homepage and page templates, reusable include components, and directories for CSS and JavaScript files. ```text site-theme/ ├── theme.xml # Theme manifest ├── layout.html # Base layout ├── index.html # Homepage template ├── page.html # Static page template ├── blog/ # Blog templates │ ├── post.html # Blog post detail │ ├── list.html # Blog post listing │ └── category.html # Blog category ├── includes/ # Reusable components │ ├── hero-section.html # Homepage hero │ ├── features-grid.html # Feature showcase │ ├── testimonials.html # Customer testimonials │ ├── contact-form.html # Contact form │ └── footer-cta.html # Call-to-action footer ├── css/ # Stylesheets │ ├── homepage.css # Homepage-specific styles │ ├── blog.css # Blog styling │ └── forms.css # Form styling └── js/ # JavaScript ├── homepage.js # Homepage interactions ├── forms.js # Form functionality └── blog.js # Blog interactions ```