I have a CakePHP website and navigaton links are stored in database. What i want is for some navigation entries to call custom function which will return some additional, dynamic data about the link: I want to add a count of articles for link "Vacancies". I could call a function on a model that would return total count. This link is to be rendered on every page.
So i need to get appropriate models instance, but not for the current request, but the request where url points to.
So basically i have url "/en/vacancies". I can get controller name by:
$urlInfo = Router::parse("/en/vacancies");
$controllerName = $urlInfo['controller'];
What would be the reliable way to do that?
Any other solutions for the problem are welcome.
Assuming you have the method to gather the navigation link data in a Model.
App::import('Controller', $controllerName);
$controller = new $controllerName;
$controller->loadModel('YourModel');
$yourModel = $controller->YourModel;
$yourData = $yourModel->your_method();
There are a variety of other ways to do this. But, without knowing more about where you're actually going to be calling this function I can't really provide anymore suggestions.
Related
I'm trying to return search results to a new controller than where the search action was performed from. Problem is Results is never accessible from CustomSearchResultPage.ss. I've added inline comments for what I think is happening, am I right in my thinking here?
// Customise content with results
$response = $this->customise(array(
'Results' => $results ? $results->getResults() : '',
));
if ($results) {
$response = $response->customise($results);
}
// Use CustomSearchResultPage.ss template
$templates = array('CustomSearchResultPage', 'Page');
// Create a new CustomSearchResultPage page
$page = CustomSearchResultPage::get_one('CustomSearchResultPage');
// Build a controller using the CustomSearchResultPage
$controller = CustomSearchResultPage_Controller::create($page);
// Add the custom data to the newly minted controller
$result = $controller->customise($response);
// Return the controller and tell it how to render
return $result->renderWith($templates);
The page seems to render as expected just the variable is always empty...
Your explanation is a little hard to follow I'm afraid. So I'm answering for what I can ascertain as below:
Performing a search. This requires loading a controller to do as such.
Customising the current controller with the results
RE-customising the current controller with itself.
Setting the template for the current (double customised) controller.
Disregarding all of the above.
Fetching a random page (or an empty record).
Creating a controller for the empty page.
Customising the new controller with the customised controller of the current controller customised with itself.
Returning that page, which shows no results.
You need only stop at step 4 (skip step 3), and return the customisation ($response).
If there is some reason you think you need another controller however (which seems superflous, but who knows), creating and then customising that one (only) before returning it would be better.
Being that you have only used this second controller for rendering a result, the URL will not have changed or anything. The whole thing seems beyond requirements.
A much more simple way to render a result from this action would probably be:
return $this
->customise(['Results' => $results ? $results->getResults() : null])
->renderWith(['CustomSearchResultPage', 'Page']);
(from the top of my head, may need a little refining).
In a joomla custom made component there are multiple posts on a page, and every post contains multiple comment, so in view i want to call comments by post id. please suggest a good method to make it working.
You have two options. The first, is to attach the comment id as a URL paramater and retrieve it within the model as needed like so:
$comment_id = JRequest::getApplication()->input->get('comment_id');
If you wish to pass in a parameter when calling the model from the view class, you need to get an instance of the MVC path model instead of using the short cut method. So, instead of using this in the JView class:
$this->items = $this->get('Items');
You would do this instead:
$model = $this->getModel();
$this->items = $model->getItems($comment_id);
Hope this helps.
I'm writing a control panel for my image site. I have a controller called category which looks like this:
class category extends ci_controller
{
function index(){}// the default and when it called it returns all categories
function edit(){}
function delete(){}
function get_posts($id)//to get all the posts associated with submitted category name
{
}
}
What I need is when I call http://mysite/category/category_name I get all the posts without having to call the get_posts() method having to call it from the url.
I want to do it without using the .haccess file or route.
Is there a way to create a method on the fly in CodeIgniter?
function index(){
$category = $this->uri->segment(2);
if($category)
{
get_posts($category); // you need to get id in there or before.
}
// handle view stuff here
}
The way I read your request is that you want index to handle everything based on whether or not there is a category in a uri segment. You COULD do it that way but really, why would you?
It is illogical to insist on NOT using a normal feature of a framework without explaining exactly why you don't want to. If you have access to this controller, you have access to routes. So why don't you want to use them?
EDIT
$route['category/:any'] = "category/get_posts";
That WOULD send edit and delete to get_posts, but you could also just define those above the category route
$route['category/edit/:num'] = "category/edit";
$route['category/delete/:num'] = "category/delete";
$route['category/:any'] = "category/get_posts";
That would resolve for the edit and delete before the category fetch. Since you only have 2 methods that conflict then this shouldn't really be that much of a concern.
To create method on the fly yii is the best among PHP framework.Quite simple and powerful with Gii & CRUD
http://www.yiiframework.com/doc/guide/1.1/en/quickstart.first-app
But I am a big CI fan not Yii. yii is also cool though.
but Codeigniter has an alternative , web solution.
http://formigniter.org/ here.
I have a page /discussion and I want to implement pagination in it. Now, I want that for the first time the page should load as /discussion, which means that this act as if it was /discussion/page/1. For the other page the url will be /discussion/page/$pagenumber.
Now, the problem is index(). Normally, I initialize all the page data in the index() and then load the view with the initialized data. But, here I’ll have to initialize default page stuff in index() and then the pagination stuff in page(). So, is there a way of sending another set of data from page() to the view? I don’t want to load the view since it will be loaded by the index().
However, I think it is not possible to do what I mentioned above. So, maybe I should keep my index() empty and do all the initialization in the page() and then load the view there. What do you say?
You don't need both the "page" and "index" methods, just use a route.
Using an index() method and dropping the page() method:
$route['discussion/page/(:num)'] = 'discussion/index/$1';
/discussion still gives you page 1, requesting discussion/page/32 will map to discussion/index/32
This assumes you're grabbing the page number as an argument (url segment), like so:
function index ($page = 1) {}
If you are doing something else, a route is still appropriate, maybe just not the one provided.
I suggest to have a look at PEAR's awesome Pager package. It automatically generates a pager and gives you the correct indexes depending on the (GET) input variables.
It sounds like you're trying to have your page method decorate your index method. Without knowing more about the overall structure of the controller, there really isn't terribly much to say, but it sounds like the below will help:
function page( $pos )
{
$this->index( $pos );
}
// a default parameter lets you ensure that this does not neet to have a page set.
function index( $pos = 0 )
{
// when calling the DB (I'm guessing that is where the pagination really happens)
// COUNT should be defined in the config if possible.
$this->db->where/*... add more here...*/->limit( COUNT, $pos );
}
Realistically, you should look into your URI routing class or using the _resolve method, but this should do what you need it to.
I'm not quite sure what your problem is.
If you have a index() method you can set all the pagination information there, remember you have to tell the pagination library which uri segment will be using to get the page number, and that doesn't have anything to do with the index().
There is no page() method in the controller, all of the pages are the same index() with a different set of paginated data, given by the uri_segment defined as the page number, that means all the stuff that is not related to the paginated queryset are intact through the pages.
I am currently working on CMS for a client, and I am going to be using Codeigniter to build on top of, it is only a quick project so I am not looking for a robust solution.
To create pages, I am getting to save the page details and the pull the correct page, based on the slug matching the slug in the mysql table.
My question is however, for this to work, I have to pass this slug from the URL the controller then to the model, this means that I also have too have the controller in the URL which I do not want is it possible to remove the controller from the URL with routes?
so
/page/our-story
becomes
/our-story
Is this possible
I would recommend to do it this way.
Let's say that you have : controller "page" / Method "show"
$route['page/show/:any'] = "$1";
or method is index which I don't recommend, and if you have something like news, add the following.
$route['news/show/:any'] = "news/$1";
That's it.
Yes, certainly. I just recently built a Codeigniter driven CMS myself. The whole purpose of routes is to change how your urls look and function. It helps you break away from the controller/function/argument/argument paradigm and lets you choose how you want your url's to look like.
Create a pages controller in your controllers directory
Place a _remap function inside of it to catch all requests to the controller
If you are using the latest version of CI 2.0 from Bitbucket, then in your routes.php file you can put this at the bottom of the file: $routes['404_override'] = "pages"; and then all calls to controllers that don't exist will be sent to your controller and you then can check for the presence of URL chunks. You should also make pages your default controller value as well.
See my answer for a similar question here from a few months back for example code and working code that I use in my Codeigniter CMS.
Here's the code I used in a recent project to achieve this. I borrowed it from somewhere; can't remember where.
function _remap($method)
{
$param_offset = 2;
// Default to index
if ( ! method_exists($this, $method))
{
// We need one more param
$param_offset = 1;
$method = 'index';
}
// Since all we get is $method, load up everything else in the URI
$params = array_slice($this->uri->rsegment_array(), $param_offset);
// Call the determined method with all params
call_user_func_array(array($this, $method), $params);
}
Then, my index function is where you would put your page function.