I have a form which is starting to get a bit too complex, so I want to split one page into three different pages. I understand that I need to use URL routing to achieve this, but no luck so far. Reading the manual didn't help.
Current URL is as following:
index.php/profiles/edit/$id
I want to achieve something like this:
index.php/profiles/edit/contact/$id
index.php/profiles/edit/pictures/$id
...
You do not need to do routing. You can simply improve your edit function like this.
public function edit($type,$id)
{
if($type=='contact')
{
//do contact task
}
if($type=='pictures')
{
//do picture task
}
}
Now your expected links will work.
Related
I got a form, that send post request and show paginated results. There are problems, when i want to see pages number 2 and more, because there sended get request and controller doesn't see form to create query. Anyone know how to solve this problem?
I'm using symfony(1.4) and I dont know if there's a big difference between 2.x
so let me discuss about it...
creating url's you should use
<?php url_for('page/view?num='.$page_num) ?>
something like that, then you can now use the request of your module
#app/{apps_name}/module/page/{actions.class.php} or {pageActions.class.php}
to your view method
public function executeView(sfWebRequest $request)
{
$page_num = $request->getParameter('num');
echo $page_num;
}
you should get what the page number now.
one more thing, this only works in $_GET requests.
You should know how to use Routing, to configure atleast 3 parameters. It will help you to use $_POST requests.
I think easiest way would be to make the search a get request so that is in the url. Then the paginated links will have the search value too.
I came from Codeigniter. In CI I had this:
$route['([a-z]+)tab'] = "$1/tab";
When I go to index.php/sometab/ I'll get some/tab/ action executed. But it doesn't redirect, instead I just tell CI that when I type this address I want to use another address instead, though there is no redirect.
Basically I want to achieve next goal: when I go to /someTab/ I want to execute some#tab action.
I only found Redirect::to_action in laravel, but I dont want the URL to be changed. I tried something like:
Route::any('([a-z]+)tab', function($controllerName) {
return Redirect::to_action("{$controllerName}/tab"); // here I want to tell to use $controllerName#tab action
});
How can I get this?
http://laravel.com/api/class-Laravel.Routing.Controller.html
There are some interesting methods here to. Route::cal, Route::forward, Route::execute...
Is there a (simple) way to echo some variables from a Codeigniter controller to the browser console?
Something like
public function my_controller_method() {
if (testing_out_something) {
$result = "looks like it works";
$this->log_to_javascript_console->write($result);
}
}
I saw this javascript class but it looks like it's more for jQuery, I just want to do something simple for debugging purposes.
I guess another way would be to send it to a view, but I don't want my view to change at the moment, I just want to make sure my data is being sent.
this links may help you :
http://www.codeforest.net/debugging-php-in-browsers-javascript-console
http://sarfraznawaz.wordpress.com/2012/01/05/outputting-php-to-browser-console/
So I have a site with a dozen pages on it using Drupal as a CMS. Wanted to know how to set/append all href links on any page with a dynamic attribute?
so here is an example URL:
http://www.site.com/?q=node/4
and I wanted to append to the URL like so:
http://www.site.com/?q=node/4&attr=1234
Now I have a nav bar on the site and when I hover over the link I see the url but I need to append the &attr=1234 string to the end of it. The string is dynamic so it might change from time to time.
I was thinking jQuery would be a good choice to do this but does Drupal have any functionality as well?
Now I've seen a couple of posts on Stack:
Post 1
Post 2
Problem is I'm learning my way around Drupal and have minimal experience with jQuery but getting better with both. I see the jQuery can replace a HREF but looks like they hard coded the HREF, could jQuery find all HREF's on a page and append the string to it? Also does Drupal have this functionality and what would be the best approach?
Also need this to work for clean or standard URL format, so I think Apache would handle this I just wanted to make sure.
Thanks for any help
EDIT:
Looks like the general consensus is the Drupal should handle this type of request. Just looking for the best implementation. Simple function call would be best but I would like it to dynamically add it to all existing href's as I want this to be dynamic instead of hard coding any url/href calls. So I could add/remove pages on the fly without the need to reconfigure/recode anything.
Thanks for the great tips though
EDIT #2:
Okay maybe I'm asking the wring question. Here is what I need and why it's not working for me yet.
I need to pass a value in the url that changes some of the look and feel of the site. I need it to be passed on just about every href tag on the page but not on User logout or Admin pages.
I see in my template code where the nav links get generated, so I though I could pass my code in the attributes array as the second parm to the function, but that is setting the tag attributes and not the URL attributes.
Now I see the bottom nav links use this Drupal function: menu_navigation_links() in menu.inc but the top nav uses a custom function.
This function in the template.php script looks to be the one creating the links
function lplus($text, $path, $options = array()) {
global $language;
// Merge in defaults.
$options += array(
'attributes' => array(),
'html' => FALSE,
);
// Append active class.
if (($path == $_GET['q'] || ($path == '<front>' && drupal_is_front_page())) &&
(empty($options['language']) || $options['language']->language == $language->language)) {
if (isset($options['attributes']['class'])) {
$options['attributes']['class'] .= ' active';
}
else {
$options['attributes']['class'] = 'active';
}
}
// Remove all HTML and PHP tags from a tooltip. For best performance, we act only
// if a quick strpos() pre-check gave a suspicion (because strip_tags() is expensive).
if (isset($options['attributes']['title']) && strpos($options['attributes']['title'], '<') !== FALSE) {
$options['attributes']['title'] = strip_tags($options['attributes']['title']);
}
return '<a href="'. check_url(url($path, $options)) .'"'. drupal_attributes($options['attributes']) .'><b>'. ($options['html'] ? $text : check_plain($text)) .'</b></a>';
}
not sure how to incorporate what I need into this function.
So on the home page the ?q=node/ is missing and if I append the ampersand it throws an error.
http://www.site.com/&attr=1234 // throws error
But if I mod it to the correct format it works fine
http://www.site.com/?attr=1234
Assuming that when you mean pages, you mean the content type of pages (will work for any other content type as long as it's really content and not something in a block or view).
You can easily replace the contents of any node that is about to be viewed by running a str_replace or with a regular expression. For instance, using str_replace:
function module_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch($op) {
case "view":
$node->body = str_replace($expected_link, $desired_link);
break;
}
}
where you define desired link somewhere else. Not an optimal solution, but non-Javascript browsers (yes, they still exist!) can't get around the forced, desired URLs if you try to change it with Javascript.
I think doing it in Drupal/PHP would be cleaner. Check out Pathauto module: http://drupal.org/node/17345
There is a good discussion on a related topic here:
http://drupal.org/node/249864
This wouldn't use jquery (instead you would overwrite a function using PHP) but you could get the same result. This assumes, however, that you are working with menu links.
I think you should consider exploring PURL ( http://drupal.org/project/purl ) and some of the modules it works with e.g. spaces and context.
I don't suggest you use jQuery to do this. It's a better practice to do this server side in PHP (Drupal).
You can overwrite the links dynamically into your preprocess page function.
On your template.php file:
function *yourtheme*_preprocess_page(&$vars, $hook){
//You can do it for the region that you need
$vars['content'] = preg_replace('/<a href="(.*?)"/i', '<a href="$1&attr=1234"', $vars['content']);
}
Note:
I did not try it, its only a hint.
It will add your parameters to the outside links too.
I'm new to MVC and I'm trying to understand how MVC fits in to what I'm used to.
Let's say I have a simple static website with the pages: Home, About, Contact.
And let's say that I have one xhtml/css "template" which will be the view for the whole site. To keep it simple, in that tag I'll have a variable for the page contents.
So in the controller am I supposed to have an individual function for the content for each page????
For example:.
function home()
{
$data['content'] = "<p>some html home page content</p>";
$this->load->view('myView', $data);
}
function about()
{
$data['content'] = "<p>some html about page content</p>";
$this->load->view('myView', $data);
}
So while I know this is a super-simplified look, is the best practice to create a function for each different page?
But what if you have a site with 100 pages? Doesn't the controller get too big to manage?
But then again, if you had a single controller for each page, that also seems that it would be tough to manage?
I am beginning to understand how the MVC concept is helpful for database connection tasks as well as some CRUD as well. But I remain confused as how to think about "pages" in MVC.
Any advice is much appreciated.
What's the best practice?
You don't have to have a function for each page.
a quick example I've found is:
<?php
//This is an example of a KISSMVC controller
//It is simply a function, which will be called by an URL such as:
//http://example.com/article/show/234
//TIP: Please assign default values to all parameters
function _show($articleid=0) {
//SECTION 1: INPUTS
//Filter, sanitize and store all inputs used by this controller
$articleid=min(0,(int)$articleid); //zero or positive integer
$uid = isset($_SESSION['authuid']) ? $_SESSION['authuid'] : 0;
$someconfig = $GLOBALS['registry']['someconfig'];
//SECTION 2: LOGIC
//Call functions/objects that implement your business logic with the inputs from SECTION 1
//Data returned from your Model should not contain UI specifics (such as html code)
$loggedinuser = new User();
$loggedinuser->retrieve($uid);
$article = new Article();
$article->retrieve($articleid);
//SECTION 3: PRESENTATION
//Call the view templates with the data obtained from SECTION 2
//A change in UI should only affect code in this section
//Sometimes there is no output needed, only a header redirect is returned
if (!$loggedinuser->hasPermission('view_article')) {
$vars['body']='<p class="error">You have no permission to access this page!</p>';
View::do_dump(APP_PATH.'views/mainlayout.php',$vars);
exit;
}
$vars['article']=$article;
//article template is defined in views/layout/view_article.php
$vars['body']=View::do_fetch('layouts/view_article.php',$vars);
View::do_dump(APP_PATH.'views/mainlayout.php',$vars);
}
Taken from http://kissmvc.com/php_mvc_framework/code
Which is a PHP implementation of MVC (its seemed to me like you're working with PHP).
You might want to have a look at their implementation etc. It was just the first one I found. Hope this helps.
The controller in MVC tends to be the biggest part of your code base. So as far as worrying about it getting too big, that's to be expected.
However, when using MVC, you typically want the Model-View-Controller to be a 1 to 1 relationship. If you have an about page, you'll want a controller specifically for that view and the actions associated with what you can do on that page. The response may be to load another view, in which case another controller will respond to events to that. The model can be shared amongst the controller's, but you don't want any parts of your view to know anything about your model or it'll break MVC, the controller being the piece that functions as the glue.
If you are indeed doing something with PHP as dtroy mentioned, that'll probably help out. Unfortunately, I'm coming from experience with MVC on the iPhone. Same concept though all around.
In summary though:
If you keep the controller responsible solely for the actions that can occur on a given view, like button clicks, etc... it should help keep your controller from getting too large and unwieldy.
Edit:
I forgot to mention, in response to your concern which I didn't address. To help with, for instance, "Controller Explosion", you may not necessarily want to create a controller for each page, but one for each type of view. For example, you may have a AboutViewController and a ContentViewController, and maybe a loginViewController. The AboutView and LoginView would be pretty unique, but if you can reuse your contentView. So if someone requested something about "Widgets", your content view would simply display information about widgets that it retrieved from your model, and display it in the appropriate location defined by your view. then when the user requests something about "gears", you can reuse the same ContentViewController to display different different information in the same fashion.
Basically you'll have a Page controller for your Page model. Then each page that you create will have a url like "/Pages/1", which will get routed to the "show" action of your Page controller.
MVC certainly takes a bit of getting used to, but once you get the hang of it, you'll really like it. Also check out resources on REST design, which will really help with problems like this.
When I design websites now, I think in terms of resources (models, more or less). So for instance, you will have many pages or users or questions or recipes or... each of these things is a thing/model. I usually make a separate controller for each one and put 7 actions in that controller:
index - used to show a list of all the Pages (URL like "/Pages")
show - used to show an individual Page (URL like "/Pages/1")
new - used to show a form to create a new Page
edit - used to show an edit form for a Page
create - used to actually create the new Page from the new form
update - used to actually update the Page from the edit form
destroy - used to delete a Page
This isn't for everyone (I don't want to turn this into a REST debate), but it helps me a lot, and I think it makes sense when you're dealing with things that are clearly objects like Pages.
The controllers contain the empty functions if there are no actions on the page. You don't have to pass page content via controller.
Place all the content to 'view' component of current unit.
If you have a site with 100 pages, you would want most of your content to be stored in a database.
your URLs would be altered to look something like this:
http://yoursite.com/showpage?pageid=mvc
http://yoursite.com/showpage?pageid=home
http://yoursite.com/showpage?pageid=whatever
and your controller would look something like this:
function showpage()
{
$post = yourframework.getmodel('post').getPost($_GET['pageid']);
$data['title'] = "<p>" . $post.title . "</p>";
$data['content'] = "<p>" . $post.title . "</p>";
$this->load->view('myView', $data);
}
Not syntactically correct but you get the idea. You need to have only one function which delivers all 100 of your pages. This would work if all your pages have a similar structure.
In other words, mvc works just like vanilla php... (but hopefully looks a bit cleaner)