SilverStripe: Latest Blog Posts Content Block - php

I'm using SheaDawson's blocks module, and I'm trying to create a "latest blog posts" content block. Here is my DataObject:
<?php
class LatestBlogPosts extends Block {
private static $db = array(
'ContainInGrid' => 'Boolean',
'PostCount' => 'Int'
);
static $defaults = array(
"PostCount" => 2
);
function getCMSFields() {
$fields = parent::getCMSFields();
return $fields;
}
public function LatestPosts() {
$blog = DataObject::get("BlogEntry", "", "Date DESC", "", $this->PostCount);
return $blog;
}
}
On the page template it's not displaying any posts. It says it can't find any. When I checked the database the BlogEntry table is empty, even though I have two posts that are published.
How do I fix this issue?

In the latest version of the SilverStripe blog module the blog entry class is named BlogPost. BlogEntry is what the class used to be, but this changed sometime in 2015.
If you are using the latest version of the blog module your blog entries will be created as BlogPosts and that data will be in the BlogPost database table.
Your LatestPosts function should look like this:
public function LatestPosts() {
return BlogPost::get()->sort('Date', 'DESC')->limit($this->PostCount);
}

Related

TreeDropdownField Silverstripe 4 Navigation Labels

I work on a SilverStripe 4 project where I use the TreeDropdownfield. In 3.6 it got the MenuTitle (Navigation Label) by default, but I noticed that in SilverStripe the default page titles are being displayed.
Since my customer changed the page titles the TreeDropdownField shows long page titles. I would like to display the Navigation labels instead of those long page titles because the structure isn't clear with those long titles.
I have the following code:
<?php
use SilverStripe\ORM\DataObject;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\TreeDropdownField;
class InternalLink extends DataObject {
private static $db = [
'Title' => 'Varchar',
];
private static $has_one = [
'LinkTarget' => SiteTree::class,
'InternalLinkCategory' => 'InternalLinkCategory'
];
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', TextField::create( 'Title', 'Titel link' ) );
$fields->addFieldToTab('Root.Main', TreeDropdownField::create( 'LinkTargetID', 'Doeladres', SiteTree::class ) );
return $fields;
}
}
you can use TreeDropdownField::setTitleField(). It sets the field to use for item title.
$treeField = TreeDropdownField::create('LinkTargetID', 'Doeladres', SiteTree::class);
$treeField->setTitleField('MenuTitle');
$fields->addFieldToTab('Root.Main', $treeField);

silverstripe-translatable: how to make dataobjects translatable (slideshow)?

I am creating a multilingual Website in Silverstripe, the goal is to have the whole content available in three languages. I am using the translatable module, works fine for now.
Some pages contains a slideshow, meaning that I am associating a bunch of images and captions to these pages. Looks like this:
class Slide extends DataObject {
private static $db = array(
'Caption' => 'Varchar(255)',
'SortIndex' => 'Int'
);
private static $has_one = array(
'ParentPage' => 'Page',
'Image' => 'Image'
);
public static $default_sort = 'SortIndex';
public function getCMSFields() {
// parent::getCMSFields() does all the hard work and creates the fields for Title, IsActive and Content.
$fields = parent::getCMSFields();
$fields->dataFieldByName('Caption')->setTitle('Titel');
$fields->dataFieldByName('Image')->setTitle('Bild');
$fields->dataFieldByName('Index')->setTitle('Reihenfolge');
$fields->push(new TextField('Caption', 'Titel'));
$fields->push(new UploadField('Image', 'Profile Image'));
// Apply Translatable modifications
$this->applyTranslatableFieldsUpdate($fields, 'updateCMSFields');
return $fields;
}
}
class SlideShowPage extends Page {
private static $has_many = array(
'Slides' => 'Slide'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$conf = GridFieldConfig_RelationEditor::create(10);
$conf->addComponent(new GridFieldSortableRows('SortIndex'));
$fields->addFieldToTab('Root.Slideshow', new GridField('Slide', 'Slides', $this->Slides(), $conf));
// Apply Translatable modifications
$this->applyTranslatableFieldsUpdate($fields, 'updateCMSFields');
return $fields;
}
}
I want to make these slideshows translatable as well. Meaning that I want to prepare the slide show once in the primary language, then hit the "create new translation" button, and get the slideshow available in the translated version as well, with the captions ready to be translated (similar as the main text content). According to the silverstripe-translatable docs this shall be possible. I have added these calls to applyTranslatableFieldsUpdate() (see in the code above) and added these lines to my _config.php file as well:
SlideShowPage::add_extension('Translatable');
Slide::add_extension('Translatable');
The table Slide_translationgroups is even created successfully and filled with new entries for each translation. But the content of table Slide is not copied.
What am I missing?
Thanks!
Sacher

Custom Silverstripe Meta Field not saving

I created a Meta Title using the code below but it works for majority of my websites but one particular website will not save the the Meta Title so when I edit it shows my previously entered title, same code for all websites but one is not saving?
class Page extends SiteTree {
private static $db = array(
'MetaTitle' => 'Varchar(255)'
);
private static $has_one = array(
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', TextField::create('MetaTitle')
->setRightTitle('Shown at the top of the browser window and used as the "linked text" by search engines.')
->addExtraClass('help')
, 'MetaDescription');
return $fields;
}
}
If you do not /dev/build after adding a new $db property, changes will not save properly.

Silverstripe, hide a page after specific date in the future

I want to have some kind of pages created with a certain expiration date (trying to apply a date picker from silverstripe documentation didn't work with me).
That date should be in the future, at that date, I want to hide the article.
Take a look at the silverstripe/advancedworkflow module - this supports Embargo/Expiry dates (among other things).
Here is a simple implementation using a CMS controlled ExpiryDate to control whether the page can be viewed or not. This solution is for Silverstripe 3.1.
class Page extends SiteTree {
private static $db = array(
'ExpiryDate' => 'SS_Datetime'
);
public function canView($member = null) {
if ($this->ExpiryDate) {
if ($this->obj('ExpiryDate')->InPast()) {
return false;
}
}
return parent::canView($member);
}
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->addFieldToTab('Root.Main', $expiryDateField = Datetimefield::create('ExpiryDate', 'Page Expiry Date'), 'Content');
$expiryDateField->getDateField()->setConfig('showcalendar', true);
$expiryDateField->getTimeField()->setConfig('timeformat', 'HH:mm:ss');
return $fields;
}
}

Page DropDownField automatically defaulting to parent Page of object in Silverstripe

I am wanting to make simple configurable "Navigation Blocks" in a Silverstripe site. These have text, image, and link to another Page in the site.
Here's my (simplified) code:
class NavBlock extends DataObject {
private static $db = array(
'Text' => 'Text'
);
private static $has_one = array(
'NavBlockPhoto' => 'Image',
'LinksTo' => 'Page'
);
public function getCMSFields() {
$linksToField = new DropdownField('LinksToID', 'Page this block links to', Page::get()->map('ID', 'Title'));
$fields->addFieldToTab('Root.Main', $linksToField);
return $fields;
}
}
Currently the HomePage page type has a $has_one relationship with NavBlock:
class HomePage extends Page {
private static $has_many = array(
'NavBlocks' => 'NavBlock'
);
When I view a NavBlock in the CMS I get the following options:
Where "Page this block links to | Home" is I'd expect to see a drop down menu, but it seems to have defaulted/ locked to "Home" which is the parent of the NavBlock object.
Creating a new NavBlock and checking the database strongly suggests this is the case - the PageID of "Home" is 1.
How do I get it so I can select any page from the "LinksToID" dropdown?
This was the addition that worked for me:
private static $has_one = array(
'NavBlockPhoto' => 'Image',
'ParentPage' => 'Page',
'LinksTo' => 'SiteTree'
);
ParentPage automatically defaults to the HomePage as read-only.
LinksTo is then editable in the CMS.
What should be the second item in the dropdown?
It is an expected behavior because you have one HomePage only and you are setting that it can have one home page. You can remove if you like by using remove
public function getCMSFields() {
$fields=parent::getCMSFields();
$fields->removeByName('HomePageID');
}
It will still save it as HomePage behind the scenes. If you want to have many, then you should use something which is more than one and it will offer you a dropdown.
Shouldn't the code on HomePage read:
class HomePage extends Page {
private static $has_one = array(
'NavBlocks' => 'NavBlock'
);
...meaning HomePage has one block, with each block comprising one menu of many pages?

Categories