Typically, you'd have the HTML for the output in a Tpl chunk with placeholders for the values (lets call it 'ProductTpl'):
<h3>[[+product_name]]</h3>
<p>Price: [[+product_price]]</p>
<p>Size: [[+product_size]]</p>
The best method, if you're going to have many product pages, is to use a custom DB table to hold the data, and use xPDO to interact with it.
That would look something like this:
$output = '';
$products = $modx->getCollection('modProduct');
foreach($products as $product) {
$fields = $product->toArray();
$output .= $modx->getChunk('ProductTpl', $fields);
}
return $output;
This requires some work up front to create the table and generate the xPDO class and map files.
The quick-and-dirty alternative, if you won't have a lot of products would be to create a separate resource for each product and put the data for the product in the resource's fields and create Template Variable (TVs) to hold any data that won't fit in the resource fields.
This is much slower, but easy to set up fairly quickly and the output (using the same Tpl chunk) would be created with a single call to the getResources snippet.
[[getResources? &tpl=`ProductTpl` . . . ]]