In the back-end, the SilverStripe Fluent module adds a green flag icon to indicate the field is translatable (as seen next to PageName, URL Segment and Content).
This is a userfriendly detail and I would expect it work for custom added CMS Fields which are made translatable. For example, I've added a custom field named Introduction and made it translatable using: private static $translate = array( 'Introduction' ); But there is no green icon next to it. Can this be added?
It was necessary to add $this->beforeUpdateCMSFields(function($fields) { ... } BEFORE $fields = parent::getCMSFields(); and put all translatable fields in there like so:
function getCMSFields() {
//This needs to be added for Fluent to apply css
$this->beforeUpdateCMSFields(function($fields) {
//Translatable field
$fields->addFieldToTab("Root.Main", new TextAreaField('Introduction','Introduction'), 'Content');
});
$fields = parent::getCMSFields();
//Non-translatable field
$fields->addFieldToTab("Root.Main", $uploadField = new UploadField('Slideshow', 'Slideshow Images'), 'Content');
return $fields;
}
Related
This should be relatively simple. I know how to create a form and hide it and show it if a specific option is selected
I want to have a Dropdown populated with a specific DataObject. That much is simple. But I need to add an option that says 'Add new' to this Dropdown, which is in a form
I can handle the submission (like if the value is something like 'new' instead of an ID), but I do not know how to add this option into the select with Silverstripe, or if it is even possible. Any help is appreciated!
You can use a DropdownField and populate it with whatever key value pairs you want. For example:
$itemsField = DropdownField::create(
'Items',
'Items',
['add-new' => 'Add new'] + $this->Items()->map()->toArray()
);
The third argument is an array that gets turned into the option html elements for the drop down.
Then you can add it to your form's FieldList:
$form = Form::create(
$this,
'MyForm',
FieldList::create(
[
$someField,
$someOtherField,
$itemsField
]
),
$actions,
$requiredFields
);
http://api.silverstripe.org/3.1/class-DropdownField.html
A Dropdown for selecting a $has_one is fine. E.g. if you have a list of Addresses and want to select the Country.
Sometimes a new Country has to be added. For this i used the quickaddnew extension which adds a nice button "add new" beneath the dropdown and opens a form in a modal for adding the new item. You can use it in your code like this:
public function getCMSFields() {
/**
* #FieldList
*/
$fields = parent::getCMSFields();
$countries = function() {
return Country::get()->map('ID','Title')->toArray();
};
$country = new DropdownField('CountryID', 'Country', $countries());
$country->setEmptyString('-- please select --');
$country->useAddNew('Country', $countries);
$fields->insertAfter($country, 'Telephone');
$fields->removeByName('SortOrder');
return $fields;
When a new page is created part of that data goes to the slugs model (slug url, template type, template id) this is standard on every page, then the rest of the data goes to a template model, in this case called text (simple text page).
The slug is required for example.com/{slug} which grabs the slug_url and looks for the appropriate page/template to produce the correct view and pass the correct data.
Logic:
Slug requires Text id
Text requires Slug id
But as I have to save them at the same time I’m not sure how I get the id of one and pass it to the other, simultaneously, so I came up with this:
Save new Slug
Save new Text (page template)
Update Slug with Text id
Here is the offending code - TextsController:
public function store()
{
$validator = Validator::make(Input::all(),
array(
'title' => 'required',
'slug_url' => 'required',
'menu_order' => 'required|numeric'
)
);
if($validator->fails()) {
Flash::error('Page not created! Please check errors below');
return Redirect::route('app.pages.index')->withErrors($validator);
} else {
$slug = new Slug;
$slug->user_id = Auth::id();
$slug->slug_url = Input::get('slug_url');
$slug->type = Input::get('type');
$slug->menu_order = Input::get('menu_order');
$slug->save();
$text = new Text;
$text->user_id = Auth::id();
$text->slug_id = $slug->id;
$text->title = Input::get('title');
$text->active = Input::get('active');
$text->save();
$slug_update = Slug::where('user_id', Auth::user()->id)->where('slug_url', $slug->slug_url)->first();
$slug_update->type_id = $text->id;
$slug_update->update();
return Redirect::route('app.texts.edit', $text->id);
}
}
I’m pretty new to Laravel (and development generally) but from what I have see so far, I’m pretty sure there must a cleaner way to do this?
You can change those lines:
$slug_update = Slug::where('user_id', Auth::user()->id)->where('slug_url', $slug->slug_url)->first();
$slug_update->type_id = $text->id;
$slug_update->update();
into:
$slug->type_id = $text->id;
$slug->save();
Running Joomla 3.3.0-dev
I'm following the info posted here about adding tag support to a third-party component.
I've added the content type to the #__content_types table and modified my table file like this:
class MycomponentTableElement extends JTable
{
public $tagsHelper = null; // failed when protected and public
public function __construct(&$_db)
{
parent::__construct('#__mycomponent', 'id', $_db);
// Add Joomla tags
JObserverMapper::addObserverClassToClass('JTableObserverTags', 'MycomponentTableElement', array('typeAlias' => 'com_mycomponent.element'));
//$this->_observers = new JObserverUpdater($this); JObserverMapper::attachAllObservers($this); // failed with or without this line
}
I added the tag field in the edit template, and it worked fine-- but when I save an object I get the following error:
Save failed with the following error: Unknown column 'tagsHelper' in 'field list'
What am I missing? There's no other steps (besides front-end steps!) that are mentioned. It seems like I need to modify the model but that info is not applicable.
Thanks
"This Page Needs Copy Editing" and it's really true!
I also follow initial steps as described in page
Register a 'Content type' for the extension view(s)
Add 'Observer methods' to the extension table class(es)
Add 'Tag fields' to the extension edit forms
But to make field tag works on custom extensions I need to explicit set form field value in view file of backend:
$tagsHelper = new JHelperTags;
$this->form= $this->get('Form');
$this->form->setValue('tags', null, $tagsHelper->getTagIds( $this->item->id, 'com_custom.viewname') );
in this way on edit page all seems to work correctly.. surely exist better and more clean method, but until doc page will not be updated, this can help someone!
1- Add tag field to your xml form file or edit template file
2- Modify #__content_types table file:
function __construct(&$db)
{
parent::__construct('#__ir_products', 'id', $db);
JTableObserverTags::createObserver($this, array('typeAlias' => 'com_itemreview.product'));
}
3- Modify model file getItem function:
public function getItem($pk = null)
{
$item = parent::getItem($pk);
if (!empty($item->id))
{
$item->tags = new JHelperTags;
$item->tags->getTagIds($item->id, 'com_yourcomponent.yourmodel');
}
return $item;
}
I'd like to do a number of small customizations on the ModelAdmin.
I'd like to change the text on the 'Add' button to one that is different from the original DataModel.
I have a has_many relationship. I'd like to hide the ability to 'link to existing' so that one cannot search for other 'skills' as per below.
I have the following in the Model:
public function getCMSFields() {
...
$characterSkillsField = new GridField(
'CharacterSkills',
'Character Skills',
$this->CharacterSkills(),
GridFieldConfig_RelationEditor::create()
);
$fields->addFieldToTab('Root.CharacterSkills', $characterSkillsField);
...
}
ANSWER to #2:
// Add the relation editor.
$config = GridFieldConfig_RelationEditor::create();
// Remove the ability to search and link to other skills.
$config->removeComponentsByType('GridFieldAddExistingAutocompleter');
$characterSkillsField = new GridField(
'CharacterSkills',
'Character Skills',
$this->CharacterSkills(),
$config
);
regarding #1:
add the following to the model class that's managed by the GridField (e.g. 'CharacterSkill') :
private static $singular_name = 'foo';
private static $plural_name = 'bar';
don't forget flushing the cache afterwards (add '?flush=All' to the url).
the preceding will set the button name to 'Add foo', but it's also possible to set your very own button title, using the following:
$config = GridFieldConfig_RelationEditor::create();
$addButton = $config->getComponentByType('GridFieldAddNewButton');
$addButton->setButtonName('my button name');
I have created a Link DataObject to automatically let users create a reference to a different page in the Frontend. I use two languages in the frontend, German and English. In the popup I create a dropdown to select the pages
public function getCMSFields_forPopup()
{
return new FieldSet(
new TextField('Titel'),
new TextField('URL', 'Externer Link'),
new SimpleTreeDropdownField('PageLinkID', 'Interner Link', 'SiteTree')
);
}
But I only get the German pages in the dropdown. Tried to change the admin language to English but no change. The database seems to only return the German pages...
Any clue?
Edit: I did some more digging and found out how to do this. You need to call "disable_locale_filter" before you get your SiteTree objects:
Translatable::disable_locale_filter();
Then call "enable_locale_filter" once you've retrieved them:
Translatable::enable_locale_filter();
These are other approaches which I'll leave here as I think they are still useful...
I believe you may have to do this using Translatable::get_by_locale() - I assume you only want people to be able to select a page to link to within their language??
Perhaps something like this?
public function getCMSFields_forPopup()
{
$member = Member::currentUser();
if($member && $member->Locale) {
$pagesByLocale = Translatable::get_by_locale('SiteTree', $member->Locale);
$pagesByLocale = $pagesByLocale->map('ID', 'Title', '(Select one)', true);
return new FieldSet(
new TextField('Title'),
new TextField('URL', 'Externer Link'),
new DropdownField('PageLinkID', 'Interner Link', $pagesByLocale);
);
} else {
// Handle non-member
}
}
Edit: see comments below but another option is to use the Translatable::get_current_locale() function to find all pages in the Site Tree for that locale... if the user is viewing an english page then the locale should be set to english etc...
public function getCMSFields_forPopup()
{
$pagesByLocale = Translatable::get_by_locale('SiteTree', Translatable::get_current_locale());
$pagesByLocale = $pagesByLocale->map('ID', 'Title', '(Select one)', true);
return new FieldSet(
new TextField('Title'),
new TextField('URL', 'Externer Link'),
new DropdownField('PageLinkID', 'Interner Link', $pagesByLocale);
);
}
You can also get the locale from the current page e.g.
$this->Locale; // From within the model
$this->dataRecord->Locale; // from within the controller
Director::get_current_page()->Locale; // If you're outside the context of the page altogether i.e. code inside your DataObject.