I'm using ahDoctrineEasyEmbeddedRelationsPlugin to add dynamic i18n translations to my object, so I wrote this in my object Form class
$this->embedRelations(array(
'Translation' => array(
'considerNewFormEmptyFields' => array('content', 'lang')
));
The result I got is only one input per record, "content".
I've tried this in the FormTranslation class, but no luck:
$this->useFields(array('content', 'lang'));
So what I did was to create a manual doctrine relation with a foreignAlias called "translations", and then:
$this->embedRelations(array(
'translations' => array(
'considerNewFormEmptyFields' => array('content', 'lang')
));
this almost worked, I get the lang field now, but only in the list of existing tranlations, not in the new translation form
Any ideas if I can archieve this? Thanks!
Hm , I always use for example for 'en' and 'uk' culture :
considerNewFormEmptyFields' => array('en','uk')
Related
I have a sfWidgetFormDoctrineChoiceMany widget, I was wondering if there was a way to order the data inside it in ascending order
'locations_list' => new sfWidgetFormDoctrineChoiceMany(array('model' => 'Location')),
To set ordering on sfWidgetFormDoctrineChoiceMany (and sfWidgetFormDoctrineChoice too) you should provide a order_by option. Like this:
// ...
'locations_list' => new sfWidgetFormDoctrineChoiceMany(array(
'model' => 'Location',
'order_by' => array('Name', 'asc'), // <--- replace 'Name' with your column name in camel-case format
)),
// ...
When I need to get a quick reference on widget supported options, I always go to it's source. Usually they have a nice documentation right in PHP comments. Check this link to sfWidgetFormDoctrineChoice source:
https://github.com/nationalfield/symfony/blob/a2d4442dfeb26355e89360f6e725c1f19c3a1ee0/lib/plugins/sfDoctrinePlugin/lib/widget/sfWidgetFormDoctrineChoice.class.php#L33
I'm trying to remove the action in the cakephp url and add a slug inflector, to be more clear this is my expected output:
from this: example.com/posts/view/81/This is a test post
to this: example.com/posts/This-is-a-test-post
This is my current code:
That gives me this output: example.com/posts/view/This is a test post
Controller:
public function view($title = null) {
if (!$title) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findByTitle($title);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
view.ctp:
$this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['title']));
I also tried this one,this link being my reference CakePHP: Use post title as the slug for view method :
Output: example.com/posts/view/21/This-is-a-test-post
Controller:
function view($id) {
$this->Post->id = $id;
$this->set('post', $this->Post->read());
}
view.ctp
$this->Html->link($post['Post']['title'], array('action' => 'view', $post['Post']['id'], Inflector::slug($post['Post']['title'],'-')));
below are the other links that I tried but failed, I also tried the modifying the routes.php but can't make the proper code to make it work
want to remove action name from url CakePHP
How to remove action name from url in cakephp?
Remove action name from Url in cakephp?
any help/suggestions is appreciated thanks.
Use Id and Named parameter...
On routes.php
define new routes as-
Router::connect('/posts/:id-:title',
array('controller' => 'posts',
'action' => 'view')
);
This new defined routes will match and parse all url containing id and title named parameter..
Important Note:: Do not define new routes after the end of routes.php. Try to define on the middle of the file..
On view
echo $this->Html->link('Hi',array(
'controller' => 'posts',
'action' => 'view',
'id' => 4,
'title' => Inflector::slug('the quick brown fox')
));
Well the solution provided above will fulfill your needs, but still after reading your question one thing comes into my mind... in your controller you are trying to read posts using title I mean this will slow down your system not recommended in programming so use id and increase one more column in your db table for slug(SEO title) which will be used for creating your post urls.
For example:
Post title: This is a test post
Create seo title for this as: this-is-a-test-post-123
Stor seo title in DB as <this-is-a-test-post>
See 123 is your posts ID now change your controller function to get data based on id ie.123, I hope you cn extract 123 from the sting easily...
Note: remember you have to think about this-is-a-123 string also because
they also land in post having id 123.
Use below route for the above solution:
Router::connect('/posts/*', array('controller' => 'posts', 'action' => 'view'),array('pass' => array('title')));
Now in your controller:
You will get string "this-is-a-test-post-123" in $post_title
function view($post_title=null){
$temp = explode('-',$post_title);
$posts_id= end($temp);
$lastKey = end(array_keys($temp));
unset($temp[$lastKey]);
$seoTitle = implode("-",$temp);
//Now compare the above seoTitle with DB seo title for unique urls
}
I've followed the tutorial for Zend Framework 2 and I see on the rendered form that the convention for binding the label is to wrap the input element in the label tags as opposed to using the 'for' attribute. While the tutorial didn't cover it, I deduced (correctly) that the attributes array allows for setting a class on the input element itself but what I really want to do is apply a class onto the label defined under options.
Here's an example used in the tutorial (from AlbumForm.php):
$this->add(array(
'name' => 'title',
'attributes' => array(
'class' => 'required', // <- I added this
'type' => 'text',
),
'options' => array(
'label' => 'Title',
),
));
That will render as this:
<label><span>Title</span><input name="title" class="required" type="text" value=""></label>
Optionally, I could live with having the class applied to the span tag but I'd prefer to use the class on the label and then use css child selectors for the span and input elements
I've re-read the tutorial plus the comments on the appropriate section and even dug into the Zend\Form API documentation itself and I don't see how I could apply a class attribute to the label in declaring a form element in this manner.
Another minor nitpick with form rendering is that it appears to be rendered inline with no line breaks between form elements. I've gotten around this by adding a line break in the view scripts (add.phtml and edit.phtml) like so:
echo $this->formRow($form->get('title')) . "\n";
However, this seems like a pain to have to do with every echoed form statement within the view and using the formCollection() also renders the entire form output inline. For legibility purposes I'd like to at least have line breaks where appropriate when viewing the source (I'd wish for proper indentation, too, but that seems like a tall order since even IDE's get it wrong much of the time)
So, is there a built-in option for either of these concerns that I'm missing or, alternatively, a way to define a factory or helper? If I'd need to write a helper, I'd want it to apply to all modules.
To add a class to the label use the 'label_attributes' key in your configuration:
$this->add(array(
'name' => 'title',
'attributes' => array(
'type' => 'text',
),
'options' => array(
'label' => 'Title',
'label_attributes' => array(
'class' => 'required',
),
),
));
To add new lines, you can either write your own FormRow view helper or render the label and element separately within your view script like this:
$form = $this->form;
$form->prepare();
echo $this->form()->openTag($form) . "\n";
echo $this->formLabel($form->get('title')) . "\n";
echo $this->formInput($form->get('title')) . "\n";
echo $this->formElementErrors($form->get('title'));
// other elements
echo $this->form()->closeTag($form) . "\n";
Iam new guy to Zend framework and currently Iam working on Zend2...I want to ask about Translator usage in Zend forms....If i want to use translator i directly using for labels in form view i.e.form_view.php like
$this->formLabel()->setTranslator($translator, 'date_of_birth');
But I want to add the translator at the form only i.e.in src/my_module/Form/UserForm.php
like
$this->add(array(
'name' => 'date_of_birth',
'attributes' => array(
'type' => 'text',
'id' => 'date_of_birth',
),
'options' => array(
'label' => 'DateOfBirth',
), //Here there is any option to put translator
));
Please help me...any answer would be help for me like I asked
Thanks in advance
You don't really need to do that. Since the the Translator that is set up using the factory-key translator will automatically be injected into the Form.
The best approach (in my opinion) is to make extensive use of the translator text_domain:
'translator' => array(
'locale' => 'de_DE',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.php',
'text_domain' => 'MyModuleTextDomain'
),
),
),
With this setup, the Files of your Module will automatically be inserted into the default TranslatorService which every Zend\Form knows of.
So ultimately all you have to do is make the ViewHelpers know of the TextDomain that you are using. And this is done in the following manner:
$this->formLabel()->setTranslatorTextDomain('MyModuleTextDomain');
$this->formButton()->setTranslatorTextDomain('MyModuleTextDomain');
$this->formElementErrors()->setTranslatorTextDomain('MyModuleTextDomain');
You need to do this once inside your respective view.phtml before(!) using the ViewHelpers like $this->formElement($element) or $this->formCollection($form)
And that's really all there is to it. I recall having seen a discussion somewhere about making it easier to pass along Text-Domain-Data, but i can't find it right now. So things may get a little easier in the future ;) For now, 3 lines are all that's needed though!
above answer is quite unnecessary ... as your translator was added automatically to zend form for rendering form labels and ....
only use this code in your module config :
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'phparray',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.php',
),
),
),
if u use the correct view helpers for rendering form elements (or whole form) it will automatically translated
This is not a recommended approach because forms are translated automatically if you have a translator configured (which you do if you are using the Skeleton Application). However, since you asked how to use the translator directly within your form, I will show you how you can do it. Please carefully consider if you really want to do this, as I cannot imagine a use case where it would be necessary.
To do exactly what you were asking, you can inject the translator into your form. You can do this either in your controller or in a factory. I will be using a factory in this example because it is more DRY.
// In your module's config file
'service_manager' => array(
'factories' => array(
'YourModule\Form\YourForm' => function($sm) {
$translator = $sm->get('Translator');
return new \YourModule\Form\YourForm($translator);
},
),
),
Then in your form class, you can do like this:
namespace YourModule\Form;
class RegisterForm extends \Zend\Form\Form {
public function __construct($translator) {
// Do something
$translated_string = $translator->translate('string to translate');
}
}
Then in your controller, you can do like this:
$your_form = $this->servicelocator->get('YourModule\Form\YourForm');
Or if you don't want to use the factory, you can choose to not add it and do like this instead:
$your_form = new \YourModule\Form\YourForm($this->servicelocator->get('Translator'));
I would recommend going with the factory, though.
I'm writing a new version of an API and would like to support legacy versions by having distinct sets of controllers for each version. Within the default "app\controllers" path in Lithium, I would like to have for example "v1" and "v2" paths.
I have tried accomplishing this within the route itself by doing something like:
Router::connect('/{:version}/{:controller}/{:action}{:args}', array(
'controller'=> '\app\controllers\{:version}\{:controller}Controller',
), array());
Then I tried overriding the path in the libraries bootstrap module by doing something like:
if( preg_match('/^\/(v[0-9\.]+)/', $_SERVER['REQUEST_URI'], $match) ) {
Libraries::paths(array(
'controllers' => "controllers\\".$match[1].'\\{:name}Controller',
'models' => "models\\".$match[1]."\\{:name}",
));
}
I spent about a half a day at work searching google and the very sparse lithium docs. I am not sure what release of Lithium we are using as I have stepped into this pre-existing code base.
Thanks for any tips you may have!
In your routes.php file, you should re-configure the Dispatcher default rules with
Dispatcher::config(array('rules' => array(
'v1' => array('controller' => 'app\controllers\v1\{:controller}Controller')
)));
and a continuation route to match /v1/... requests
Router::connect('/v1/{:args}', array('v1' => true), array(
'continue' => true, 'persist' => array('controller', 'v1')
));
You can easily use :version instead of a predefined version number if you need so.