My template layout blade doesn't render when the url is a subfolder.
I made a test example to check:
URL/tests is okay
but
URL/tests/1/edit loses the outer layout template and only renders the content.
Testcontroller:
class TestController extends AdminController {
protected $layout = 'layouts.admin';
public function index()
{
// load the view
$this->layout->content=View::make('tests.index');
}
public function edit($id)
{
//
$course=Course::find($id);
return View::make('tests.edit')->with(array('course'=>$course));
}
}
layout admin.blade.php
<html><body>
{{ $content }}
</body>
</html>
tests/index.blade.php
hello
/tests renders source full layout html code and works fine on proper site examples
tests/edit.blade.php
edit
/tests/1/edit renders with NO layout HTML
There are various ways of using blade but I thought the easiest was with protected layout but there seem to be issues?
Any help appreciated.
In the edit method instead of
return View::make('tests.edit')->with(array('course'=>$course));
use:
$this->layout->content= View::make('tests.edit')->with(array('course'=>$course));
In your AdminController which is the base controller of your TestController, add the layout setings, put this code in your AdminController
protected $layout = 'layouts.master';
protected function setupLayout()
{
if ( ! is_null($this->layout))
{
$this->layout = View::make($this->layout);
}
}
Now you use any view with layout using something like this:
$this->layout->content = View::make('tests.edit')->with(array('course'=>$course));
Here, tests.edit means that edit.blade.php (also could edit.php if not blade) file is in app/views/tests/ directory.
In your index method you have used:
$this->layout->content=View::make('tests.index');
So the layout showed up because you set data to layout but in other example you didn't set data to layout so layout is not rendered, it's returning only the view as given below:
return View::make('tests.edit')->with(array('course'=>$course));
So, setup the layout in the base controller class so in your every controller you don't have to setup the layout, but always set data to the content variable of layout using this:
$this->layout->content = 'your data';
Related
I'm trying to create a custom field for a view in Drupal 8 which allows to perform an action without changing the page (link). I guess I have to create a form inside that custom field but I do not know how to achieve it.
Any idea on how to do it or other alternative without redirecting to a route?
The view will be a list of custom entities and I need a button for each of the lines.
Thanks in advance!
Finally I solved it by following this steps:
I created a view custom field (generate:plugin:views:field with
drupal console)
I created a form (generate:form)
Then, in the view custom field render function return the form:
$form = \Drupal::formBuilder()->getForm('Drupal\test_module\Form\TestForm', $values->_entity->ID());
return $form;
It's important to notice that an incremental (dynamic) formId is needed for things to work properly. I did that by creating a static variable and a __construct() method as follows:
protected static $instanceId;
public function getFormId() {
return 'my_form_id_' . self::$instanceId;
}
public function __construct(){
if (empty(self::$instanceId)) {
self::$instanceId = 1;
}
else {
self::$instanceId++;
}
}
SilverStripe 3.1.x How to Render with a specific template from an Extension?
In SilverStripe 3.1.x, How can I make a Page render with a specific template from a Module Extension? I'm working on a module that allows an administrator to change the display behaviour of a page at specific timeframes. Making the page redirect works fine, but when it comes to rendering with a specific template, it seems to get ignored.
Here's an excerpt of the key parts of my code:
mymodule/_config/mymodule.yml
---
Name: mymodule
After:
- 'framework/*'
- 'cms/*'
---
Page_Controller:
extensions:
- MyPage_ControllerExtension
mymodule/code/MyPage_ControllerExtension.php
class MyPage_ControllerExtension extends Extension {
public function onAfterInit() {
//Render with MyTestTemplate.ss as a test
return $this->owner->renderWith(array('MyTestTemplate', 'Page')); //Don't work
//try redirecting
//return $this->owner->redirect('http://google.com'); //Works fine
}
}
mysite/code/Page.php
class Page_Controller extends ContentController {
private static $allowed_actions = array ();
public function init() {
parent::init();
}
}
themes/simple/templates/Layout/MyTestTemplate.ss
<% include SideBar %>
<div class="content-container unit size3of4 lastUnit">
<article>
<h1>MY TEST TEMPLATE</h1>
<div class="content">MY TEST CONTENT</div>
</article>
</div>
After flushing the template cache, SilverStripe does not render Page.ss with MyTestTemplate.
How do I achieve that from the MyPage_ControllerExtension above?
When I debug by adding the parameter ?showtemplate=1 to the URL, I can see that SilverStripe does indeed get the content for MyTestTemplate, but in the end, it ignores it and the Layout/Page.ss template gets used instead.
This would work for actions and index functions when default rendering is used (by returning array() or $this)
public function onAfterInit() {
$this->owner->templates['index'] = array('MyTestTemplate', 'Page');
}
You could also use $this->owner->templates['currentaction'] if you want
But you'd have to add the following property to your Page_Controller class, because although it is checked from within the Controller class, it doesn't seem to be defined anywhere in the class chain (?):
public $templates;
You could use the index() function in your (Data)Extension to return the rendered data:
public function index() {
return $this->owner->renderWith(array('MyTestTemplate', 'Page'));
}
Note: that would fail though, if the Page you're extending already has an index() function defined.
So, the final solution, from #Martimiz, which works whether or not an action is called is:
In the Page_Controller class in mysite/code/Page.php, add the following property as follows:
class Page_Controller extends ContentController {
public $templates;
⋮
}
In mymodule/code/MyPage_ControllerExtension.php, add:
class MyPage_ControllerExtension extends Extension {
public function onAfterInit() {
$action = $this->owner->request->param('Action');
if(!$action) $action = 'index';
$this->owner->templates[$action] = array('MyTestTemplate', 'Page');
}
}
I have a master layout with #yield('content') but I need my controller to inject a non-blade file into the content section. How can I achieve this?
I've tried in my controller:
protected $layout = 'master';
public function showWelcome()
{
$this->layout->nest('content', 'welcome')->render();
}
Where welcome is an not a blade file. Is this possible or just a limitation of Laravel?
I am developing a joomla website which required some custom component to integrate manage portfolio, user profile etc. We downloaded one of the hello_world MVC component for joomla 2.5[http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Introduction] and did necessary customization. First component worked well. But now we need a new component that is having multiple forms required to integrate.
Eg: Store types for one form, store details for another form, manage country/ state by another form.
In the default component having option for manage one form [add/edit/delete/view]. Here I tried to modify/replicate but I failed.
Can anyone suggest the architecture/ sample code to manage multiple forms [Add/edit/delete/view] in joomla 2.5 component creation.
Any help will be apreciate?
Supposing You're speaking of forms stored in the model/forms folder... You should try to override the getForm() function in your model, to call the right form. You should pass a 'layout' when calling the page and then get it in the model constructor.
May be so:
class YourComponentModelYourModel extends JModelAdmin{
public function __construct($config = array()){
switch(JRequest::getVar('layout')){
case 'firstlayout' : $this->form='firstform';
break;
case 'secondlayout' : $this->form='secondform';
break;
default : $this->form='defaultform';
}
parent::__construct($config);
}
...
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_yourcomponent.'.$this->form,$this->form,
array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)){return false;}
return $form;
}
You must put a layout for each form in the views/YourView/tmpl folder and the form declaration must call the layout also :
<form action="<?php echo JRoute::_('index.php?option=com_yourcomponent&layout=firstlayout&id='.(int) $this->item->id); ?>"
method="post" name="adminForm" id="draw-form">
I don't understand the purpose of using templates in Kohana. I see almost no difference in the process of building a view with a template controller vs a regular controller, except that the template controller is tied to a given template and so is less flexible. What are the advantages?
Building view with regular controller:
Class Controller_Hello extends Controller
{
public function action_index()
{
$view = View::factory('page');
$view->page_title = 'My Hello App';
$view->content = 'hello, world!';
$view->sidebar = View::factory('parts/sidebar');
$this->response->body($view);
}
}
Building view with template controller:
Class Controller_Hello extends Controller_Template
{
public $template = 'page';
public function action_index()
{
$this->template->page_title = 'My Hello App';
$this->template->content = 'hello, world!';
$this->template->sidebar = View::factory('parts/sidebar');
}
}
Controller_Template is just an example of how you can implement your own templating-system.
It is not ready-to-use solution (at least for my projects usually). Check this one controller (it is also not ready-to-use solution but possibly it will help you understand point of extending different controllers for different purposes): http://pastie.org/2563595
I am sure there are other, maybe better solutions for templating systems. But why am I using templates in Kohana?
Think about multiple pages, all based upon one layout/design scheme. So I build a template controller using a certain view, defining layout/design, defining content, header and footer "areas". In the template controller I am loading the CSS files and script files, setting the title and meta values of the website, because every single site is using these CSS/script files with the same meta values and title.
So in every Controller extending the template controller I don't need to load the CSS/script files anew, set the meta values and title etc... But I could change all these values, maybe add a CSS file only for a single site.
Maybe all the mentioned sites have the same footer and/or header: I assign the header/footer view to the template within the template controller, so I don't need to do that in all the controller extending the template controller. Or all actions in one controller have the same header/footer, so I assignt he header and footer few in the before() function of the controller...
For me templates in kohana are a good utility for building small web applications.