stubs, dynamic homepage in cakePHP - php

I'm working on a site for a client that wants to be able to update modifying their content. The brief was to allow them to edit pages, but not create or delete them. For the site I decided to work with cakePHP, as I've heard good things.
First up, a quick explanation of my setup. I've got a single table, called 'contents', in which i'm storing each page's content. The table has a pid, a varchar 'title', a varchar 'slug' and a longtext 'body'. They're all pretty self explanitory, Each page will have it's own row, and body will be a simple HTML dump.
I've got two situations that I am having trouble with. Firstly, is setting the homepage. Cake's default is the page based on home.ctp, but that is static. Currently the page I was as the homepage is at localhost/alc/contents/view/2. I understand this is something to do with the routing, but most examples out there give half the solution, when I need every detail :P
The second problems is the slugs of the pages. Each page is currently under /contents/view/id, and i'd like this to be the slug in the database instead. Each time i try to change this (i.e. modify the view link in my index), I get an error rather than the page's content.
Any help on this would be appreciated, as there are the two things I cannot seem to grasp properly. Thanks!
By the way, you can view the site at http://www.roberttilt.name/web-dev/ALC_proto/

For the first question you need to open the /app/config/routes.php and change the line which is for the home page. i.e.:
Router::connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
need to become
Router::connect('/*', array('controller' => 'contents', 'action' => 'view'));
In your controller file /app/controllers/contents_controller.php go to action view and change it to accept empty id i.e.
function view($id = null){
if($id == null){ //Load the default home page
$this->find('first', array('conditions'=>array('default'=>1)));
} else {
//load the
$this->find('first', array('conditions'=>array('OR'=>array('slug'=>$id, 'id'=>$id))));
}
.....
}
This way if the id or slug are not provided you are loading the home page. If one of them is loaded, just use it to load the contents of the desired web page.
Your links will look like:
$this->Html->link('About', array('controller'=>'contents', 'action'=>'view', $slug_var));
The link will be converted to
About
Probably you have to take a look on the Cookbook.

Related

Get full rendered Wordpress page with WPML via REST API

I've made a Laravel-Wordpress connection for a project. For this connection, I use the Worpdress REST API.
I'm able to get specific pages from Laravel with the header and footer from Wordpress via API (for a uniform look) and other pages comes completely from Wordpress. Big benefit is, that Wordpress pages can be edited with the pretty user-friendly Wordpress backend while other pages can be custom coded in Laravel.
To achieve this, I have added some new API endpoints to retrieve the rendered header / footer and a complete page:
add_action('rest_api_init', function () {
// add 'rendered_page' member with complete HTML for requested page
register_rest_field(
'page',
'content',
array(
'get_callback' => 'by_render_page_content',
'update_callback' => null,
'schema' => null,
)
);
// add new endpoint for getting header and footer
register_rest_route('eeg/v1', '/headerandfooter', array(
'methods' => 'GET,POST',
'callback' => 'get_page_header_and_footer',
));
});
The callbacks look like this: (i.e. for the complete page)
if (isset($request['language'])) {
do_action('wpml_switch_language', $request['language']);
}
$file = THEME_DIR . '/single.php';
ob_start();
include $file;
return ob_get_clean();
As you can see, I'm checking for a language parameter and set the current language of the WPML plugin with wpml_switch_language hook.
This seems to work 'a little bit'. So, for example, the language switcher shows the correct current language.
The problem is, in the main menu: All links are showing to default language. For example if currently selected language is english, the links should look like mydomain.com/en/requestedpage. But all links go to the default mydomain.com/requestedpage. Also the <html lang> parameter is set to the default language, not to the requested. And also the <link hreflang> tags from WPML are missing.
If I access the page via the Wordpress Frontend (which is hosted at a subdomain), everything is working correctly.
So I think, I have to set the requested language somewhere else or have to call some WPML 'prepare' hooks or something like that, to make this work. Maybe also the include './single.php'; is not the right way to do this.
Any hint is welcome.
I could fix it by myself.
The solution was to create a translated menu with WPML.
In Wordpress frontend, the links in the menus are localized also without an extra translated menu. But for this scenario with the REST API, a translated menu is necessary.

How do you write an HREF link to a specific controller and action in CakePHP?

I have a small application. I have written some of the code in index.ctp file and this file is working fine. Now I have added another function called add to my Controller file and also created a seperate file called add.ctp in Views folder.
My doubt is how to navigate to add.ctp file if I click a link. I want to create a menu in my main file and write a link so that when I click on that link the page must navigate to add() function.
My problem is:
How to write href in cake php?
What link do I provide? Controller or Views?
The manual would be a good place to start your CakePHP journey. Then you'd quickly notice it's very easy to link to a controller action from your views with:
echo $this->Html->link('Link text', array(
'controller' => 'controller_name',
'action' => 'add'
));
You can create hyperlink in view like this:
echo $this->link('text',
array('controller'=>'controllerName','action'=>'actionName'));
you are able to create URLs just from controllerName and it's action:
echo $this->Html->url(
array('controller' => 'controllerName','action' =>'actionName'),true);?>

Drupal node 2-page content split

My employer requires certain pages on the website have a two page feature.
What this means is that some default content show up on the node_view page as normal but the second part should show up when a link is clicked.
This will be easy if I could do this across multiple nodes but the requirement is for all the data to be stored in one node but displayed across two pages.
I hacked together the following code:
function mymodule_node_view($node, $view_mode, $langcode){
$path = current_path();
$path_alias = drupal_lookup_path('alias',$path);
$links = array( 'test' => array('title'=>'my_link', 'query'=>'', 'href'=>"{$path_alias}/nextpage") );
$node->content['my_module'] = array(
'#theme' => 'links__node__mymodule',
'#links' => $links,
'#attributes' => array('class' => array('links', 'inline')),
);
}
That creates a hyperlink called my_link across the top of my content area - which is great.
The problem starts when I click the hyperlink. Supposing I am on http://example.org/homepage and I click the hyperlink, I expect to be redirected to http://example.org/homepage/nextpage. Also, I still want to maintain the view and edit tabs of the actual node I was on. However, Drupal correctly gives me a "page not found" error.
What's interesting is if I used http://example.org/node/1 and visited http://example.org/node/1/nextpage, I don't get the issues I described above but the url is less descriptive.
To solve this problem, I am sure I have to extend hook_menu but I don't know how to account for any number of taxonomy terms leading up to the actual node title. So, I can't predict how many % I will need before the node title and then my /nextpage. However, I want /nextpage to still have the view and edit tabs of it's parent page.
This is all unexplored territory for me.
Update
I found the following function which does a great job of returning the entire node path complete with taxonomies:
$path = current_path();
$path_alias = drupal_lookup_path('alias',$path);
What I don't know is how to take advantage of this in hook_menu to dynamically create /nextpage for my nodes.
Please remember, I don't really want /nextpage to be entirely independent of the original and actual Drupal node. When on /nextpage I want to be able to have access to the view, edit etc tabs of the node.
So, /nextpage effectively is just an extension of a Drupal node page.
There is a quick way to do that. Using views module.
In the fields section choose the field you wanna view. And in the arguments add the nid.
Then add the link to the node view you already created.
The final result http://mysite/views-page/[nid]
Hope this helps... Muhammad.
I would check the node_menu() function to get some reference on how it's implemented.
Not sure on your taxonomy requirements so this might be insufficient but I'll go with what I understand.
But off the top of my head I'd go for something like:
function mymodule_menu() {
$items['node/%node/nextpage'] = array(
'title' => 'Next page',
'type' => MENU_LOCAL_TASK, // Makes it a tab on node/%node-pages
'page callback' => 'mymodule_node_page_view', // Your page display function
'page arguments' => array(1), // First will be a node object, second will be whatever value is passed in the url
// You should rip access callback and access arguments from node_menu()
);
return $items;
}
That should do something like what you are asking for.
It is also possible, easier and definitely recommended to do this with Panels/Pages (see also Chaos Tools) or arguably Views as they are quite capable of all this and generally a better way to work with Drupal's strengths than custom code.
Updated
To clarify I've simplified the menu hook and you should be able to use the below page view function. I still believe you would make a better solution using Panels and overriding node_view and such.
The MENU_LOCAL_TASK part in the menu hook should turn this into another tab along with View and Edit.
function mymodule_node_page_view($node) {
die("It works: ".$node->title);
}
Hope that's more helpful.

opencart - How to manually display a module inside a template file?

Let's say I want to display the specials module on the homepage in a position different than $content_top, $content_bottom, $column_left or $column_right. How do I do that? If you have some experience with this, could you give me some pointers?
The module will be display in home.tpl but I'm assuming I would need to edit the controller file home.php
To do this, you will need to make edits to two files
Firstly, you will need to edit the controller. In this example, I'm going to add the specials to the home page
So open the controller file catalog/controller/common/home.php. Somewhere before this line $this->response->setOutput($this->render()); add the following
$this->data['special_block'] = $module = $this->getChild('module/special', array(
'limit' => 5,
'image_width' => 80,
'image_height' => 80
));
The array is the settings for the module. Note that the layout, position, status and sort order aren't included, as they're irrelevant here. I've also used special_block as a unique key for the content, to avoid it conflicting with any other items that may need rendering
Then in your template file, you just need to use <?php echo $special_block; ?> wherever you want the module to go

ViewScript decorator unable to set

I am following the section about "Full Customization Using the ViewScript Decorator" from this page -> http://devzone.zend.com/article/3450
In the init method of my form class I have added this
$this->setDecorators(
array(
array(
'ViewScript',
array(
'script' => 'display.phtml'
)
)
)
);
Now in the place where my form appeared I have this:
An error occurred
Application error
What am I doing wrong here? I really need to customize the appearance of the form and I just want to change the form and not the appearance of the whole page.
I have tried this:
$this->setElementDecorators(array(array('ViewScript', array('viewScript'=>'display.phtml'))))
Which works but affects the display of the whole page (I am using zend layout). I just need the render of the form to be passed to the display.phtml page.
Note: Is there any place in particular I have to place the display.phtml? I placed it in the view\scripts folder.
I think it is as simple as this.
The ViewScript cannot be used in the init() method for your form for one simple reason. If you look at the example (and probably your display.phtml) there are echo statements like this one $this->form->firstname;. At this point in init() the form elements are not loaded yet!
The author therefore correctly shows this code
$form->setDecorators(array(
array('ViewScript', array('script' => 'demogForm.phtml'))
));
Note that he uses $form as the object. Either in controller or view script you load your form as an object and then add the ViewScript. So in one of your controllers you would do something like this
$form = new My_Form();
$scriptPath = '/path/to/script/display.pthml'
// or without a path if you have a script folder loaded
$form->setDecorators(array(
array('ViewScript', array('script' => $scriptPath))
));
This should do the trick.
Update Looking at the naming of your pthml I assume (and hope) this is a special template for your form and not your whole layout file. If you use your whole layout file then of course if will render the whole page!
When working with view scripts, I find it's best to make any such changes at the view level.
Ignore the "ViewScript" decorator details in your form and set them from the view, eg
<?php echo $this->form->setDecorators(array(
'PrepareElements',
array('ViewScript', array('viewScript' => '_forms/display.phtml'))
)) ?>
The location of the display.phtml file is relative to the module's view scripts folder. If this is just the default module (under the application folder), the script in my example will be located at application/views/scripts/_forms/display.phtml
If you want to remove HTML tags like <dt> or <dd> (labels and viewscript) you can use methods removeDecorator('HtmlTag') or removeDecorator('Label')

Categories