Translating Breadcrumbs (View Helper) on Zend Framework 2 - translation

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 ;))

Related

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.

How we can automatically inject liquid code inside shop's theme using shopify app?

I'm building a Shopify application and I'm interested in automatically adding a liquid content into the shop's theme.
this is the code I use to insert liquid files in active theme.
$asset = $shopify('PUT /admin/themes/' . $id . '/assets.json', array(), array
(
'asset' => array
(
"key" => "snippets/file.liquid",
"src" => "https://yourdomain.com/file.liquid"
)
));
To get the active theme ID i use
foreach ( $themes as $theme){
if($theme[role] == 'main'){
$id = $theme[id];
}
}
Let me know if this helps.

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 );

Right way to attach a jQuery-UI dateselect to a Zend Framework 2 form element?

What would be the right way to attach a jQuery-UI dateselect to a Zend Framework 2 form element?
Would it be adding a appendScript so a javascript selector is added to the end of the layout that selects the class/id?
First of all, i strongly suggest to go with the time and to start using Zend\Form\Element\Date. All browsers who do not support the Date-Input will still render out a Input of type="text", so there is literally no loss in doing so.
The advantage you do get is that most modern browsers are able to render out there default Datepicker. Using the browsers defaults is preferred for users usability and comfort. Even IE10 does do a very good job of supporting the current neat stuff of CSS3 and HTML5. But of course you can't be sure and so you should always include a fallback for older browsers, too. For this, I strongly suggest that you run with Feature-Detection in favor of blindly overwriting the users defaults. The library that does the job the best probably is Modernizr. I will give you the JS for that at the end.
Another thing to note is that this kind of JavaScript belongs at the BOTTOM of your document. For this you have to print this right before closing your </body>-Tag
<?=$this->inlineScript();?>
Now print the script you want inside the right place like this inside your $action.phtml
<?php $this->inlineScript()->captureStart(); ?>
Modernizr.load({
test: Modernizr.inputtypes.date,
nope: [
'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js',
'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js',
'jquery-ui.css'
],
complete: function () {
$('input[type=date]').datepicker({
dateFormat: 'yy-mm-dd'
});
}
});
<?php $this->inlineScript()->captureEnd(); ?>
What's happeing there is that the Modernizr-library will check for the browser support of the Date-Input of HTML5. If the browser is not able to render out a DateSelect, the appropriate JavaScript-Libraries will be loaded (jQuery, jQueryUI and CSS) and attached to the DOM and the jQueryUI.datepicker() will be called to your input-elements of type date.
In addition, all of this JS-Stuff will be captured and moved to the END of your DOM (where a script element will be added). Doing this you have the advantage that first the full DOM will be rendered and then the JS will be attached. Meaning your Form is usable sooner than in the example provided by Raj.
Based on the 2 answers, I did a bit more research and came up with my own approach...
Here is the top of my layout.phtml
$this->inlineScript()->offsetSetFile(10,$basePath . '/jquery/jquery-1.10.1.min.js');
$this->inlineScript()->offsetSetFile(12,$basePath . '/jquery-ui/ui/jquery-ui.min.js');
I have assigned all my javascripts with an ID so they are all loaded in the right order.
I then use this in my Form... by default it looks like any form element has the ID set to its name, this makes ite easy to style with input#name
$this->add(array(
'name' => 'start',
'type' => 'DateTime',
'options' => array(
'label' => 'Start Date',
'format' => 'Y-m-d H:i P',
),
));
Its then very easy to style with the following, here is my $action.phtml ...
echo $this->form($form);
# Decorations
$this->inlineScript()->offsetSetScript(99,"
$(function() {
$('input#start').datepicker({
dateFormat: 'yy-mm-dd',
showOtherMonths: true,
selectOtherMonths: true,
});
});
");
You can see here I have assigned it offset 99. This is what I use in all my templates.

Zend Framework 2: Zend_Navigation

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.

Resources