### 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 ThemeLearning Webasyst theme developmentYour Name1.0.0
```
```smarty
{$wa->title()}
{$wa->meta()}
{$wa->header()}
```
```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 WebasystYour NameYour Company1.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 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Комплексная бизнес-тема для приложений WebasystYour CompanyYour Company Ltd.2.1.02024010301Color SchemeLayout WidthShow Breadcrumbspreview.jpgicon.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}
{if $product.images}
{foreach $product.images as $image}
{/foreach}
{/if}
{$product.name}
{$product.price|wa_currency:$product.currency}
{if $product.description}
{$product.description}
{/if}
{* Product features *}
{if $product.features}
```
--------------------------------
### 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}
{$feature.name|escape}
{$feature.value|escape}
{/if}
{/foreach}
{/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