I'm new to Zend framework and trying to get some insights about code re-usability. I definitely know about modules but there seems to be a bit of uncertainty about what functionality should go into modules and what not.
What I'm trying to accomplish:
1) to have reusable mini programs/widgets/plugins (whatever you may call them) that one can simply plug into any site be doing this in layout or view:
<?php echo $this->contactform;?>
or this in the view:
<?php echo $this->layout()->blog;?>
I'd call them extension. so basically sort of what you'd see in Joomla/ WordPress/Concrete5 templates.
2) All code that is related to that specific extension should be in it's separate directory.
3) We should be able to output extensions only for certain modules/controllers where they are required. they shouldn't be rendered needlessly if it won't be displayed.
4) each extension may output multiple content areas on the page.
Do you have a nicely laid out structure / approach that you use?
It sounds like you need study up on view helpers. View helpers can be a simple as returning the App Version number or as complicated as adding html to multiple place holders. For example:
layout.phtml:
<h1><?php echo $this->placeholder('title'); ?>
<div class="sidebar">
<?php echo $this->placeholder('sidebar'); ?>
</div>
<div class="content">
<?php echo $this->layout()->content; ?>
</div>
in your view script foo.phtml for example:
<?php
$this->placeholder('title')->set('Hello World!');
$this->placeholder('sidebar')->set('Hello World!');
?>
<h1>Bar Bar!</h1>
Now if you want to be able to reuse that over and over again you can do this:
<?php
class Zend_View_Helper_MyHelper extends Zend_View_Helper_Abstract
{
public function myHelper()
{
$this->view->placeholder('title')->set('Hello World!');
$this->view->placeholder('sidebar')->set('Hello World!');
return '<h1>Bar Bar!</h1>';
}
}
Now, replace the code in your foo.pthml with:
<?php
echo $this->myHelper();
Both examples of foo.phtml output:
Hello World!
Hello World!
Bar Bar!
Of course this is very simplified example, but I hope this helps point you in the right direction. Happy Hacking!
Related
I"m trying to write custom auto complete for text field. can anyone pls tell me where to write this jquery, ajax code for this textfield in yii..
<div id="output" class="row">
<?php echo $form->labelEx($model,'id'); ?>
<?php echo $form->hiddenField($model,'id'); ?>
<?php echo $form->textField($model,'id');
'$(function () {
$("#search").change(function(){
$.ajax({url:BASE_URL + '/controller/lookup/',
type:"POST",
data:this.value,
success:function(data){
$("#output").html(data);
}
});
});
});'?>
any help pls,
Many Thanks
Try Yii::app()->clientScript->registerScript instead of Yii::app()->getClientScript()->registerScript
You should just make a new file, call it, 'myFuncs.js'. Place in a directory within your Yii Web App.
Then, in your view, simply call the js file.
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl.'/path/to/your/scripts/myFunc.js');
i am using partials to decorate Zend_Navigation to fetch desired output. everything is working good except i am having difficulty adding class="active" in <a href..> tag. here is my layout partial sidebar.phtml
<ul id="menu" class="nav">
<?php foreach($this->container as $page): ?>
<li class="<?php echo $page->class; ?>"><span><?php echo $page->label; ?></span></li>
<?php endforeach; ?>
</ul>
in the <a href="<?php echo $page->getHref(); ?>"> i want to add class="active" for the current page.
i tried some solutions which i found after searching. but nothing worked for me.
most of the solutions talk about doing it in controller for example
$page = $this->view->navigation()->findOneByLabel('Your Label');
if ( $page ) {
$page->setActive();
}
i haven't tested this yet. as i am using multiple navigations in the layout from one single navigation.xml file. i was wondering if is there a way i could do it in partials itself instead of in controllers or other helpers?
thank you
It's easy. In the view partial you can check which page is active:
if ($page->isActive()) { ... }
From ZF documentation:
Note: Note that when using the route property in a page, you should also specify the default params that the route defines (module, controller, action, etc.), otherwise the isActive() method will not be able to determine if the page is active. The reason for this is that there is currently no way to get the default params from a Zend_Controller_Router_Route_Interface object, nor to retrieve the current route from a Zend_Controller_Router_Interface object.
In Zend Framework, Can anybody explain the difference between partial and placeholder?
From my understanding, one can render a particular template / container by using both placeholders and partials.
In which condition should one use a partial and what scenario is optimal use for placeholders?
It's pretty simple, the placholder is used to persist data between views and layouts and partials are used in specific views to do specific tasks.
See these excerpts from the reference.
77.4.1.6. Placeholder Helper: The Placeholder view helper is used to persist content between view scripts and view instances. It also
offers some useful features such as aggregating content, capturing
view script content for later use, and adding pre- and post-text to
content (and custom separators for aggregated content).
77.4.1.5. Partial Helper: The Partial view helper is used to render a specified template within its own variable scope. The primary use is
for reusable template fragments with which you do not need to worry
about variable name clashes. Additionally, they allow you to specify
partial view scripts from specific modules.
Here is a simple example of a placeholder, that sounds like what you want. (to persist data)
<?php
//this is placed in my layout above the html and uses an action helper
//so that a specific action is called, you could also use view helpers or partials
$this->layout()->nav = $this->action('render', 'menu', null,
array('menu' => $this->mainMenuId))
?>
<div id="nav">
//Here the placeholder is called in the layout
<?php echo $this->layout()->nav ?>
</div>
in this case the menu id's are setup in the bootstrap, however this is not requiered it just simple.
protected function _initMenus() {
$view = $this->getResource('view');
$view->mainMenuId = 4;
$view->adminMenuId = 5;
}
[EDIT]
I think a better placeholder example might be in order. This place holder is a small search form I use in several actions in several controllers in different configurations.
In this configuration this form is setup to search just for music artists, the controllers that use this placeholder will have different paths for setAction(), different Labels and sometimes different placeholder text. I use this same form to search music and video databases.
I you always use the same setup or have more interest in doing it then I do, this can be setup as a plugin.
//in the controller
public function preDispatch() {
//add form
$searchForm = new Application_Form_Search();
$searchForm->setAction('/admin/music/update');
$searchForm->query->setAttribs(array('placeholder' => 'Search for Artist',
'size' => 27,
));
$searchForm->search->setLabel('Find an Artist\'s work.');
$searchForm->setDecorators(array(
array('ViewScript', array(
'viewScript' => '_searchForm.phtml'
))
));
//assign form to placeholder
$this->_helper->layout()->search = $searchForm;
}
I use the placeholder in my layout (can also be used in any view script). The search form is rendered when the placeholder has a value and not rendered when the placeholder has no value.
//in the layout.phtml
<?php echo $this->layout()->search ?>
and just to be complete, here is the partial that the form uses as a viewscript decorator.
<article class="search">
<form action="<?php echo $this->element->getAction() ?>"
method="<?php echo $this->element->getMethod() ?>">
<table>
<tr>
<th><?php echo $this->element->query->renderLabel() ?></th>
</tr>
<tr>
<td><?php echo $this->element->query->renderViewHelper() ?></td>
</tr>
<tr>
<td><?php echo $this->element->search ?></td>
</tr>
</table>
</form>
</article>
This example should really illustrate the difference between partial and placeholder.
I think what might be more helpful for you here is either a custom view helper, possibly expanding on the existing Zend_View_Helper_FormSelect class or create a custom Zend Form element that suits your needs. Alternatively, a helper script that's in a general location may be the best bet.
I got few issues proting a pear based form to zend form.
I have few elements I need :
Basic Elements
Groups
Group Elements
Sections
I previously used templates to render the forms on Pear. I obviously cannot use pre-existing zend decorators, since I need to specify css classes for each of the components of my base elements.
To see the issue I need to render this, which is the template for a basic element :
<li class = "{position_in_the_form} {error}">
<label class="{label_class}"> {label}
[<span class="required_class"> * </span>]
</label>
<div> {element_content} </div>
[<p class = "{error_class}"> {error_message} </p>]
</li>
So as you can see I have many dynamic things I would like to be able to specify : position in the form, class for the label, class for the required section, the class for the error.
I would also like to be able to specify this from an ini file. I manage to set up the basic meta from the ini but not custom fields.
One of the reason I cannot use basic decorators is that I need to have "error" in the "li" class when there is an error in the element or the sub_form.I'm not sure this is possible with the error decorator... (correct me if I'm wrong)
Also, for the group I need something handling the errors, and since the core groups don't handle errors I need to subclass the sub_form. But how can I create a subform in an ini file and I don't know how to provide parameters to the sub form fromn the ini.
The main idea here is to be able to have visual and logic groups of elements in a form. For example I need a 'name' group with fullname, middle name, etc. This also implies a global validator for this "name" group.
An other thing is that I want to be able to position these groups : left half, right half, full
I got the css ready for this and working with pear.
So what I need is a simple solution, with few code and ini configurations. Unfortunately I think I got stuck in something too complicated, so if someone has any idea about a simple architecture it would be amazing!
Thanks in advance for your help,
Best, Boris
In your complex decoration need, you might want to use the ViewScript Zend_Form_Element_Decorator
$element->setDecorators(array(
array('ViewScript', array('viewScript' => 'path/to/your/views/element.phtml')),
));
and then in path/to/your/views/element.phtml, more or less something like
<li class="<?php echo $this->element->getAttrib('position_in_the_form') ?> <?php echo $this->element->hasErrors() ? 'error' : '' ?>">
<label class="<?php echo $this->element->getAttrib('label_class') ?>">
<?php echo $this->formLabel($this->element->getName(),
$this->element->getLabel()) ?>
<? if ( $this->element->isRequired() ) { ?>
[<span class="required_class"> * </span>]
<? } ?>
</label>
<div> <?php echo $this->{$this->element->helper}(
$this->element->getName(),
$this->element->getValue(),
$this->element->getAttribs()
) ?> </div>
<? if ( $this->element->hasErrors() ) { ?>
[<p class="<?php echo $this->element->getAttrib('error_class') ?>"> <?php echo $this->formErrors($this->element->getMessages()) ?> </p>]
<? } ?>
</li>
This is only a drafty snippet of code, but should lead you in the direction you aim.
Regards
Has anyone run into this problem...
In my layout.phtml I have:
<head>
<?= $this->headTitle('Control Application - ') ?>
</head>
then in index.phtml I have:
<? $this->headTitle()->append('Client List'); ?>
I expect that, when I go to my index action, the title should be 'Control Application - Client List' but instead I have 'Client ListControl Application - '
What is going on? How can I fix this?
Default behaviour of the headTitle() is to append to the stack. Before calling headTitle() in layout.phtml, your stack is:
Clientlist
Then, you call headTitle with the first argument and no second argument (which makes it default to APPEND), resulting in the following stack:
ClientListControl Application -
The solution, in layout.phtml:
<?php
$this->headTitle()->prepend('Control Application -');
echo $this->headTitle();
?>
Additionally, you can use the setPrefix method in your layout as such:
<head>
<?= $this->headTitle()->setPrefix('Control Application') ?>
</head>
And in your controllers/actions/etc use the standard append/prepend:
<?php
$this->headTitle()->setSeparator(' - ');
$this->headTitle()->append('Client List');
?>
I don't actually use headTitle, but do use ZF, and I had a quick look on the mailing list, this might solve the problem:
<head>
<?= $this->headTitle('Control Application') ?>
</head>
Then:
<?php
$this->headTitle()->setSeparator(' - ');
$this->headTitle()->prepend('Client List');
?>
This happens because the layout is the last script to be executed. So you actually do the append BEFORE the set of the title, so that there's nothing to append to yet.
Set the main title (Control Application) in a Controller. For example I always do it in the predispatch action of a initPlugin so that it is execute before any other Controller Action, and I can append or prepend at will.
To use such a plugin just define a new Class extending Zend_Controller_Plugin_Abstract and define a function preDispatch(Zend_Controller_Request_Abstract $request) where you can put all your common-to-the-whole-site code, and to register the plugin just put it into the controllerFront of your bootstrap: $controller->registerPlugin(new InitPlugin());