Zend Framework 2: Zend_Navigation - zend-framework2

I am just wondering what would be the best way, to use Zend_Navigation in Zend Framework2. At the moment i am trying to a add a Config for a Header and a Footer Menu. Both Menus should be populated automatically. Though, i have run into a lot of Problems:
a) The best place for the Default Menu should be hopefully the Application-Module
b) I added the following to the root of module.config.php:
'view_helpers' => array(
'helper_map' => array(
'navigation' => 'Application\View\Helper\Navigation'
),
),
My Navigation.php is located in ./module/Application/src/Application/View/Helper/Navigation.php
and contains:
class Navigation extends AbstractContainer {
public function __construct($menu = null) {
var_dump($menu);
}
}
I know that the Class may be wrong. But at the Moment i did not get ZF2 to even load the Class. What is wrong ?

Assuming you're using beta5 - you're just configuring your viewhelper wrong. See this post on how to do it correctly.
On how to use navigation: I'd create a service in the servicemanager called navigation and put my navigation into a new config-key:
return array(
'navigation' => array(
// your navigation config goes here
),
'servicemanager' => array(
'factories' => array(
'navigation' => function($sm) {
$config = $sm->get('Configuration');
$navigation = new \Zend\Navigation\Navigation($config->get('navigation'));
return $navigation;
}
),
),
'view_helpers' => array(
'factories' => array(
'navigation' => function($sm) {
return new \My\View\Helper\Navigation($sm->get('navigation'));
}
),
),
);
(Not sure about the navigation class names. Haven't had a look on them.)
This does three things:
Provide a service called navigation pointing to the actual instance
if zend's navigation
Provide your view helper and hand it a reference to the instance of your navigation
Create a new top-level key navigation containing the navigation configuration. Other modules can add custom navigation here without changing anything in your setup.
For example in your controllers you code fetch the navigation instance by calling
$this->getServiceLocator()->get('navigation');
while in your view helper has access to the navigation by it's constructor:
Navigation extends // ...
{
public function __construct($navigation)
{
// do anything you want
}
}
Other modules can add entries to your navigation by writing into the same key:
return array(
'navigation' => array(
// further navigation entries
),
);
Where you put the initial logic (e.g. setting up the services/view helpers) is up to you. I prefer writing a own module for this which can be disabled with a single line of code (resulting in the navigation not being present anymore). But the default module is probably a good place as well.
Ultimately you could create your own factory-classes for the navigation and view helper instead of mixing the configuration with your code.
Disclaimer: Code's just a draft - not tested.

Related

How i can on October CMS use translate plugin after extend new fields to user plugin?

For my project i use User Plugin and Translate Plugin.
I've added custom new fields to the user and now I want to translate them.
I think I know why it does not work. But find no solution.
Somebody to have idea?
if i add to $model->translatable default fields like 'email', works fine.
i added boot function to my custom plugin with this code
\RainLab\User\Models\User::extend(function ($model) {
$model->implement[] = 'RainLab.Translate.Behaviors.TranslatableModel';
$model->translatable = ['about', 'preview_text'];
});
Hmm,
There is one problem. when you try to add it directly $model->translatable, It seems its treating it like attribute of model.
Try this $model->addDynamicProperty(variable_name, value);
\RainLab\User\Models\User::extend(function ($model) {
$model->implement[] = 'RainLab.Translate.Behaviors.TranslatableModel';
$model->addDynamicProperty('translatable', ['about', 'preview_text']);
// like this ^
});
It should treat it as local variable and it should work.
If any doubts please comment.
Revision [ Final solution ] - solution for : it works for existing fields when we are adding new fields this is not working.
Problem: With translation mechanism is that it listens the backend.form.extendFieldsBefore event for form and then register fields for translation. When we try to register new fields in form using extendFormFields extension, It happens afterward so new added fields are not visible to translation listener. so they are kind of skipped as translation field registration process already been done.
Solution: So for solution we can just add our field before translation registartion happens. luckily translate plugin has lowest -1 priority for listening this event backend.form.extendFieldsBefore so we can register our fields before It so we are good now and our fields can be added before it can process fields for translation.
Code
\Event::listen('backend.form.extendFieldsBefore', function($widget) {
// You should always check to see if you're extending correct model
if (!$widget->model instanceof \RainLab\User\Models\User) {
return;
}
// we will merge current fields with fields we want to add
// we used shorthand + plus operator for this
$widget->tabs['fields'] = $widget->tabs['fields'] + Config::get('rms.secis::user_fields');
// here Config::get('rms.secis::user_fields') is just returning field array
// Fo ref. Ex:
// return [
// 'gender' => [
// 'label' => 'Gender',
// 'tab' => 'Security Island',
// 'type' => 'radio',
// 'options' => [
// 'male' => 'Male',
// 'female' => 'Female'
// ],
// 'span' => 'auto'
// ],
// ];
});
Note: we are adding fields to tab so we are using $widget->tabs['fields'] to add fields to the tabs. If you want to add normal fields or secondary tab fields you can use $widget->fields and $widget->secondaryTabs['fields] respectively.
Yes now translator can see our fields and its processed, It should able to show translation UI in frontend-ui as well.
if any doubts please comment.
#hardik-satasiya
yes, no more errors on frontend, but new problem is, that no translate functions on fields.
Maybe to add jQuery Script to Controller?
Integration without JQuery and October Framework files:
https://octobercms.com/plugin/rainlab-translate
end of documentation

Kendo TreeList with checkboxes on ASPNET Mvc

I'm using Kendo (and I've almost never used it before) in an ASPNET Mvc application and I need to create a TreeList with checkboxes: checking a father should check all children and unchecking a child should uncheck the father (and the grandfather, and so on).
The tree in itself works well: I've added a column with custom template and I'm using (successfully) the onClick event to get the value of the checkbox, but I can't figure out how to "bind" that value to the node of the tree (to reach every child and check it).
Here the code:
#(Html.Kendo().TreeList<TreeElem>()
.Name("treelist")
.Columns(col =>{
col.Add().Field(f => f.NodeDescription).Title("TREE LIST");
col.Add().Template("<input type='checkbox' data-bind='checked: checked' onClick='onCheck(event)'/>").Width(55);
})
.DataSource(source => source.Read(read => read.Action("GetData", "TreeController"))
.Model(m => {
m.Id(f => f.NodeId);
m.ParentId(f => f.ParentId);
m.Field(f => f.NodeDescription);
})
)
)
In the javascript:
function onCheck(e) {
console.log(e.target.checked); //print true/false according to the checkbox
console.log($("#treelist").data('kendoTreeList').dataSource.data()); //print the complete node list
//Other stuffs
}
I would like to get the right node from data() (or view()) according to the checkbox selected. Every node has references to his children and father, so the recursive function should be easy after that.
I've looked for and tried a lot of solutions but with almost no result, any idea?
Thanks

How do I add jquery ui select to a drupal module

I am porting a plugin I built originally for WordPress to a drupal 7 module.
Everything works fine except I cannot add jquery ui selectmenu:
Here is my .module code
<?php
function mortamCalc_menu() {
$items = array();
$items['mortam_calc/render_calculator'] = array(
'title' => 'Hello World Test',
'page callback' => 'render_calculator',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
return $items;
}
function render_calculator() {
$module_path = drupal_get_path('module', 'mortamcalc');
drupal_add_css($module_path.'/assets/css/mortamCalc.css');
drupal_add_library('system', 'ui.datepicker');
drupal_add_library('system', 'ui.widget');
drupal_add_library('system', 'ui.selectmenu');
drupal_add_js($module_path.'/assets/js/mortamCalc.js');
ob_start(); // start capturing output
include('views/mortamcalc.php'); // execute the file
$template = ob_get_contents(); // get the contents from the buffer
ob_end_clean();
return $template;
}
?>
ui.datepicker and ui.widget load fine but ui.selectmenu is nowhere to be seen.
What am I doing incorrectly?
Drupal 7 has a ui.selectable library item in the system.module. But I don't think there is any ui.selectmenu library available by default.
Did you add it yourself as a library item, or as part of your module? If that's the case you'd need to update that referencing line to make it work.

SilverStripe 3.1 GridField file link is re-written with HTML Entities

I'm very new to Silverstripe (3.1). I am using it to collect applications from users. Each user uploads a file which later in the CMS somebody can download.
There is a has_one relationship for the file called 'Document.'
I want to link to that file inside a GridField. So after some searching I did the solution below - easy, and it works except for one problem.
The link does appear inside the correct column in the GridField but it has been converted through something like HTMLSpecialChars() and I can see all the HTML. For the life me I cannot figure how to stop it.
I would like to know where this conversion is taking place?
and how can I circumvent it?
$submissionGrid = new GridField('submissions', 'Submissions', $submission, $config );
$submissionGrid->addDataFields(array(
"Document" => function($row) {
$link = 'Download Document';
return $link;
},
));
You are pretty close.
Instead of addDataFields(), have you tried setFieldFormatting on the configuration of your gridfield?
$submissionGrid = new GridField('submissions', 'Submissions', $submission, $config );
$config = $submissionGrid->getConfig();
$config->getComponentByType('GridFieldDataColumns')->setFieldFormatting(array(
"Document" => function($value, $item) {
$link = 'Download Document';
return $link;
},
));
Depending on the fields available on the Submission Dataobject, if "Document" is something you are adding as a custom column to your gridfield, you will need to add it as well using setDisplayFields(). In this case, add this as well
$config->getComponentByType('GridFieldDataColumns')->setDisplayFields(array(
"Document" => "Link to document"
));
What actually worked:
I gave the right answer to jfbarrois for pointing me straight but thought I should post up the code that actually worked because it took me a while to find this answer.
It does have the inestimable advantage that it does actually work and a link is placed in a custom-formatted column in the GridField.
$config = GridFieldConfig_Base::create();
$config->getComponentByType('GridFieldDataColumns')->setDisplayFields($displayFields);
// Adding the custom named 'Download' column to the previously defined $displayFields
$config->getComponentByType('GridFieldDataColumns')->setDisplayFields(
array_merge($displayFields, array(
"Download" => "Link to document"
)
));
// Set the field formatting on the custom column inserting the real data from the 'Document' File Object
$config->getComponentByType('GridFieldDataColumns')->setFieldFormatting(array(
"Download" => function($value, $item) {
$link = 'Download Document';
return $link;
},
));
// Create the GridField
$submissionGrid = new GridField('submissions', 'Submissions', $submission, $config );

Translating Breadcrumbs (View Helper) on Zend Framework 2

I´m working in a Zend Framework 2 project and I´m using the View Helper (Breadcrumbs) to inject this navigation component into my views.
To render my Breadcrumbs the following code is used:
<?php echo $this->navigation('Navigation')
->breadcrumbs()
->setLinkLast(false) // link last page
->setMaxDepth(7) // stop at level 7
->setMinDepth(0) // start at level 0
->setSeparator(' »' . PHP_EOL); // separator with newline
?>
I´ve been translating most of the project´s content with the following code
<?php echo $this->translate("Text to translate here", $textDomain); ?>
So applying the same logic to the existing code:
<?php echo $this->translate($this->navigation('Navigation')
->breadcrumbs()
->setLinkLast(false) // link last page
->setMaxDepth(7) // stop at level 7
->setMinDepth(0) // start at level 0
->setSeparator(' »' . PHP_EOL), "navigation"); // separator with newline
?>
Is this the most efficient and/or correct way to translate the breadcrumbs? The text domain here set as "navigation" is where this translation lives. Without being set it defaults to the value "default".
you cannot really do it like this, you're passing html to the translator. simply use these methods on the viewhelper:
$navHelper->setTranslator($yourTranslator);
$navHelper->setTranslatorTextDomain('de_DE');
$navHelper->setTranslatorEnabled(true); // (default)
$navHelper->setInjectTranslator(true); // to pass the translator down to menu/breadcrumbs etc. (default)
To fix the translation of the breadcrumb, I did this :
Cut/paste all the translator configuration into a new file : config/autoload/translator.global.php
I use only one translation file for the entire application and not one by module... but anyway, if you do have one translation file by module, just choose one for your navigation ;)
I modify the base_dir option to the module/application/language :
<?php
return array(
'translator' => array(
'locale' => 'fr_FR',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../../module/Application/language',
'pattern' => '%s.mo',
),
),
),
);
I also put my navigation config array into one autoload file : config/autoload/navigation.global.php
=> I add the new path in the poedit file used to translate my navigation (the only one for me) for automatic detection ;)
In this file, I instanciate a specific translator using the translator's factory method, and I just have to call the translate() method :) :
<?php
$config = require 'translator.global.php';
$options = (array)$config['translator'];
$translator = \Zend\I18n\Translator\Translator::factory($options);
return array(
'navigation' => array(
'default' => array(
array(
'label' => $translator->translate('Home'),
'route' => 'home',
),
[...]
And everything works great now (even breadcrumbs) :)
I had the same translation problem with my forms, and the first trick I found still work great without having to create a new translator for each forrm :
the only trouble was poedit autodetection :
create an underscore function in public/index.php (not used by zend but regognized by poedit)
function _($str){
return $str;
}
and then only have to declare form labels like that :
'label' => _('My Label'),
poedit detects it and translate labels without anything else than a little translation works in poedit for all theses new words ;)
EDIT :
I had a bug in my beadcrumb partial phtml file : didn't call for the translate viewhelper... (just copied it from the zend tutorial and forgot it... stupid isn't it ? :D)
That fixed, the underscore function works as well for the form labels and for navigation... even breadcrumbs ! All my heavy stuff, creating a new translator to call it in the navigation config array is useless :)
I found back where I got this trick inbeetween : => How to translate form labels in Zend Framework 2? (in the last comment... that should be more voted than the actual 0 ;))

Resources