Rendering views inside layouts - forms

I'm trying to use a form in my main.php layout. The form is in the view folder with views related to my newsletter model and controller.
So far I've tried to create the following widget:**
<?php
namespace app\components;
use app\models\Newsletter;
use yii\base\Widget;
use yii\helpers\Html;
class NewsletterForm extends Widget
{
public function run()
{
$model = new Newsletter;
return $this->render('_form', [
'model' => $model
]);
}
}
?>
The widget is located in: app\components\NewsletterForm.php
I have a DB model called Newsletter.php and a database table called newsletter.
There is a folder inside app\views called newsletter. This folder as the _form.php where i want the user to input name and email to receive the newsletter.
The problem is I need to load the _form in views\newsletter in the footer of main.php
When I use the widget I always get the error:
The view file does not exist: /Applications/MAMP/htdocs/beladona/components/views/_form.php
How can I render the form inside views\newsletter\ _form.php.
The form needs to render inside the footer of main.php

After extensive discussion with the OP, we decided that a widget wasn't appropriate for his use case. Widgets are intended to be independent pieces of code, capable of being re-used in different situations. All he wanted to do was render a view file from an existing MVC combination
So here is what we settled on;
Layout being used is main.php We edited this for the following;
use app\models\Newsletter;
echo $this->render('#app/views/site/_index', 'model' => new Newsletter);
This has the advantage of keeping the existing form he is using.
He then needed to specify a controller/action combination to use in the form, like this;
$form = ActiveForm::begin([
'action' => Url::to(['newsletter/create'])
]);

Related

Joomla: how can I use one form for frontend and backend view?

I am creating a Joomla 2.5 component. In the backend I created a model/view/controller 'Members' which shows a grid. I also created an MVC 'Member' which is used to add or edit a member from the grid. So far so good.
Now, I would like to add a frontend view that is very similar to the 'Member' view in the backend, but this one is meant for visitors so they can subscribe themselves. It has to look more user friendly than the backend form, so I will create a slightly different 'Member' view in the frontend, but I would really like to reuse the form file (/administrator/components/mycomponent/models/forms/member.xml) from the backend!
So, my question is how my frontend view can find and use that backend form?
You definitely have to load it in the model. Your model has to extend JModelAdmin and then the getForm function has to load the form
public function getForm($data = array(), $loadData = true) {
// Get the form.
JForm::addFormPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/forms');
JForm::addFieldPath(JPATH_COMPONENT_ADMINISTRATOR . '/models/fields');
$form = $this->loadForm('com_dpattachments.attachment', 'attachment', array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)) {
return false;
}
....
}
I'm using the same approach in my DPAttachments component, it is for Joomla 3.1 but the main code, to use the same model and form on the front and back, should also run on Joomla 2.5. Here is the link to the getForm function
https://github.com/Digital-Peak/DPAttachments/blob/master/com_dpattachments/admin/models/attachment.php#L102
If you are following Joomla MVC guidance your frontend should be able to pick-up the forms automatically.
In your view (though it should request it from the model actually) you can write:
$formsPath = JPATH_ADMINISTRATOR.DS.'components'.DS.'com_mycom'.DS.'models'.DS.'forms';
$this->form = JForm::getInstance('myform', $formsPath.DS.'myform.xml');
You can also look at the summer of code cm_config project which pulls the config forms and the templateDetails form to the front end using JSON. https://github.com/Buddhima/joomla-cms/tree/gsoc_com_config or the com_services branch.

Automatically clear captured placeholder view-helper content after it is displayed

Generating a mail message in a partial, I use the placeholder view-helper as follows:
<?php $this->placeholder('mykey')->startCapture() ?>
Some content here that is actually more complicated than just text.
Trust me that, in this case the, using the placeholder for capturing
is desirable.
<?php
$this->placeholder('mykey')->endCapture();
echo $this->placeholder('mykey');
?>
The problem is that if I use the same key in a different partial for a different mail message within the same request, then this captured content is still stored in the container for that key. In principle, I'd like the partials to be free to use whatever placeholder keys they want without having to sweat what other partials are using.
I know I can use different keys in different partials. Alternatively, I can manually clear the content after use/display with something like:
$this->placeholder('mykey')->set('');
But I'd hate to put the burden of all that on the view script that uses the placeholder.
I suspect what I want to do is create my own custom placeholder view-helper that auto-clears his captured content after it has been output.
I've tried creating a custom placeholder container (extends the Standalone container, overriding the toString() method), creating a custom view-helper (extends the the standard Placeholder view-helper), and telling the view-helper to use the custom container class.
But I keep bumping into some error associated to a missing view object. Clearly, I'm missing something about the how the view object, the container, and the registry all interact - and probably even something how the plugin system loads them all.
Any advice and general explanation greatly appreciated.
You need to set this container in the Placeholder view helper because otherwise the Zend_View_Helper_Placeholder_Registry loads automatically the Zend_View_Helper_Placeholder_Container. So, first you need to set your custom container manually. In a view script:
$this->getHelper('placeholder')
->getRegistry()
->setContainerClass('My_View_Helper_Placeholder_Container');
Or for exameple in a _initCustomContainer() in your Bootstrap.php:
$view = $this->bootstrap('view')->getResource('view');
$view->getHelper('placeholder')
->getRegistry()
->setContainerClass('My_View_Helper_Placeholder_Container');
Then, you need to create this class based on the Zend_View_Helper_Placeholder_Container (and not the Zend_View_Helper_Placeholder_Container_Standalone. I'd suggest you keep the option open to reset the content or not, you do that with a setter:
class My_View_Helper_Placeholder_Container
extends Zend_View_Helper_Placeholder_Container
{
protected $_resetCapture = true; // defaults true for new behaviour
public function setResetCapture($flag)
{
$this->_resetCapture = (bool) $flag;
return $this;
}
public function toString($indent = null)
{
$return = parent::toString($indent);
if ($this->_resetCapture) {
$this->exchangeArray(array());
}
return $return;
}
}
By default, the reset capture is already on, but to switch it off and start capturing:
$this->placeholder('my_key')->setResetCapture(false)->startCapture();
And to switch it on again:
$this->placeholder('my_key')->setResetCapture(true);
In a view script, use:
$this->placeholder('mykey')->captureStart('SET');
or using the class constant:
$this->placeholder('mykey')->captureStart(Zend_View_Helper_Placeholder_Container_Abstract::SET);

passing values from model to view in CI

I have this library in CI that retrieves my latest twitter updates. It has a function that sends my latest updates as objects to my controller.
I would like to show these twitter updates on the footer of my page, so they're visible at all times.
Now my question is how I call these directly from a view? I know this is not a good practice in MVC but I don't see how else I could do this.
My controller currently takes care of all my different pages (it's a small website) and I don't think it's very good practice to call my twitter class at the end of every page-function in the controller and then send it through to the views.
Typycally I do this in my controller:
<?php
function index(){
$data['page'] = 'home';
//i don't want to call my twitter class here every single time I write a new page. (DRY?!)
$this->load->view('template', $data);
}
?>
And it loads the "template" view that looks like this:
<?php
$this->load->view('header');
$this->load->view('pages/'.$page);
$this->load->view('footer');
?>
So any suggestions how I should do this?
I have a helper library that takes a page Partial and wraps it in the master theme. You can use the optional parameter on your load->view to render to a string.
Then when you render your master page, you can load the twitter updates, and display them. Although, I highly suggest caching your twitter response for 5 minutes at least, will save you a LOT of overhead.
Example:
// Controller somwhere:
$content = $this->load->view('pages/'.$page, array(), true);
$this->myLibrary->masterPage($content);
// Your library:
function masterPage($content)
{
$twitterData = $this->twitter->loadStuff(); // whatever your function is
$twitter = $this->load->view('twitter_bar', array('data' => $twitterData), true);
$this->load->view('master', array('content' => $content, 'twitter' => $twitter);
}
An alternative approach is to use a base controller. All my controllers extend my custom base controller which holds things I need on every page, for example an object containing the current user.

Symfony forms or normal HTML forms

I am using Symfony 1.4 to create project, and i need to create dynamic forms depending upon the question set type coming from database. i have used Symfony forms in rest of my project, but in this case using symfony forms seems to be tough, as i need dynamic form.
can it be safe to use normal HTML forms..in symfony project, or it is advisable to use Symfony forms. so need your help.
You can use html forms, but it would bypass symfony's form validation system.
You can still build dynamic forms by creating and adding input widgets to the current form, or a new form inside an action. You can then echo the form in the template and the dynamically generated fields will be part of the form as well.
If you start with a MyForm.class.php in the lib/forms, make sure to add:
$this->validatorSchema->setOption('allow_extra_fields', true);
Otherwise, you will automatically get validation errors. If you want to add fields to a form in an action you would do something like this:
$this->form = new MyForm();
$widgetSchema = $this->form->getWidgetSchema();
$widgetSchema['add_field'] = new sfWidgetFormInputText();
When you echo your form the 'add_field' input will be added to it.
It would help to have more information about what you're doing, but here's one way in which forms can be dynamic in Symfony. This code creates widgets and validators for a survey dynamically based on the "type" of a question:
class SurveyAnswerForm extends BaseSurveyAnswerForm
{
public function configure()
{
$question = $this->object->Question;
$method = sprintf('createWidgetAndValidatorFor%sInputType', $question->type);
$this->$method($question);
$this->getWidget('value')->setOption('label', $question->question);
$this->getValidator('value')->setOption('required', $question->required);
}
protected function createWidgetAndValidatorForTextFieldInputType(Question $question)
{
$this->setWidget('value', new sfWidgetFormInputText());
$this->setValidator('value', new sfValidatorString());
}
protected function createWidgetAndValidatorForTextAreaInputType(Question $question)
{
$this->setWidget('value', new wfWidgetFormTextareaAutosize());
$this->setValidator('value', new sfValidatorString());
}
//etc. for as many types as you require
}
Note: while this answer is code from one of my projects, it was heavily influenced by this answer over on SymfonyExperts.

Drupal 6 - How to customise form layout using theme

I have create a new content type and added new form items using CCK. I need to customise the layout of the form which I've partially managed using css and moving items around and adding custom markup in the form_alter hook. However, this still isn't enough as the weightings don't appear to be doing exactly what I want them to do.
Is there a way I can do this using a theme.tpl.php file?
Thanks
Steve
once in a time I was in the same situation and found a quite easy solution.
I needed a highly customized registration form and form_alter was a mess. So I used a template for the form and printed each field into the html output.
First register a new template for the form in template.php of you theme.
<?php
function your-theme-name_theme() {
return array(
'user_register' => array(
'arguments' => array('form' => NULL),
'template' => 'user-register',
),
);
}
?>
Now add a new template to your theme. In my case "user_register.tpl.php". Add the following lines to it, so that the form still works.
<?php
print drupal_render($form['form_build_id']);
print drupal_render($form['form_id']);
print drupal_render($form['form_token']);
?>
From there on you can add as much html as you want and put the form fields where ever you need them. Here are examples for the gender and birthday field. As you can see you have to use the internal CCK names.
<?php print drupal_render($form['field_profile_gender']); ?>
<?php print drupal_render($form['field_profile_birthday']); ?>
I have not tested this for any other form than user_register, but I guess it should work as long as the template name equals the name of the form.
I hope this will help you.
Regards
Mike