Skip to content
  1. Extras
  2. MiniShop3
  3. Manager interface
  4. Product

Product page

Editing a product in the MiniShop3 admin panel.

Overview

The product edit page (msProduct) combines standard MODX functionality with e-commerce features:

  • Editable sections with product fields
  • Image gallery with drag-and-drop upload
  • Product links
  • Options and specifications
  • Additional categories

Tab structure

Document

Standard MODX tab with main resource fields:

FieldDescription
pagetitleProduct name
longtitleExtended title
descriptionMeta description
introtextShort description
contentFull description
aliasURL alias
parentParent category

Product data

Tab with product fields grouped by sections. Uses a Vue 3 component for flexible display.

Default sections:

SectionFields
Main dataarticle, price, old_price, weight
Stockremains, new, popular, favorite
Specificationscolor, size, vendor, made_in, tags

Configuration

Sections and fields are configured via Utilities → Product fields.

Product image management:

  • Upload via drag-and-drop
  • Sort by dragging
  • Set main image
  • Edit description

See also: Product gallery

Product link configuration:

Link typeDescription
RelatedAccessories, components
SimilarSimilar products
RecommendedPersonal recommendations

Categories

Additional product categories. A product can belong to several categories besides the main one (parent).

Options

Product option values (if configured in Settings → Options):

  • Colors
  • Sizes
  • Materials
  • Any custom options

Section and field architecture

Data storage

Field configuration is stored in the database:

TableDescription
ms3_page_sectionsPage sections
ms3_product_fieldsProduct fields with settings

msPageSection model

A section is a container for grouping fields.

Model fields:

FieldTypeDescription
idintSection ID
page_keystringPage key (product_data)
section_keystringUnique section key
lexicon_keystringLexicon key for name
labelstringName (if no lexicon)
hiddenboolWhether section is hidden
sort_orderintSort order

msProductField model

Product field with display settings.

Model fields:

FieldTypeDescription
idintField ID
namestringSystem name
labelstringDisplay name
descriptionstringHint
xtypestringWidget type
sectionintSection ID
visibleboolVisibility
requiredboolRequired
sort_orderintOrder in section
widthintWidth in percent
configjsonExtra settings
is_systemboolSystem field
is_defaultboolDefault field

Section management

Creating a section

Via interface:

  1. Open Utilities → Product fields
  2. Click "Add section"
  3. Fill in:
    • Section key — unique identifier (Latin, e.g. seo)
    • Lexicon key — for multilingual names (e.g. ms3_section_seo)
    • Label — display name
  4. Save

Via API:

POST /api/mgr/config/sections/product_data
json
{
  "section_key": "seo",
  "lexicon_key": "ms3_section_seo",
  "label": "SEO",
  "hidden": false,
  "sort_order": 100
}

Via PHP:

php
$section = $modx->newObject('MiniShop3\\Model\\msPageSection');
$section->fromArray([
    'page_key' => 'product_data',
    'section_key' => 'seo',
    'lexicon_key' => 'ms3_section_seo',
    'label' => 'SEO',
    'hidden' => false,
    'sort_order' => 100
]);
$section->save();

Editing a section

  1. Click the edit icon next to the section
  2. Change parameters
  3. Save

Deleting a section

Note

When a section is deleted, all its fields are moved to the "No section" area (section = 0).

Sorting sections

Drag sections in the desired order in the left panel.

Field management

Adding a new field

New fields are added via Utilities → Extra fields. This creates:

  1. A column in the ms3_product_data table
  2. A record in ms3_product_fields

Configuring an existing field

Via interface:

  1. Open Utilities → Product fields
  2. Select a section
  3. Click a field to edit
  4. Configure:
ParameterDescription
LabelDisplay name
DescriptionHint under field
SectionSection membership
Widget typeForm element type
VisibilityShow/hide
WidthWidth in % (50 = half)

Via API:

PUT /api/mgr/config/page-fields/product_data
json
{
  "name": "article",
  "label": "Product SKU",
  "section": 1,
  "visible": true,
  "sort_order": 0,
  "width": 50
}

Moving a field between sections

  1. Open field edit
  2. Select new section in the dropdown
  3. Save

Or change section via API.

Sorting fields

Drag fields in the desired order within a section.

Hiding a field

  1. Open field edit
  2. Uncheck "Visibility"
  3. Save

The field remains in the database but is not shown on the product card.

Widget types (xtype)

Standard

TypeDescriptionUse
textfieldSingle-line textSKU, name
numberfieldNumberPrice, weight
textareaMulti-lineDescription
xcheckboxCheckboxnew, popular, favorite

MiniShop3 comboboxes

TypeDescription
ms3-combo-vendorVendor selection
ms3-combo-categoryCategory selection
ms3-combo-autocompleteAutocomplete from list
ms3-combo-optionsOption value selection

Extended

TypeDescription
modx-combo-browserFile selection via Media Browser
datefieldDate picker
timefieldTime picker
htmleditorWYSIWYG editor

System settings

SettingDescriptionDefault
ms3_product_tab_extraShow data tabtrue
ms3_product_tab_galleryShow gallery tabtrue
ms3_product_tab_linksShow links tabtrue
ms3_product_tab_optionsShow options tabtrue
ms3_product_tab_categoriesShow categories tabtrue
ms3_product_remember_tabsRemember active tabtrue
ms3_product_main_fields"Document" tab fieldspagetitle, longtitle, ...
ms3_product_extra_fieldsExtra fieldsprice, article, ...

API Endpoints

Field configuration

Get all fields:

GET /api/mgr/config/page-fields/product_data

Response:

json
{
  "success": true,
  "object": {
    "fields": [
      {
        "name": "article",
        "label": "SKU",
        "xtype": "textfield",
        "section": 1,
        "visible": true,
        "sort_order": 0,
        "width": 50
      }
    ],
    "sections": {
      "1": {
        "id": 1,
        "section_key": "main",
        "label": "Main data",
        "sort_order": 0
      }
    }
  }
}

Save field:

PUT /api/mgr/config/page-fields/product_data

Sections

Get sections:

GET /api/mgr/config/sections/product_data

Create section:

POST /api/mgr/config/sections/product_data

Update section:

PUT /api/mgr/config/sections/product_data/{id}

Delete section:

DELETE /api/mgr/config/sections/product_data/{id}

Product data

Get data:

GET /api/mgr/product-data/{product_id}

Save data:

PUT /api/mgr/product-data/{product_id}

Configuration examples

Creating an "SEO" section

  1. Create section:

    • Key: seo
    • Label: SEO
  2. Add lexicon (optional):

php
// lexicon/ru/product.inc.php
$_lang['ms3_section_seo'] = 'SEO';

// lexicon/en/product.inc.php
$_lang['ms3_section_seo'] = 'SEO';
  1. Move fields longtitle and description into the SEO section

Hiding unused fields

For a clothing store with separate color/size options:

  1. Open the color field
  2. Uncheck "Visibility"
  3. Repeat for size

Changing field width

To make article full width:

  1. Open field edit
  2. Set width to 100
  3. Save

Two fields in a row — set each to width 50.

Adding a custom field

  1. Open Utilities → Extra fields
  2. Select model msProductData
  3. Create field:
    • Name: warranty_months
    • Type: INT
    • xtype: numberfield
  4. Save (creates column in DB)
  5. Open Utilities → Product fields
  6. Move the field to the desired section
  7. Set label and description

Extending via plugins

msOnManagerCustomCssJs event

Add custom CSS/JS to the product page:

php
<?php
// Plugin: MyProductExtension
// Events: msOnManagerCustomCssJs

if ($modx->event->name !== 'msOnManagerCustomCssJs') return;

$page = $modx->event->params['page'] ?? '';

if ($page === 'product_update' || $page === 'product_create') {
    $modx->regClientCSS('/assets/components/mycomponent/css/product.css');
    $modx->regClientStartupScript('/assets/components/mycomponent/js/product.js');
}

Extending the Vue component

Add custom widgets via Plugin Registry:

javascript
// assets/components/mycomponent/js/product.js

document.addEventListener('DOMContentLoaded', () => {
  if (window.MS3PluginRegistry) {
    MS3PluginRegistry.registerWidget('my-custom-field', {
      component: MyCustomFieldComponent,
      props: ['field', 'modelValue']
    })
  }
})