G'day folks, I'm attempting to integrate Ajax Availability Calendar into a WordPress site via PHP.
I have multiple calendars set up, and need to display a different one on each property page.
The problem I'm having is that I need to be able to specify the ID e.g. $_GET["id_item"]=2 of the calendar before the <?php require_once 'pathtofile' ?> statement which is in the template.
The result I need to achieve is...
<?php $_GET["id_item"]=2; require_once 'path\to\required.file'; ?>
If I put this code in the template with the appropriate ID, it works, but I need the ID number to change on each page, otherwise I'll always be displaying the calendar with ID number 2.
I currently have custom shortcode (below) with which I can specify the ID in the page content, but I am at a loss as to how to access that ID before the statement in the template.
So what I currently have is...
In Functions.php
function ajaxcalendar_shortcode($atts) {
$args = shortcode_atts(
array(
'id_item' => 1
),
$atts
);
return '<?php $_GET["id_item"]='.$id_item.'; ?>';
}
add_shortcode('cal_display', 'ajaxcalendar_shortcode');
with the shortcode [cal_display id_item = "2"] in the content.
Is it even possible to do this or should I try another approach?
My research suggests that I may be able to use do_shortcode() to achieve this, but I haven't figured out how to use it in this situation, or I may be misinterpreting it's purpose.
I've tried putting this in the page template file:
<?php $content = the_content(); echo do_shortcode($the_content); ?>
<?php require_once 'C:\xampp\htdocs\MooreRiver\availability\ac-includes\cal.inc.php'; ?>
But it continues to display the calendar with ID 1.
Any tips would be appreciated :)
I am working on a WordPress theme. I use a plugin to display pictures on a page (for each post 1 picture), Whenever one of this pictures is clicked the following code registers this and opens a lightbox with the content of the post in it:
<?php
if($_REQUEST['popup']!=''){
$postObj = get_post( $_REQUEST['pid'] );
echo '<div class="ostContent">'.$postObj->post_content.'</div>';
exit;
?>
This all works fine.
Now the problem is that all content get displayed nicely. but for some reason shortcodes don't work. and also when I use a widget in post plugin to display a widget in the post, it doesn't get displayed.
First I tought I needed to enable shortcodes. So I changed this:
echo '<div class="ostContent">'.$postObj->post_content.'</div>';
with this:
echo '<div class="ostContent">'.do_shortcode( $postObj->post_content ).'</div>';
But still nothing. So now I have no idea what to change to make the lightbox show widgets
Hope anyone knows the solution!
EDIT: when I open the post outside the lightbox (by just going to the single page) the shortcode get used like it should be. so somehow the code above don't recognize the shortcode or...
According to a sample here: http://codex.wordpress.org/Function_Reference/do_shortcode
It looks like you need to change: echo '<div class="ostContent">'.do_shortcode( $postObj->post_content ).'</div>';
to:
echo '<div class="ostContent">'.do_shortcode([shortcode_in_brackets]).'</div>';
This should actually display the code. I am assuming that you have defined the actual text in the widget in which the shortcode applies.
Otherwise in the way you currently do it the PHP fires before the post_content even has a value.
I think I understand your problem.
The following should work, assuming the posts in question have a post_type of post:
<?php
// Check for existence of 'popup' & 'pid' query vars
if ( $_REQUEST['popup'] && $_REQUEST['pid'] ) {
// Select single post by ID (using value of the 'pid' query var)
$query = new WP_Query( array ( 'p' => $_REQUEST['pid'] ) );
// Check that the query has returned something
if ($query->have_posts()) {
/* Loop through query until we run out of posts
(should only happen once in this case!) */
while ($query->have_posts()) {
// Setup post, so we can use the_content() and stuff
the_post();
echo '<div class="ostContent">';
/* The part we've been waiting for! the_content() will
display your post content as expected */
the_content();
echo '</div>';
}
}
}
?>
WP_Query is the way to go the majority of the time when needing to retrieve posts: http://codex.wordpress.org/Class_Reference/WP_Query
Your code was retrieving and displaying data almost directly from the WordPress posts table, giving WordPress no chance to apply any of its internal actions and filters (e.g. automatic paragraphs from double line breaks, shortcode execution).
What I'm trying to do is convert my one page design in wordpress and i thought it would be nice to be able to edit, add and modify different part of the page in seperated pages. The one page website will be ordered by a menu (with id main).
Following the wp-codex i used get_template_part, it should work properly because it should:
Load a template part into a template (other than header, sidebar, footer)
get_header gets skipped but get_footer gets excecuted and the site is rendered incorrectly.
front-page.php
$pages = wp_get_nav_menu_items('main');
global $post;
foreach ($pages as $post) {
$post = get_post($post->object_id);
if($post->post_type != "page") continue;
setup_postdata( $post );
$postName = (locate_template('page-' . $post->post_name . '.php') == '') ? null : $post->post_name;
get_template_part('page', $postName);
}
wp_reset_postdata();
Is this a bug? Or did I do something wrong? What is the best way to accomplish this?
if your get_template_part() is not working, then the problem may be there is no file named as page.php in theme, check for this file.
For what it's worth, I often skip a some of the WP helpers and work more directly, but not rogue. Here is a snippet from my library :
/** Get core data for a WP post/page using ID
* #param $id : wp post/page ID
* #return array
*/
function wp_get_single_post_basic($id){
$post = get_post($id, ARRAY_A);
$ret = array();
$content = $post['post_content'];
// FILTER via WP
$content = apply_filters('the_content', $post['post_content']);
$ret['title']= $post['post_title'];;
$ret['content']= $content;
$ret['link'] = $post['post_name'];
$ret['edit_link'] = 'edit';
return $ret;
}
That function breaks down the content in a very easy to manage manner and generates the edit link (build bool for that in calling script). Also formats content.
So grab and sort the IDs you want and run this in the loop over IDs for your one page. Then all of the content will be isolated by page/post/whatever (custom taxonomy FTW).
If you had the IDs ready and sorted plus the html/css ready to go I could drop this function in and work your one page to complete in under an hour. For production line work this type of helper is great -- also perfect for sites where you want a specific post/page to be placed in some weird way in some weird place outside of the loop.
If you have a problem w/script let me know, I have not used it in a few months, wrote it a few years ago...
I think you have a problem using the global $post and storing also the $post variable in the foreach loop from the menu objects. I think probably that's the cause of the error with the template part calling.
I would recommend you to remove the global $post declaration, the reset_postdata and also the setup_postdata since you aren't using the global in your loop, you're just naming it.
You're getting the $post object from the menu so it appears that you don't need the global or the other functions that are mostly used when you want to use "Loop Style" template tags without a post_id, like the_permalink() or the_title().
I ended up copying the default page.php template as page-page.php and loaded it like this:
$postName = (locate_template('page-' . $post->post_name . '.php') == '') ? 'page' : $post->post_name;
Then in page.php just loaded page-page.php
First question here, though reading and searching has saved my bacon a number of times.
I'm a PHP hack at best, and a Wordpress theme I'm building is forcing me to learn a lot.
I've run into a problem in trying to get the next & previous links' formats to display differently based on their respective categories (and not the single.php's page).
Here's my best try so far:
<?php next_post_link(
'%link',
if ( in_category( 'tweet' ) ) {
get_the_content()
} else {
echo '%title'
};,
FALSE
)?>
This results in a syntax error.
My first question is can I even use an if-else statement within a function's parameters?
If I'm approaching it in completely the wrong way, then it's back to the drawing board. I'd appreciate any alternate suggestions, then, as well!
I know the following work:
next_post_link( '%link', get_the_title(), FALSE );
next_post_link( '%link', '%title', FALSE );
To try and be more clear, I'm looking to affect output of the next/previous links based on the category of the links themselves, and not the present host page they are on.
The problem I'm having is a) how to determine what category the next_post_link() and previous_post_link() are, and then b) display their Link parameter accordingly. If I may throw up the white flag, the examples I've found using get_adjacent_post() and various arrays and the like seem way over my head at this point. I'd really appreciate someone walking me through any solutions using them.
What to aim for?
I think you're mixing stuff a bit too much which makes your problem more complicated than it needs to be. I know with many new things, this can happen quite easily, so I think it's worth to spend some thoughts about the what to be done before starting to code. It should help in the end.
Start to formulate what you want to achieve. If I understand you right you write that you want to display the next and prev links below the current post differently based on category.
But which category? The one of the current post that displays? Or the category of the prev/next linked post?
Next to that, posts can have multiple categories. Do you want to change the display based on one or on multiple of or even all of the categories?
And finally: Do you want to output tons of HTML tags for the visual styling? Or do you want to use CSS for that.
How to do it?
After you have thought about what you actually want to achieve, you can make your mind how this can be done.
In the following I'll show some example code that will do the following:
Explains the use of the link-format parameter you want to change.
Shows how to get the CSS-classes for the links in question.
Extends a theme's output with these CSS-classes.
Make it re-useable for different files within your theme.
So this example covers the categories of the linked posts for visual styling via your Theme's CSS which I think is the preferable way.
The PHP code
PHP is pretty flexible so it's in the end easy to get that done, but without knowing what exactly to do, this flexibility in PHP can turn out to be a problem because it's also possible to loose the trail and then code something non-working.
Let's just say you just want to change the link-format for the next_post_link() function.
The function will replace %link with the HTML link tag (<a href=...>Post Title</a>), so if you take 'This is the next post of my blog: %link; waiting to be read!' as parameter, you've added some text around the link.
<?php
$format = 'This is the next post of my blog: %link; waiting to be read!';
next_post_link($format);
?>
You can additionally add HTML tags around it as well:
<?php
$format = '<span style="font-size:2em">%link</span>';
next_post_link($format);
?>
Which will make all next post links having a double of their standard font-size.
So now to make this a bit more easy for themeing, best would be to add css classes of the category/ies then you can change the display easily within the CSS.
<?php
$inSameCategory = true; // depends on what you want, can be false as well
$nextPost = get_adjacent_post($inSameCategory, '', false);
$cssClasses = get_post_class('next-post-link ', $nextPost);
$format = sprintf('<span class="$s>%link</span>', $cssClasses);
next_post_link($format);
?>
This will wrap the next post link into a <span> containing all CSS-classes of the linked post plus a next-post-link class in case you need this for the CSS-selector to style the links. Here some example CSS:
.next-post-link.category-tweet {font-size: 2em;}
Making it reuseable
As you have a next and prev link you could copy over that code only for changing one parameter. But we're lazy and instead we wrap it into a function of it's own:
/**
* my theme's format string for prev|next_post_link()
*
* #param bool $previous (optional) previous (true, default) or next (false) post
* #param bool $inSameCategory (optional) use same category, default: true
* #return string
*/
function my_prev_next_link_format($previous = true, $inSameCategory = true) {
$postId = get_adjacent_post($inSameCategory, '', $previous);
$cssClasses = get_post_class('next-post-link ', $nextPost);
$format = sprintf('<span class="$s>%link</span>', $cssClasses);
return $format;
}
Place this function into your theme's functions.php. It's available then in all your templates. Using it becomes now very easy:
<?php prev_post_link(my_prev_next_link_format()); ?>
...
<?php next_post_link(my_prev_next_link_format(false)); ?>
If you've put this all together, you can easily style the next and prev links within your theme's CSS.
Have you tried anonymous functions? In that way you can use if-else statements within a function
Try:
$format_string = in_category('tweet') ?
'<span style="color:red;">%link</span>' : '%link';
next_post_link($format_string);
The second and third parameters are optional and default to title and false.
Edit:
I don't know this plugin, but..
if(in_category('tweet')){
$format_string = '<span style="color:red;">%link</span>';
$link_text = get_the_content();
}else{
$format_string = '%link';
$link_text = '%title';
}
next_post_link($format_string, $link_text);
I would like to display a Drupal view without the page template that normally surrounds it - I want just the plain HTML content of the view's nodes.
This view would be included in another, non-Drupal site.
I expect to have to do this with a number of views, so a solution that lets me set these up rapidly and easily would be the best - I'd prefer not to have to create a .tpl.php file every time I need to include a view somewhere.
I was looking for a way to pull node data via ajax and came up with the following solution for Drupal 6. After implementing the changes below, if you add ajax=1 in the URL (e.g. mysite.com/node/1?ajax=1), you'll get just the content and no page layout.
in the template.php file for your theme:
function phptemplate_preprocess_page(&$vars) {
if ( isset($_GET['ajax']) && $_GET['ajax'] == 1 ) {
$vars['template_file'] = 'page-ajax';
}
}
then create page-ajax.tpl.php in your theme directory with this content:
<?php print $content; ?>
Based on the answer of Ufonion Labs I was able to completely remove all the HTML output around the page content in Drupal 7 by implementing both hook_preprocess_page and hook_preprocess_html in my themes template.php, like this:
function MY_THEME_preprocess_page(&$variables) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'page__embed';
}
}
function MY_THEME_preprocess_html(&$variables) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'html__embed';
}
}
Then I added two templates to my theme: html--embed.tpl.php:
<?php print $page; ?>
and page--embed.tpl.php:
<?php print render($page['content']); ?>
Now when I open a node page, such as http://example.com/node/3, I see the complete page as usual, but when I add the response_type parameter, such as http://example.com/node/3?response_type=embed, I only get the <div> with the page contents so it can be embedded in another page.
I know this question has already been answered, but I wanted to add my own solution which uses elements of Philadelphia Web Design's (PWD) answer and uses hook_theme_registry_alter, as suggested by Owen. Using this solution, you can load the template directly from a custom module.
First, I added raw.tpl.php to a newly created 'templates' folder inside my module. The contents of raw.tpl.php are identical to PWD's page-ajax.tpl.php:
<?php print $content; ?>
Next, I implemented hook_preprocess_page in my module in the same fashion as PWD (except that I modified the $_GET parameter and updated the template file reference:
function MY_MODULE_NAME_preprocess_page(&$vars) {
if ( isset($_GET['raw']) && $_GET['raw'] == 1 ) {
$vars['template_file'] = 'raw';
}
}
Finally, I implemented hook_theme_registry_alter to add my module's 'templates' directory to the theme registry (based on http://drupal.org/node/1105922#comment-4265700):
function MY_MODULE_NAME_theme_registry_alter(&$theme_registry) {
$modulepath = drupal_get_path('module','MY_MODULE_NAME');
array_unshift($theme_registry['page']['theme paths'], $modulepath.'/templates');
}
Now, when I add ?raw=1 to the view's URL path, it will use the specified template inside my module.
For others who may hit this page, if you're just working with standard callbacks (not necessarily views), this is easy. In your callback function, instead of returning the code to render within the page, use the 'print' function.
For example:
function mymodule_do_ajax($node)
{
$rval = <<<RVAL
<table>
<th>
<td>Data</td>
<td>Data</td>
<td>Data</td>
</th>
<tr>
<td>Cool</td>
<td>Cool</td>
<td>Cool</td>
</tr>
</table>
RVAL;
//return $rval; Nope! Will render via the templating engine.
print $rval; //Much better. No wrapper.
}
Cheers!
Another way to do it which I find very handy is to add a menu item with a page callback function that doesn't return a string:
Example:
/**
* Implementation of hook_menu.
*/
function test_menu(){
$items['test'] = array (
/* [...] */
'page callback' => 'test_callback',
/* [...] */
);
return $items;
}
function test_callback() {
// echo or print whatever you want
// embed views if you want
// DO NOT RETURN A STRING
return TRUE;
}
-- Update
It would be much better to use exit(); instead of return TRUE; (see comment).
Hey, here's yet another way of doing it:
1) Download and install Views Bonus Pack (http://drupal.org/project/views_bonus)
2) Create a Views display "Feed" and use style "XML" (or something you think fits your needs better).
3) If you're not satisfied with the standard XML output, you can change it by adjusting the template for the view. Check the "theme" settings to get suggestions for alternative template names for this specific view (so you'll still have the default XML output left for future use).
Good luck!
//Johan Falk, NodeOne, Sweden
Based on answer of Philadelphia Web Design (thanks) and some googling (http://drupal.org/node/957250) here is what worked for me in Drupal 7 to get chosen pages displayed without the template:
function pixture_reloaded_preprocess_page(&$vars)
{
if ( isset($_GET['vlozeno']) && $_GET['vlozeno'] == 1 ) {
$vars['theme_hook_suggestions'][] = 'page__vlozeno';
}
}
instead of phptemplate, in D7 there has to be the name_of_your_theme in the name of the function. Also, I had to put two underscores __ in the php variable with the file name, but the actual template file name needs two dashes --
content of page--vlozeno.tpl.php :
<?php print render($page['content']); ?>
The output, however, still has got a lot of wrapping and theme's CSS references. Not sure how to output totally unthemed data...
Assuming you're in Drupal 6, the easiest way to do this is to put a phptemplate_views_view_unformatted_VIEWNAME call in template.php (assumes your view is unformatted - if it's something else, a list say, use the appropriate theme function). Theme the view results in this theme call then, instead of returning the results as you normally would, print them and return NULL. This will output the HTML directly.
PS - make sure to clear your cache (at /admin/settings/performance) to see this work.
there are probably a number of ways around this, however, the "easiest" may be just setting your own custom theme, and having the page.tpl.php just be empty, or some random divs
// page.tpl.php
<div id="page"><?php print $content ?></div>
this method would basically just allow node.tpl.php to show (or any of drupal's form views, etc...) and would be an easy way to avoid modifying core, or having to alter the theme registry to avoid displaying page.tpl.php in the first place.
edit: see comments
ok i played around with views a bit, it looks like it takes over and constructs it's own "node.tpl.php" (in a sense) for display within "page.tpl.php". on first glance, my gut feeling would be to hook into theme_registry_alter().
when you're looking at a views page, you have access to piles of information here, as well as the page.tpl.php paths/files. as such i would do something like:
function modulejustforalteration_theme_registry_alter(&$variables) {
if (isset($variables['views_ui_list_views']) ) {
// not sure if that's the best index to test for "views" but i imagine it'll work
// as well as others
$variables['page']['template'] = 'override_page';
}
}
this should allow you to use a "override_page.tpl.php" template in your current theme in which you can remove anything you want (as my first answer above).
a few things:
as i said, not sure if views_ui_list_views is always available to check against, but it sounds like it should be set if we're looking at a view
you can alter the theme paths of the page array if you prefer (to change the location of where drupal will look for page.tpl.php, instead of renaming it altogether)
there doesn't appear to be any identifiers for this specific view, so this method might be an "all views will be stripped" approach. if you need to strip the page.tpl.php for a specific view only, perhaps hooking into template_preprocess_page() might be a better idea.
I like the Drupal module. BUt, here's another way.
copy page.tpl.php in your theme folder to a new file called page-VIEWNAME.tpl.php, where VIEWNAME is the machine-readible name of the view.
Then edit page-VIEWNAME.tpl.php to suit.
There is also http://drupal.org/project/pagearray which is a general solution...
Also, #Scott Evernden's solution is a cross site scripting (XSS) security hole. Don't do that. Read the documentation on drupal.org about how to Handle Text in a Secure Fashion http://drupal.org/node/28984
A simple way to display content of a special content-type you wish to display without all the stuff of the page.tpl.php:
Add the following snippet to your template.php file:
function mytheme_preprocess_page(&$vars) {
if ($vars['node'] && arg(2) != 'edit') {
$vars['template_files'][] = 'page-nodetype-'. $vars['node']->type;
}
}
Add a page-nodetype-examplecontenttype.tpl.php to your theme, like your page.tpl.php but without the stuff you don't want to display and with print $content in the body.
If I understand your question, you want to have nodes which contain all the HTML for a page, from DOCTYPE to </HTML>. What I would do is create a content type for those nodes -- "fullhtml" as its machine-readable name -- and then create a node template for it called node-fullhtml.tpl.php. You can't just dump the node's contents, as they've been HTML-sanitized. node.fullhtml.tpl.php would literally be just this:
echo htmlspecialchars_decode($content);
Then you'll need a way to override the standard page.tpl.php. I think what you could do is at the top of your page.tpl.php check the $node's content type, and bail out if it's fullhtml. Or, set a global variable in node-fullhtml.tpl.php that page.tpl.php would check for.
I'm no Drupal expert, but that's how I'd do it. I'm talking off the cuff, so watch for devils in the details.
I see you have already gone and made yourself a module, so this may no longer help, but it is fairly easy to get a view to expose an rss feed, which might be an easier way of getting at the content, especially if you want to include it on a different site.
On D7 you can use menu_execute_active_handler
$build = menu_execute_active_handler('user', FALSE);
return render($build);
jeroen's answer was what did for me after playing with it. I have a Drupal 7 site.
First of all make sure you replace MY_THEME with your theme name. Yes it is obvious but most newbies miss this.
I actually already had a function MY_THEME_preprocess_page(&$variables) {. Do not recreate the function then but add this code at the end of the function before you close it with }.
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
$variables['theme_hook_suggestions'][] = 'page__embed';
}
My function used $vars not $variables, so I had to update that as well. Again obvious if you think look for it.
My first answered allowed me to only display the node when I called it up in a web browser. However the ultimate goal of this is to embed the drupal node in an 3rd party site using iframe.
Since the release of Drupal Core 7.50 iframe is by default blocked to prevent Clickjacking
To get only the node to successfully embed in a 3rd party site you also need to override the x-frame default setting. Everything started working after I added the following in template.php
function MY_THEME_page_alter($page) {
if (isset($_GET['response_type']) && $_GET['response_type'] == 'embed') {
header_remove('X-Frame-Options');
}
}