Single Page website with CakePHP - cakephp

I'm currently working on a single-page scrollable website (5 pages displaying as a single page) using CakePHP. I have worked on each controller action and everything runs well. I have one layout for the entire app and a view for each action. My challenge is finding a way to load the view of each action without reloading the page inside the layout. Should I just put all the view content inside the layout (without echoing $content_for_layout) or could there be a better way to do it?

Considering the div you want to update has the id #content:
$.ajax({
url:"http://yourdomain.com/controller/action",
context:document.body,
dataType:"html",
data:{id:123}, // in case you need to pass some params
success:function(data){
$("#content").html(data);
}
})
The action must return the HTML you want to display inside that div. If you want to have each pags loaded in different div's, you will have to create one div for each page and call AJAX for each one.
When the page is loaded for the first time, you can just pull the data for whatever default action you defined. Then, when you want to change the content, just call AJAX.

Related

AngularJS - using Angular UI router - how to fetch the next content via AJAX without removing the current content

I'm using Angular UI router in my app. This is what I'm doing.
A main view contains a child view and a div container for "pagination"
By default, initially, a first set of contents is loaded
When a user clicks on "next page", next set of contents is loaded (with the URL also being changed to /content/2 (where 2 indicates the next page number)
All is working well, but each time the contents are loaded, it goes "blank" before it loads. So it seems like it's reloading the view (which is obvious).
What I would like to do is reload the content without having that "blank" page. How can I achieve this?
At first thought, I think you could you the same approach as infinite-scroll, which is what I'm using. So you make a GET request to the server to get new content and push it to the list on clicking 'next'. However, since the URL changes also. This will cause the controller to be reloaded. You can actually bypass this by setting reloadOnSearch to false.

Backbone.js: How to utilize router.navigate to manipulate browser history?

I am writing something like a registration process containing several steps, and I want to make it a single-page like system so after some studying Backbone.js is my choice.
Every time the user completes the current step they will click on a NEXT button I create and I use the router.navigate method to update the url, as well as loading the content of the next page and doing some fancy transition with javascript.
Result is, URL is updated which the page is not refreshed, giving a smooth user experience. However, when the user clicks on the back button of the browser, the URL gets updated to that of a previous step, but the content stays the same. My question is through what way I can capture such an event and currently load the content of the previous step and present that to the user? Or even better, can I rely on browser cache to load that previously loaded page?
EDIT: in particular, I'm trying something like mentioned in this article.
You should not use route.navigate but let the router decide which form to display based on the current route.
exemple :
a link in your current form of the registration process :
<a href="#form/2" ...
in the router definition :
routes:{
"form/:formNumber" : "gotoForm"
},
gotoForm:function(formNumber){
// the code to display the correct form for the current url based on formNumber
}
and then use Backbone.history.start() to bootstrap routing

Concrete5: Take the central part of my single page and have it displayed on the homepage

Within my Concrete5 there's a package that contains many single pages, which actually make the core functionality (community connections).
There's one particular page that contains search functionality. Is there any way to take the central part of that page and somehow display it on the homepage, in a div element or similar?
You can do this with jquery .load()
On the single page, wrap the content you want to import in a div with a unique id.
On the home page, add a div to import the content into
// Get the URL of the page
var url = "relative/path/to/page;
// Load the new page into the temp container
// Replace #wrapper with the selector of the element you want to import
$("#import-content").load(url + " #wrapper");
You should be able to do this by creating a new public function in the single_page's controller that returns whatever you want it to (data that you can then render in HTML, or you could have the controller method itself render an "element" with some data, or just create an HTML string in the controller method itself if you want to totally violate the MVC pattern).
Then you should be able to retrieve that data or markup from your other page like so:
$myController = Loader::controller('/path/to/singlepage'); //<--NOTE this is a C5 URL path (e.g. "slug"), not a server file path!
$myMarkup = $myController->myCustomFunctionIWroteToReturnSomeStuff();
echo $myMarkup;

CakePHP: How to use the same controller function to render 2 pages

I wish to have a page called "index" with a corresponding url "domain/controller/index" and another
page called "admin_index" with a corresponding url "domain/admin/controller/index".
The trick is that i want both pages to use the same view to render and the same function for the logic while on of the page's parameters are a flag indicating to the view from which url the view is rendered.
I need it because currently in my "index" page I have table with data.
The page also has a smart filter for that page which requires a respectful amount of logic in the controller side.
My problem is that currently there is an "Edit" button in each line which I don't want to share to all the users.
Currently I'm using the admin prefix to handle this kind of pages by protecting them by limiting the access from the web-server (Apache in my case).
Any ideas of how to implement this without duplicating the controller function?
Try this (I've tested it on my CakePHP 2.0.x app, but there's nothing in this code that should be 2.0 specific):
//controller
public function index($admin = false) {
$this->set(compact('admin'));
}
public function admin_index() {
$this->index(true); //calls the index function to do all that stuff
$this->render('index'); //tells it to render the 'index' view
}
When you hit the /index page, all should be as normal. When you hit the admin_index, it runs the logic from the index function, then specifies to use the index view.

CakePHP dynamic element

I am trying to create a message-board type element in a CakePHP app. This element will be displayed on all pages and views that use a particular layout. I want it to display all the messages in the model, then show the add form when a link is clicked, then return to the updated message list when submitted. All this without affecting the current view/page.
I have my message model/controller/index set up, with a message board element that requests the index action. This works fine. However I am perplexed about how to return back to the original page/action from which the link was clicked. I can't use $this->referer() because that will link back to the add() action; what I want rather is to link to the page/view before that.
Any general pointers on how to achieve something like this?
I would approach this using Ajax, and use an ajax layout.
$this->layout('ajax')
Then you would be able to setup a full stack for processing this, and pass various things in as parameters into the controller actions.
By using Ajax you will not need to worry about passing in the referrer controller / action pair. You can also use the return from this to update the list by calling out to the MessagesController. The added bonus of this is that you can just switch the layout in your actual controllers, thus not having to write any extra code at all.
In your controller, you can check for Ajax
if($this->params['requested']){
$this->layout('ajax');
return $data;
}else{
$this->set('data',$data);
}

Resources