Ivan
Ivan

Reputation: 5248

Silverstripe looping has_many inside template

I want to loop my products on template using has_many relation but somthing am doing wrong. First i create DataObject Product with has_one and create ModelAdmin for adding new products. After that i create ProductPage model and controller and ProductPage template where i loop products.

Data Object:

<?php

class Product extends DataObject
{
    private static $db = array(
        'Name' => 'Varchar',
        'Description' => 'HTMLText',
        'Price' => 'Decimal'
    );

    private static $has_one = array(
        'Photo' => 'Image',
        'ProductPage' => 'ProductPage'
    );

    public function getCMSFields()
    {
        $fields = FieldList::create(TabSet::create('Root'));

        $fields->addFieldsToTab('Root.Main', array(
            TextField::create('Name'),
            HtmlEditorField::create('Opis'),
            NumericField::create('Price'),
            UploadField::create('Photo')
        ));

        return $fields;
    }

}

ProductPage:

class ProductPage extends Page
{
    private static $has_many = array(
        'Products' => 'Product'
    );
}

class ProductPage_Controller extends Page_Controller
{

}

Template:

<% if $Products %>
    <% loop $Products %>
        <div class="col-md-4">
            <h3>$Name</h3>
        </div>
    <% end_loop %>
<% else %>
    No product found
<% end_if %>

Am get all time No product found but i have products in database.

What can be problem?

Upvotes: 2

Views: 444

Answers (1)

bummzack
bummzack

Reputation: 5875

You should use the name you used for your relation in your template. Eg. you name your relation RelationName, then that is what you use to access the relation in code or templates.

private static $has_many = array( 'RelationName' => 'ObjectName' );

So in your case, use Products:

<% if $Products %>
    <% loop $Products %>
        <div class="col-md-4">
            <h3>$Name</h3>
        </div>
    <% end_loop %>
<% else %>
    No product found
<% end_if %>

You'll need to ensure that the Products are actually linked to your Product-Page. Just creating them in a ModelAdmin won't establish a relation for you… I suggest you use a GridField for that. You can add the following code to your ProductPage to do that:

public function getCMSFields()
{
    $fields = parent::getCMSFields();

    $gridConfig = GridFieldConfig_RelationEditor::create();

    /** @var GridField $gridField */
    $gridField = GridField::create(
        'Products',
        _t('ProductPage.has_many_Products', 'Products'),
        $this->Products(),
        $gridConfig
    );

    $gridField->setModelClass('Product');

    $fields->addFieldToTab('Root.Main', $gridField);

    return $fields;
}

If you want to create Products via ModelAdmin and not link them to ProductPage, you can skip the entire has_many relation and just output all Products in a method of ProductPage:

public function Products()
{
    return Product::get();
}

Upvotes: 3

Related Questions