Shopware 5 - Looping through all attributes - foreach

Hello i need some help with shopware.
My question is probably pretty basic but i cannot get it done. I want to print out attributes from an article. In shopware documentation they call them {$sArticle.attr1} till {$sArticle.attr20} but they can also have different names so i cannot refer directly to the name and instead i want only a few attributes to be printed.
so far i know that all attributes are stored in the s_articles_attributes database table and i only want to print out those columns when the column name containes='artikelattribut_'
The code is going to be implemented in a table from frontend/detail/tabs --> description.tpl
the actual table already uses the $sArticle.sProperties and the code looks the following:
{if $sArticle.sProperties}
<div class="product--properties panel has--border">
<table class="product--properties-table">
{foreach $sArticle.sProperties as $sProperty}
<tr class="product--properties-row">
{* Property label *}
{block name='frontend_detail_description_properties_label'}
<td class="product--properties-label is--bold">{$sProperty.name|escape}:</td>
{/block}
{* Property content *}
{block name='frontend_detail_description_properties_content'}
<td class="product--properties-value">{$sProperty.value|escape}</td>
{/block}
</tr>
{/foreach}
</table>
</div>
{/if}
The thing is that $sArticle.sProperties and {$sArticle.attr1} till {$sArticle.attr20} are different. All i want is a second {foreach} that loops threw all article attributes maybe the idea is getting clear with that:
{foreach $sArticle.attr FROM s_articles_attributes WHERE name contains='artikelattribut_'}
I hope somebody understands my problem. Thankfull for any advice.
Thanks

First, keep in mind, that "properties" and "attributes" mean something different in Shopware as you might know it from other shop systems.
"Properties" are used for characteristics of a product, like the taste or colour of product.
"Attributes" in Shopware do not have anything to do with attributes in the usual meaning. You can find those *_attributes tables for almost every entity and they are used more like custom fields or columns which you could add to the entities to extend them with custom data.
Now back to your problem. Try this:
{foreach $sArticle.attributes.core->toArray() as $attributeName => $attribute}
{$attributeName|var_dump}
{$attribute|var_dump}
{/foreach}
There are two ways to access the attributes of a product.
All attributes are directly assigned to the $sArticle variable and you can use them, as you already described in your text.
Attributes are also stored in $sArticle.attributes where you can find different types of attributes. By default those are core and marketing for products on the detail page. Be aware that the values of those keys are objects of type Shopware\Bundle\StoreFrontBundle\Struct\Attribute. That's why we need to call the toArray method, to get an array which we can iterate.

Related

Knockout List Item Animation

I've been working with Knockout.js for some time now but only recently I've started to integrate jqueryUI animations for the sake of a better user experience. I'm seeing some issues trying to use the animation bindings on the tr elements inside a table tag. When I use the "visible" binding to hide and show each element it works just fine but when I attempt to animate the showing hiding of each element it only seems to apply to the first row in the table. I've attempted this using various methods. I've attempted using the knockout foreach template 'afterAdd' option as described here:
http://knockoutjs.com/documentation/foreach-binding.html#note_5_postprocessing_or_animating_the_generated_dom_elements
I've also created a custom binding and attempted to use that on each of the table row items with the same results.
Lastly I attempted to use the plugin found here:
http://www.codecoding.com/knockout-plugin-visibility-bindings-with-jqueryui-effects/
And again, it only appears to work on the first element of the table. Now before attempting to rewrite my HTML to use divs and spans rather than the tables I wanted to see if anybody else has seen these sorts of issues with knockout in the past. The relevant chunk of HTML is this:
<table class="tab_table table_a">
<tbody data-bind="foreach:featuredMenuItems,visible:showFeatured">
<tr data-bind="fadeVisible:readyToShow, click:function(){$root.showProductOptions($data);}">
<td class="td_large" data-bind="css:{td_select:itemInCart};"><span class="inCart_delete" data-bind="css:{display_IB:itemInCart},click:removeFromCart,clickBubble:false"><i class="fa fa-times-circle"></i></span><span data-bind="text:name"></span></td>
<td class="td_last" data-bind="css:{td_select:itemInCart},text:lineItemCost"></td>
</tr>
</tbody>
</table>
I would paste the ViewModel code in here as well but it is a rather large view model and the relevant part to this is just a simple "readyToShow" observable set to either true or false. Whenever this table is being shown the "readyToShow" values of each of the objects in the observableArray containing the table items is being set to true over time using a timeout so as to show a cascading effect when the table is shown.
I would really appreciate any help you guys could provide. Thanks!

No edit link in list scaffold view when first field is nullable

Let's say I have a Domain Class (let's call it Person) with various String properties, like the following:
class Person {
String favoriteColor
String favoriteAnimal
static constraints = {
favoriteColor(nullable: true)
favoriteAnimal(nullable: true)
}
}
I am trying to use dynamic scaffolding only for now to see how far it will take me with this great rapid application development ability I've heard so much about...but that stops right here with this class.
The Problem
The problem is that the default behavior in Grails dynamic scaffolding is that the index page will show the first X amount of entries, with the first field of each entry turned into a hyper-link that allows you to view/edit that specific item.
That's really great, but sadly when the first field can be null the index page lists the entry - but there is no link to click to be able to view/edit the item in detail.
The easy solution, of course, is to make a non-nullable field the first item...but now I have a class which has properties where all individual fields can be null, with custom validation to ensure at least one field contains something. So that won't work in this annoying edge case (yet which is a business requirement, there is no single field I can guarantee will never be null here).
What is the Grails way to fix this issue, without just completely throwing out scaffolding?
If I need only to alter the index function of this one controller to fix the issue, I'd like to do that with minimal code and not have to ditch dynamic scaffolding for the rest of the controller. I really like the rapid prototype ability of scaffolding (and Grails), and want to make the most of this feature set.
The Solution
Using Dónal's answer suggesting install-templates, I simply ran the grails install-templates command and then went to my projects src->templates->scaffolding->index.gsp file. While it is full of scriptlets and such that make it somewhat tricky to understand, the solution proved remarkably easy.
In the html for the table section, there is a bit of code similar to this:
<table>
<thead>
<tr>
<% excludedProps = Event.allEvents.toList() << 'id' << 'version'
...
By simply changing it to the following, you get an extra header row for an edit function:
<table>
<thead>
<tr>
<th> </th>
<% excludedProps = Event.allEvents.toList() << 'id' << 'version'
...
Then lower you have code such as:
<g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
<tr class="\${(i % 2) == 0 ? 'even' : 'odd'}">
<% props.eachWithIndex { p, i ->
if (i == 0) { %>
<td><g:link action="show" id="\${${propertyName}.id}">\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</g:link></td>
With a simple change to get rid of the link on the first property name column, and instead add your own Edit link to the first column, the problem is fixed:
<g:each in="\${${propertyName}List}" status="i" var="${propertyName}">
<tr class="\${(i % 2) == 0 ? 'even' : 'odd'}">
<% props.eachWithIndex { p, i ->
if (i == 0) { %>
<td><g:link action="show" id="\${${propertyName}.id}">Edit</g:link></td>
<td>\${fieldValue(bean: ${propertyName}, field: "${p.name}")}</td>
So with one line changed and two lines added to a single file (after a Grails command) you have changed default scaffold behavior to suit your fancy and support nullable fields. Problem solved!
What is the Grails way to fix this issue, without just completely throwing out scaffolding?
The templates that are used to generate the scaffolded views can be modified. Before you can modify them you must first run the install-templates command. After you've installed the templates, modify the template that generates the list view such that it adds a view link (or buttons) to each row, rather than linking the value of a particular property. Then you will always be able to view the domain instance, regardless of which properties are null.

How to loop through properties in a tab and display them using Razor?

I have a Document Type, that has a tab with some properties.
The properties are Upload types, and Simple Editor types.
(Users are supposed to upload images with some image text).
I have not grouped the "Upload" and "Simple Editor" properties, so how do i do this?
Next question,
I want to loop through each group (there should be 3 currently) and display them on my website.
The markup should look like the following:
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
..
<div>
<img src="PATH-TO-UPLOAD-TYPE" />
<div>"TEXT FROM SIMPLE EDTIOR TYPE"</div>
</div>
...
I would like to use Razor for this. Thanks in advance!
For the first part, using the Razor model, you can't. The content object that you get on the front end only contains the properties, the tabs are not included, as they're only really for organising things in the back office.
You CAN get that information using the Umbraco API, but it's pretty database intensive and could potentially be quite slow if you have a lot of properties/tabs.
You'd be better grouping them yourself in your Razor Macro.
for the second part, you can acces the properties of a page via #Model.property. For example:
<div>
<div>#Model.simpleProperty</div>
</div>

How to change the number pattern in gsp?

I have one domain class which has one numeric field. Default scaffolding generated it. When I enter a number with more than 3 digits, ex:- 1234, then in show.gsp and list.gsp it shows as 1,234. My requirement is to show the number without comma. I can't use g:formatNumber because I have more than 50 domains and not able to use this tag for every gsp page. Is there anything I can do to change the number pattern globally?
thanks
maybe solution suggested here can be useful
Get the field directly like:
<td valign="top" class="value">${formulationTypeInstance?.id}</td>
Of course you may lose some of the tag's features with it, like highlighting field when a validation error occurs. But you're in show.gsp and it shouldn't have text fields or something to submit, so you lose nothing! Simple is the way to go here. =)

naming form files using square brackets

I've noticed in some php applications, that form fields are labelled with [] in them.
Say a shopping cart page, that lists all the items where you can edit the quantity.
is the [] type naming used to get the correct row?
Just trying to figure out how I should name each textbox?
should it be like:
name="quantity-<%= items.RowId %>"
THen when I loop the form fields, I would get the index number?
This is done in PHP when you need to pass <select multiple="multiple"> to the server, otherwise PHP will catch only the first selected value.
Textboxes don't normally require such naming.
This might answer a few of your questions. Here, Phil Haack uses square brackets in order to bind to a model that contains a list.

Resources