I'm working with Yii2 and I wonder which is the right way to render from a controller a file located within a subfolder in views directory. For example, I have the following situation:
views
-campus (carpeta)
--actividad (subcarpeta)
---2020.php (vista)
So far, I've tried this options but without success:
return $this->render('/actividad/2020',[]);
return $this->render('/actividad/2020',[],$this->context);
return $this->render('2020',[],$this->context);
return $this->render('#app/views/campus/actividad/2020',[]);
return $this->render('//actividad/2020',[]);
My controller CampusController:
<?php
namespace frontend\controllers;
class CampusController extends \yii\web\Controller
{
public function action2020()
{
return $this->render('actividad/2020');
//return $this->render('/campus/actividad/2020');
//return $this->render('//campus/actividad/2020');
//return $this->render('#app/views/campus/actividad/2020');
}
}
If you are on CampusController, want to render 2020.php, and have the folder structure that you show in your question:
views
-campus (carpeta)
--actividad (subcarpeta)
---2020.php (vista)
All the following ways would work:
return $this->render('actividad/2020');
return $this->render('/campus/actividad/2020');
return $this->render('//campus/actividad/2020');
return $this->render('#app/views/campus/actividad/2020');
If you are not passing any parameters to the view, you can pass an empty array, but you can also remove the second parameter.
You do need to return the result of $this->render(...), in your question it looks like you are calling return after, that would return an empty response instead of the result of rendering the view file.
Related
I'm brand new to CodeIgniter, so apologies if I'm missing something obvious here.
I'm comfortable with sending data from a controller to a view file using return view('default/blog/index', $data);. My issue is accessing the same data in a layout file which is extended by the view file using <?= $this->extend('layouts/default'); ?>.
For example, if I insert <?= $data['content'] ?> in my view file, it displays as expected. If I insert the same code in the layout file that is extended by my view file, I get the "Trying to access array offset on value of type null" exception.
What am I missing that will allow me to access my data from within the layout file?
Thanks in advance.
Update:
So in my BlogController I've got
class BlogController extends BaseController
{
public function index()
{
$model = new Blog();
$data = $model->getBlog();
return view('default/blog/index', ['data' => $data]);
}
public function item($slug = null){
$model = new Blog();
$data = $model->getBlog($slug);
return view('default/blog/item', ['data' => $data]);
}
}
And then in my item.php and index.php files, I have
<?= $this->extend('layouts/default', ['data' => $data]); ?>
My Blog Model's getBlog() method:
public function getBlog($slug = false)
{
if ($slug === false) {
return $this->orderBy('bs_created_dt', 'desc')->findAll();
}
return $this->where(['bs_slug' => $slug])->first();
}
When I use the debug toolbar to inspect the data, it is showing as expected, and I can display it in the view files, but not in the layout file.
In Codeigniter, you need to pass data also in an extended file called layouts.
Because you want to access data inside the extended file and for that, you just need to pass data to that file.
So replace the line of code of extended view with this :
$this->extend('layouts/default', ['data' => $data]);
Figured this out - absolute rookie mistake.
I'm working off of a pre-existing template, and the previous developer had overwritten the $data variable in layout file before where I was trying to use it.
I'm off to stand in the corner for a while.
In my laravel app database, the resource are saved as link like this
/storages/photos/bla-bla.png
what is the best way, so I can append my app url to the result,
www.baseurl.example/storages/photos/bla-bla.png
it's because the backend and front end has difference base url
Thanks
IT can be achieved in two ways
While storing the images/files
$request->photo
->storeAs(
'photos',
config('app.url'). $request->file('photo')->getClientOriginalName()
);
While accessing (via an accessor)
class Some extends Model
{
public function getPhotoAttribute($value)
{
return config('app.url'). $value;
}
public function setPhotoAttribute($value)
{
$this->attributes['photo'] = str_replace(config('app.url'), '', $value);
}
}
You need to set the correct value for APP_URL in the .env file
I have been successfully using XML view files in CakePHP (request the XML output type in headers so CakePHP will use e.g. Orders/xml/create.ctp instead of Order/create.ctp).
However, now i need to add some functionality that requires me to the reformat the XML at the end of most business logic in the controller.
So i tried this in the controller action:
public function createorder() {
$this->autoRender = false; // disable automatic content output
$view = new View($this, false); // setup a new view
{ ... all kinds of controller logic ...}
{ ... usually i would be done here and the XML would be outputted, but the autorender will stop that from happening ... }
{ ... now i want the XML in a string so i can manipulate the xml ... }
$view_output = $view->render('createorder'); // something like this
}
But what this gives me is:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<error>View file "/Users/test/Documents/hosts/mycakeapp/app/View/Orders/createorder.ctp" is missing.</error>
<name>MissingViewException</name>
<code>500</code>
<url>/orders/createorder/</url>
</response>
So i need to tell CakePHP to pickup the xml/createorder.ctp instead of createorder.ctp. How do i do this?
Cheers!
This answers refers to cakephp 2.4
I have been successfully using XML view files in CakePHP (request the XML output
type in headers so CakePHP will use e.g. Orders/xml/create.ctp
instead of Order/create.ctp).
In lib/Cake/View you can see different View files like:
View.php
XmlView.php //This extends View.php
JsonView.php //This extends View.php
So you told cakephp to use the XmlView. When you create a new View you need to use the XmlView instead of View. Or you can create your own custom View and put it inside app/View folder. In your custom View you can set your subdir.
<?php
App::uses('View', 'View');
class CustomView extends View {
public $subDir = 'xml';
public function __construct(Controller $controller = null) {
parent::__construct($controller);
}
public function render($view = null, $layout = null) {
return parent::render($view, $layout);
}
}
So what you need now is to create your custom view $view = new CustomView($this, false);
You can also write in your CustomView functions to handle the data as xml and use it to every action.
Also #Jelle Keizer answer should work. $this->render('/xml/createorder'); points to app/View/xml/createorder. If you need this to point to app/View/Order/xml/create just use $this->render('/Orders/xml/create');.
$this->render('/xml/createorder');
I'm trying to integrate custom code into my Laravel project, here's the current folder structure :
You can see my controllers and models - views are in a module subfolder and I already made the controller and views run properly, but now I want to load a config file under module/Csol/Fight/Config, named development.php (for example) - here's my current attempt :
In my controller :
public function __construct()
{
$namespacePath = substr(__NAMESPACE__, 0, strrpos(__NAMESPACE__, "\\"));
View::addNamespace($namespacePath, app_path()."/module/".str_replace("\\", "/", $namespacePath).'/views');
Config::addNamespace($namespacePath, app_path()."/module/".str_replace("\\", "/", $namespacePath).'/Config');
var_dump(get_class(Config::getFacadeRoot()));
}
public function showWelcome()
{
// View::addLocation(app_path().'/module/Csol/Fight/views');
echo "<pre>";
var_dump($this);
echo "</pre>";
var_dump(Csol\Fight\Config::getItems());
die();
return View::Make("Csol\Fight::a");
}
development.php:
return array(
"dbs"=>array(
"host"=>"sss",
"db_name"=>"ccc",
)
);
I can't get the result of my own config file, any help please ?
Problem fixed...
takes me a little more time...
I should use this var_dump(Config::get('Csol\Fight::development.xxx'));
instead of var_dump(Csol\Fight\Config::getItems());
have fun...
I'm new to working with CI and I have a question. More like a design method suggestion. I want to create a base template for static pages. Basically I want to load doc type, head, and the body but nothing else. I want the content to be loaded by whatever class/function I call via the URL. I know I can do this with a HTML template and str_replace() but is there a better way or some fancy CI method I'm not familiar with?
Here is what I have so far and it works but it's not the best.
class Sandbox extends CI_Controller {
public function __construct() {
parent::__construct();
//echo "hello world?";
}
public function load($what){
if ($what == 'something'){
if (!file_exists('application/views/content/'.$what.'.php')){
// Whoops, we don't have a page for that!
show_404();
}
$data = array();
$this->load->view('templates/header', $data);
$this->load->view('content/'.$what, $data);
$this->load->view('templates/footer', $data);
}
else { // Default load
$data = array();
$data['message'] = 'Hello World';
//$this->load->view('templates/header', $data);
$this->load->view('content/sandbox', $data);
//$this->load->view('templates/footer', $data);
}
}
}
When I load the view method it seems to work but I had to add the doctype and head to the template. I would prefer to load those seperately so do not have to create multiple headers. What I am looking for is a way to specifically load parts of the page and whatever scripts/css that are required for that given page.
Thanks for any advice.
Your function names in the controller are references to the url eg:
www.ci.com/sandbox/load
The above url would load function load() inside the sandbox controller.
To create a template you can just create a view with the basics that you want and then pass the content to that view eg:
function home(){
$data['content'] = $this->load->view('home_content',,TRUE);
this->load->view('template', $data)
}
By using TRUE in the 3rd argument you are returning the data rather than displaying it.
Then in the template file just echo $content;
You could also create separate head files and other files to include in your template using the same method ie:
function home(){
$data['content'] = $this->load->view('home_content',,TRUE);
$data['head'] = $this->load->view('head',,TRUE);
this->load->view('template', $data);
}
You can also pass the data variable to views that you are returning ie:
$data['content'] = $this->load->view('home_content',,TRUE);
$data['admin_script'] = $this->load->view('admin_script',,TRUE);
$data['head'] = $this->load->view('head',$data,TRUE);
I hope this helps! :)
ALSO
If you want to load different pages you should create separate functions for them and create a new routing rule : Codeigniter: URI ROUTING