Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Silverstripe 3.2 re-usable blocks

I have created a new page type that needs something to break up the content. I have created a strapline block that i would like to use in 3 places on the page, however i want to create only 1 version of the strapline block and drive that content by dynamic data.

I have the following in Straplines.php

class Straplines extends DataObject{
    private static $db = array(
        'Title'=>'Text',
        'Content'=>'HTMLText',
        'SortOrder'=>'Int'
    );
    private static $has_one = array(
        'Parent'=>'Page'
    );

    private static $default_sort = 'SortOrder';

    public function getCMSFields(){
            $fields = parent::getCMSFields();
            $fields->addFieldToTab("Root.Main", new HtmlEditorField('Content','Content'));
            $fields->addFieldToTab("Root.Main", new TextField('Title','Title'));
            return $fields;
    }
}

Then i add the cms fields to HomePage.php. I can add straplines no problem there and they all show up. Then in HomePage.ss i have the following

<% include PricesBlock %>
<% include TourStraplineBlock %>
<% include QuickFacts %>
<% include TourStraplineBlock %>

But then I cannot figure out away in TourStraplineBlock to get separate content for each of these. Surely there must be away to parameterize the include or not have to create multiple templates. I'm quite new to Silverstripe dev and am finding it a tough process to create re-usable content.

Edit: This is the strapline.ss template that handles displaying.

<div class="strapline"> 
        <% loop Straplines %>
            $Content        
        <% end_loop%>
</div>

As you can probably guess, if i put this in twice it simply shows all the straplines. I want to do something like

<% include Strapline?id=1 %>

Then decode that in Strapline.ss and go from there.

Edit sorry yes its 3.2 not 3.0. I assumed that they were quite similar.

like image 916
Andrew MacNaughton Avatar asked Dec 19 '15 00:12

Andrew MacNaughton


2 Answers

Like Firesphere mentioned you could just create a function that you can call in your template and pass the object ID to it.

Put this function in your Page_Controller class or if you wish to access it only from the homepage, than put it in your HomePage_Controller class.

public function StraplineByID($id) {
  $strapline = Straplines::get()->byID($id);
  if($strapline) {
    return $strapline;
  }
}

In your template you can now use that:

<% if $StraplineByID(1) %>
  <% with $StraplineByID(1) %>
    $Title, $Content, $WhatEver or an include
  <% else %>
    Can't find a strapline with this ID
  <% end_with %>
<% end_if %>

If you want to identify the straplines not by id but by name (this would be more user friendly) you should create a new field called "Name" or something like that and use this instead of the id. But note the values in the Name field should be unique

public function StraplineByName($name) {
  $strapline = Straplines::get()->find('Name', $name);
  if($strapline) {
    return $strapline;
  }
}

and in your template

<% if $StraplineByName(prices) %>
  <% with $StraplineByName(prices) %>
    $Title, $Content, $WhatEver or an Include
  <% else %>
    Can't find a strapline with this Name
  <% end_with %>
<% end_if %>

The code is untested but it should work ;)

like image 165
csy_dot_io Avatar answered Nov 18 '22 04:11

csy_dot_io


You could make a function in page, which takes the argument as a literal, and returns the wished strapline. e.g.

<% $currentStrapline(1) %>

and a function in page,

public function currentStrapline($id) {
 // returns the wished strapline or null; 
}
like image 4
Firesphere Avatar answered Nov 18 '22 03:11

Firesphere