Right now I am displaying HTML in my view by using html_entity_decode:
<strong>Body:</strong>
<?php echo html_entity_decode($post->body); ?></p>
But is there another way to do in when I am passing data to my view, in:
public function action_view($id = null)
{
$data['post'] = Model_Post::find($id);
is_null($id) and Response::redirect('Post');
$this->template->title = "Post";
$this->template->content = View::forge('post/view', $data);
}
I read the documentation and tried:
public function action_view($id = null)
{
$data['post'] = Model_Post::find($id);
is_null($id) and Response::redirect('Post');
$this->template->title = "Post";
$this->template->content = View::forge('post/view', $data);
View::$auto_encode = false;
}
But this just gave me an "access to undeclared static property". Clearly I am doing something wrong...
As I can see you are not setting auto_encode correctly.
Try this and see if it's what you are looking for.
public function action_view($id = null)
{
$view = View::forge('post/view');
is_null($id) and Response::redirect('Post');
$post = Model_Post::find($id);
$view->set('post', $post, false); //Here the auto_encode is set to false
$this->template->title = "Post";
$this->template->content = $view;
}
Hope this helps
There are abunch of ways to do this:
protected $this->auto_encode = false;
That property in the controller will stop ALL assigned values from being encoded.
Otherwise, use this:
$this->template->set('title', "Post", false);
$this->template->set('content', $view, false);
That'll stop the specific value being encoded.
Related
I'm trying to follow the instructions on this docs page, but I seem to be missing something:
https://docs.joomla.org/Supporting_SEF_URLs_in_your_component
The URI that needs to be corrected is: index.php?com_component&view=legal&page=customermasteragreement
It seems like the routing function should be simple, but the page is just displaying default instead of the sub-view.
Here's my current code:
function ComponentBuildRoute(&$query)
{
$segments = array();
if (isset($query['view'])) {
$segments[] = $query['view'];
unset($query['view']);
}
if (isset($query['page'])) {
$segments[] = $query['page'];
unset($query['page']);
}
return $segments;
}
function ComponentParseRoute($segments)
{
$vars = array();
switch($segments[0])
{
case 'legal':
$vars['view'] = 'legal';
break;
case 'customermasteragreement':
$vars['page'] = 'customermasteragreement';
break;
}
return $vars;
}
Update
This code works to display the subpage, but it gives me a URI like: legal-agreements/legal?page=customermasteragreement
class ComponentRouter extends JComponentRouterBase {
public function build(&$query) {
$segments = array();
$view = null;
if (isset($query['view'])) {
$segments[] = $query['view'];
$view = $query['view'];
unset($query['view']);
}
if (isset($query['id'])) {
if ($view !== null) {
$segments[] = $query['id'];
} else {
$segments[] = $query['id'];
}
unset($query['id']);
}
return $segments;
}
public function parse(&$segments) {
$vars = array();
// View is always the first element of the array
$vars['view'] = array_shift($segments);
return $vars;
}
}
EDIT 2
If it helps, here's my model and views
models/legal.php
// import Joomla modelitem library
jimport('joomla.application.component.modelitem');
class ComponentModelLegal extends JModelItem {
public function __construct($config = array())
{
JLoader::register('ComponentHelper', JPATH_COMPONENT_ADMINISTRATOR . '/helpers/component.php');
parent::__construct($config);
}
/**
*
* #return string
*/
public function getLegal() {
$app = JFactory::getApplication();
$page = $app->input->get('page', '', 'STRING');
if ($page) {
ComponentHelper::add('type', $page); //This is an API request to an external service, returning JSON formatted data
$legal = ComponentHelper::getData('commons/legal-agreements.json', TRUE);
if (isset($legal[0]['status'])) {
JError::raiseError(400, $legal[0]['ERROR']);
return false;
} else {
if (!isset($this->legal)) {
$this->legal = $legal;
}
return $this->legal;
}
}
}
}
views/legal/view.html.php
class ComponentViewLegal extends JViewLegacy {
function display($tpl = null) {
// Assign data to the view
$this->legal = $this->get('legal');
// Check for errors.
if (count($errors = $this->get('Errors'))) {
JLog::add(implode('<br />', $errors), JLog::WARNING, 'jerror');
return false;
}
// Display the view
parent::display($tpl);
}
}
views/legal/tmpl/default.php
$page = JRequest::getVar('page');
$pages = array(
'resellermasteragreement',
'customermasteragreement',
'resellerdomainagreement',
'customerdomainagreement',
'resellerwebserviceagreement',
'customerwebserviceagreement',
'resellerdigicertagreement',
'customerdigicertagreement',
'registraragreement',
'customerhostingproductagreement',
'resellerhostingproductagreement'
);
?>
<div class="col-lg-12">
<?php
echo in_array($page, $pages) ? $this->loadTemplate('legal') : $this->loadTemplate('home');
?>
</div>
views/legal/tmpl/default_legal.php
$page = JRequest::getVar('page');
echo nl2br(htmlspecialchars($this->legal[$page]['defaultagreement'], ENT_NOQUOTES, "UTF-8"));
?>
<a type="button" class="btn btn-primary" href="<?php echo JROUTE::_("index.php?option=com_component&view=legal"); ?>">Back</a>
EDIT 3
This works because I wasn't navigating directly to the page from a menu item. There's a top level menu, then a page a links to the agreements. I have a hidden menu to each item, but that wasn't the link I followed.
$app = JFactory::getApplication()->getMenu();
$customermaster = $app->getItems( 'link', 'index.php?option=com_component&view=legal&page=customermasteragreement', true );
JRoute::_('index.php?Itemid='.$customermaster->id);
You have one view but you're not actually set the page argument correctly when you catch a view argument, but you treat page as some king of another view. Can you please try this and check if it works:
function [componentname]ParseRoute($segments)
{
$vars = array();
switch($segments[0])
{
case 'legal':
$vars['view'] = 'legal';
$vars['page'] = $segments[1];
break;
}
return $vars;
}
Also the functions ComponentBuildRoute, ComponentParseRoute must have your components name instead of Component at the beginning.
EDIT
[componentname]BuildRoute and [componentname]ParseRoute are deprecated, you should stick the the class that extends JComponentRouterBase as you have it in your updated second example. Try this one here and see if it works:
class ComponentRouter extends JComponentRouterBase {
public function build(&$query) {
$segments = array();
$view = null;
if (isset($query['view'])) {
$segments[] = $query['view'];
$view = $query['view'];
unset($query['view']);
}
if (isset($query['page'])) {
$segments[] = $query['page'];
unset($query['page']);
}
return $segments;
}
public function parse(&$segments) {
$vars = array();
// View is always the first element of the array
$vars['view'] = array_shift($segments);
if(count($segments) > 0)
$vars['page'] = array_shift($segments);
return $vars;
}
}
EDIT 2
I have a test Joomla 3 site with a simple component named Ola.
Non SEO component URL: http://j3.dev.lytrax.net/index.php?option=com_ola&page=test_page&view=ola
URL generated by JRoute before Router class added to router.php: http://j3.dev.lytrax.net/index.php/component/ola/?page=test_page&view=ola
SEO URL returned by JRoute::_('index.php?option=com_ola&page=test_page&view=ola'); after creating router.php and used the Router class above: http://j3.dev.lytrax.net/index.php/component/ola/ola/test_page
If you visit the links, you'll see that all are working and you can even see the page, view and JRoute results of the calling component Ola.
Unless I've completely misunderstood Joomla (I've been developing with it for four five years now), there is no "sub-view" concept implemented. Trying to use the idea is what's getting you into trouble I think.
I'm astounded that the idea of using a visual debugger is so unpopular.
Get yourself something like Netbeans (there are others too), set up a local web and database server, and watch the code run. Very (well, relatively very) quickly you'll start to understand how the structure hangs together.
You may put code in your view that picks up the extra params you've set and displays or hides things accordingly, but there is no "sub-view".
I have a function in my controller. I created a lot of variables, and send them to my view via compact function one by one.
public function edit($id,$cpe_mac) {
$vcpe = VSE::vcpe($cpe_mac);
$vcpe = json_decode (json_encode($vcpe), FALSE);
$cpe = VSE::cpe($cpe_mac);
$wan = $cpe['wan'];
$acl = $cpe['acl'];
$guest = $cpe['vlan'][0];
$private = $cpe['vlan'][1];
$cpe_name = VSE::cpe_name($cpe_mac)['cpe_name'];
$p_max_up = $private['bandwidth']['max_up'];
$p_max_down = $private['bandwidth']['max_down'];
$p_ip = $private['lan']['ip_address'];
$p_netmask = $private['lan']['netmask'];
$p_max_clients = $private['lan']['dhcp_server']['max_clients'];
$p_dns = $private['lan']['dhcp_server']['dns'][0];
$p_dns2 = $private['lan']['dhcp_server']['dns'][1];
$cpe = json_decode (json_encode($cpe), FALSE);
return view('cpe.edit', compact(['vcpe','cpe_mac','cpe_name','cpe','wan','acl','private','guest',
'p_max_up','p_max_down','p_ip','p_netmask','p_max_clients','p_dns','p_dns2'
]));
}
Question
Is there a way to send all the variables to the view rather than doing it one by one ?
You could do the following...
return view('cpe.edit', get_defined_vars());
There might be some unnecessary overhead though if you are creating a lot of variables which you would not otherwise need in your view.
To simplify you can do this
// BaseController
protected $data = array();
// Controller
$this->data = array(
'variable' => $variable,
// ...
);
return View::make('example', $this->data);
But I dont think there is more simpler way or I am not aware.
You could use an array to send all the variables to the view.
i have here:
public function index()
{
$this->is_logged_in();
$this->load->model('ReportModel');
$this->load->model('ConsultantModel');
if (isset($_POST['report'])){
$reports=$this->ReportModel->search($_POST['report']);
} else {
$reports=$this->ReportModel->get_last_ten_entries();
}
$models=$this->ReportModel->getModel();
$terms=$this->ReportModel->getTerm();
$username = $this->session->userdata('username');
$data['query'] = $this->ConsultantModel->getConsultantData($username);
//i want to send data to the report list view
//$this->load->view('report/reportlist', $data);
$this->load->view('report/reportlist', array('reports'=>$reports,'terms'=>$terms,'models'=>$models));
}
i want to pass both the array and the data in a single view (report/reportlist). i know that its possible because its very a simple idea but i don't know how. even if it can't, i know you guys know some tricks. please if you know, answer this.
public function index()
{
$this->is_logged_in();
$this->load->model('ReportModel');
$this->load->model('ConsultantModel');
$data = array();
if (isset($_POST['report'])){
$data['reports'] = $this->ReportModel->search($_POST['report']);
} else {
$data['reports'] = $this->ReportModel->get_last_ten_entries();
}
$data['models'] = $this->ReportModel->getModel();
$data['terms'] = $this->ReportModel->getTerm();
$username = $this->session->userdata('username');
$data['query'] = $this->ConsultantModel->getConsultantData($username);
$this->load->view('report/reportlist', $data);
}
You can use as following in your views -
1) Reports -
i) If single value -
echo $reports;
ii) If an array
foreach($reports as $report)
{
echo $report[..];
}
Similarly for rest.
I would like to know if it's possible out of the box in CodeIgniter2 to create the urls without modifying routes.php for each controller's function like this:
backend.website.com/ecommerce/products/edit/$id
backend.website.com/ecommerce/currencies/form/$id
backend.website.com/ecommerce/customers/partners/etc/$arg1/$arg2
My controllers/ecommerce.php for function products() is something like this:
public function products($page = 0, $items = NULL, $subview = NULL)
{
if($subview != NULL){
// This function is localhost/ecommerce/products/form/$some_id
_remap($subview); // gives me an error
}else{
// Default view with pagination arguments $page and $items
// Page settings
$this->config->set_item('page_name', 'Products');
$this->config->set_item('page_subname', 'Product listing table');
// Request items
$this->data['items'] = $this->ecommerce_model->get_products(array('page' => $page, 'items' => $items));
// Creating a view
$this->data['view'] = $this->load->view('/ecommerce/products/index', $this->data, TRUE);
$this->load->view('/_templates/default/index', $this->data);
}
}
public function _remap($method)
{
if ($method == 'form')
{
$this->$method();
}
else
{
// SKIP
}
}
I found that default _remap() function could be useful, but I do not understand how to use it with my function.
Does anyone have any experience with that and could provide some little sample?
==== UPDATED ====
Is it even possible for _remap() to work with another functions such as orders(), customers(), currencies(), etc... at the same time?
You don't need to complicate things that much for something like this.
Just add another parameter to each of your methods, for example $action:
public function products($action = false, $page = 0, $items = NULL, $subview = NULL) {
switch($action) {
case 'edit':
// edit stuff here
break;
case 'something else':
// other stuff
break;
}
// etc...
}
I am having trouble retrieving and putting the user id in the url into a variable. Here is my controller that I am trying to do this with. I have read the documentation in the user guide,however I am not getting any results.
here is my url structure:
clci.dev/account/profile/220
Controller:
public function profile()
{
$this->load->helper('date');
$this->load->library('session');
$session_id = $this->session->userdata('id');
$this->load->model('account_model');
$user = $this->account_model->user();
$data['user'] = $user;
$data['session_id'] = $session_id;
//TRYING TO MAKE A VARIABLE WITHT THE $_GET VALUE
$user_get = $this->input->get($user['id']);
echo $user_get;
if($user['id'] == $session_id)
{
$data['profile_icon'] = 'edit';
}
else
{
$data['profile_icon'] = 'profile';
}
$data['main_content'] = 'account/profile';
$this->load->view('includes/templates/profile_template', $data);
}
Am I flat out doing this wrong, or are there adjustments that I need to make in my config files?
thanks in advance
In codeigniter, instead of having something.com/user.php?id=2 we use something.com/user/2 and the way to get that 2 is using this:
$this->uri->segment(3)
for more info http://ellislab.com/codeigniter/user-guide/libraries/uri.html
edit:
based on your url: clci.dev/account/profile/220 you would need $this->uri->segment(4)
You would set up your controller function as follows
public function profile($id = false)
{
// example: clci.dev/account/profile/222
// $id is now 222
}
I suppose at this point that the value for $_GET['id'] is intended to be 220 so here:
To get 220, you would have to do it this way (except the get value in question is other than 220 as shown in your url above)
Let's say you visit: clci.dev/account/profile/220. Follow the comments for more info.
public function profile()
{
$this->load->helper('url'); //Include this line
$this->load->helper('date');
$this->load->library('session');
$session_id = $this->session->userdata('id'); //Ensure that this session is valid
$this->load->model('account_model');
$user = $this->account_model->user(); //(suggestion) you want to pass the id here to filter your record
$data['user'] = $user;
$data['session_id'] = $session_id;
//TRYING TO MAKE A VARIABLE WITHT THE $_GET VALUE
$user_get = $this->uri->segment(3); //Modify this line
echo $user_get; //This should echo 220
if($user_get == $session_id) //Modify this line also
{
$data['profile_icon'] = 'edit';
}
else
{
$data['profile_icon'] = 'profile';
}
$data['main_content'] = 'account/profile';
$this->load->view('includes/templates/profile_template', $data);
}
I hope that helps your gets your started in the right track.
you can directly get like this:
public function profile($user_id = 0)
{
//So as per your url... $user_id is 220
}