Wordpress PHP - categories - php

I think my previous question was over complicated and, to be honest, was confusing me, nevermind the people trying to answer.
I currently have to pages, both with one category of posts assigned to them, however both post pages are using the same content.php and content-single.php, but i was both pages to use different iterations of these pages for cosmetic reasons.
As an example, visit http://dev.n8geeks.com/blog/ and click on the first blog post. It displays a thumbnail, which is cool and is what i want. However, now on the "videos" page as seen here; http://dev.n8geeks.com/videos/ (once there, click on the post) it also shows the thumbnail box (but no thumbnails will be attached on this posts page category).
This is why i need to user different iterations of content.php and content-single.php, but i simply don't know how. It would also be great if the "videos" page had the same formatting as the "blog" page, but again, i don't know how to achieve this.
The code i'm using for the current "videos" page is as below.
<?php get_header(); ?>
<div id="content">
<div id="main">
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php the_content(); ?>
<?php endwhile; else: endif; ?>
<?php query_posts('category_name='.get_the_title().'&post_status=publish,future');?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h1 class="entry-title"><a href="<?php the_permalink(); ?>">
<?php the_title(); ?></a></h1>
<p><?php the_content(); ?>
<?php endwhile; else: endif; ?>
</div>
</div>
<?php get_footer(); ?>
Thanks in advance, i really appreciate any help like you wouldn't believe - it's 4:33am and i'm going insane trying to find a fix for this.
Regards

Still extremely confusing, haha, but from the sounds of it you want different templates to show up based on which category the post is in when you're viewing a single post?
If so, you could try setting this as you single.php:
<?php get_header(); ?>
<?php
if ( have_posts() ) { the_post(); rewind_posts(); }
if ( in_category(1) || in_category(2) ) {
include(TEMPLATEPATH . '/single-cat1-2.php');
}
else {
include(TEMPLATEPATH . '/single-default.php');
}
?>
<?php get_footer(); ?>
(from http://wordpress.org/support/topic/alternate-single-post-template-for-specific-categories)
And create the files 'single-cat1-2.php' and 'single-default.php', just add to the if statement checking to see if the post is in a certain category (or categories) and load the correct template. You can use ID, name, and their slug as selectors for the in_category function as well, read more here.
EDIT:
Kay, well you do need to learn plugin programming to really do this. I've begun a quick plugin for you to help you out. It works, just isn't perfect. You could definitely use a different system, like tying the categories in the category menu, but I didn't feel like playing with the Settings API for that page.
So make a new directory in your plugins directory, call it PostCatTheme, make a new file in there called index.php and put this in it:
<?php
/*
* Plugin Name: Post Category Templates
*/
//Replace __FILE__ with whatever the real path is because of symbolic link
/**
* Allows declarations of which categories a single-post template is assigned to
*/
class WordpressPostCatTheme
{
private $pluginDir, $templates;
function __construct ()
{
$this->pluginDir = dirname(__FILE__);
add_action("init", array($this, "load"));
add_filter('single_template', array($this, 'get_post_template'));
}
public function WPCT_deactivate ()
{
delete_option("PostCatTheme_templates");
}
public function load ()
{
register_deactivation_hook( __FILE__, array(&$this, 'WPCT_deactivate') );
$this->templates = get_option("PostCatTheme_templates");
if ($this->templates === FALSE)
{
$this->templates = $this->get_post_templates();
update_option("PostCatTheme_templates", $this->templates);
}
}
// This function scans the template files of the active theme,
// and returns an array of [category] => {file}.php]
public function get_post_templates()
{
$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];
$post_templates = array();
$base = array(trailingslashit(get_template_directory()), trailingslashit(get_stylesheet_directory()));
foreach ((array)$templates as $template)
{
$template = WP_CONTENT_DIR . str_replace(WP_CONTENT_DIR, '', $template);
$basename = str_replace($base, '', $template);
// don't allow template files in subdirectories
if (false !== strpos($basename, '/'))
continue;
$template_data = implode('', file( $template ));
$categories = '';
if (preg_match( '|Categories (.*)$|mi', $template_data, $categories))
$categories = _cleanup_header_comment($categories[1]);
//The categories are split by a | (pipe), if there aren't any pipes, assume it's just
//one category, otherwise split at the pipe
if (empty($categories))
continue;
if (strpos($categories, "|") === FALSE)
$categories = array($categories);
else
$categories = explode("|", $categories);
foreach ($categories as $category)
{
if (!empty($category))
{
if (isset($post_templates[$category]))
throw new Exception("Error, category assigned to more than one template");
if(basename($template) != basename(__FILE__))
$post_templates[trim($category)] = $basename;
}
}
}
//file_put_contents($this->pluginDir . "/log", json_encode($post_templates));
return $post_templates;
}
// Filter the single template value, and replace it with
// the template chosen by the user, if they chose one.
function get_post_template($template)
{
global $post;
$cats = wp_get_post_categories($post->ID);
//Go through each category, until one hits
foreach ($cats as $c)
{
$templateP = $this->templates[$c];
if(!empty($templateP) && file_exists(TEMPLATEPATH . "/{$templateP}"))
{
$template = TEMPLATEPATH . "/{$templateP}";
break;
}
}
return $template;
}
}
if (!isset($PostCatThemePlugin))
$PostCatThemePlugin = new WordpressPostCatTheme;
?>
After that, in your custom single.php template, add the code Categories: 1|2 in the header section (where Template Name is). Whenever you change or add these, make sure to deactivate and reactivate the plugin, to refresh the cache that this information is stored in.
To get the ID of a category, edit a category and in the URL, the number after tag_ID= is the category's ID.
Hope that helps some,
Max

Related

Yootheme Pro - Wordpress: Get content of page before it is displayed

I'm writing a simple plugin for wordpress that changes a single word on a page or a post to make it bold.
For example: vlbs -> vlbs
It works fine for normal Wordpress pages and posts with this code:
defined('ABSPATH') or die('You can\'t enter this site');
class VLBS {
function __construct() {
}
function activate() {
flush_rewrite_rules();
}
function deactivate() {
flush_rewrite_rules();
}
function unstinstall() {
}
function new_content($content) {
return $content = str_replace('vlbs','<strong style="color:#00a500">vlbs</strong>', $content);
}
}
if(class_exists('VLBS')){
$VLBS = new VLBS();
}
add_filter('the_content', array($VLBS, 'new_content'));
//activation
register_activation_hook(__FILE__, array($VLBS, 'activate'));
//deactivation
register_deactivation_hook(__FILE__, array($VLBS, 'deactivate'));
However, it does not work on a page built with Yootheme Pro Pagebuilder. Whatever is done within the function new_content() is processed after the content has already been loaded. Thus, I cannot manipulate it before it is displayed to the user.
So the question would be: How can I get the content of a page before it is displayed? Is there an equivalent to Wordpress' 'the_content'?
Any help is really appreciated! Thank you very much in advance.
Best regards
Fabian
Yootheme: 1.22.5
Wordpress: 5.2.4
PHP: 7.3
Browser: Tested on Chrome, Firefox, Edge, Internet Explorer
In your code, do you are sure it's the good usage of add_filter content ?
In the doc, the 2nd parameter is string, not array:
add_filter( 'the_content', 'filter_the_content_in_the_main_loop' );
function filter_the_content_in_the_main_loop( $content ) {
// Check if we're inside the main loop in a single post page.
if ( is_single() && in_the_loop() && is_main_query() ) {
return $content . esc_html__("I'm filtering the content inside the main loop", "my-textdomain");
}
return $content;
}
In wordpress, the_content function display the content. There is an other function for get_the_content
Go to your page file and get the content. You can use str_replace and echo the new content after.
Example single.php :
if ( $query->have_posts() ) :
while( $query->have_posts() ) : $query->the_post();
$content = get_the_content();
$new_content = str_replace(search, replace, $content);
echo $new_content;
endwhile;
endif;
If it is not possible for you, try to use the output buffer functions. If you need use this functions, I say it and I developpe more this part. But test the solution above before.
Oh, and it exist a special community for WP where your question will more pertinent : https://wordpress.stackexchange.com/

Link title to external link instead of permalink

I'm trying to get the same effect as the plugin Pages Link To where the title of the post is linked to an external link. The reason I don't want to use the plugin is the link is generated dynamically when the post is saved, but I'm unable to update the the permalink of the post with the external link.
Below is my code in functions.php:
function savepost( $post_id ) {
if( $_POST['post_type'] == 'books' ){
$genre = strip_tags(get_field('genre'));
$author = strip_tags(get_field('author'));
$extlink = "http://www.".$genre."/".$author.".com";
update_post_meta( $post_id, 'extlink', $extlink);
$url = strip_tags(get_field('extlink',$post));
update_post_meta( $post_id, 'post_link', $url);
}
}
add_action( 'save_post', 'savepost' );
i m trying another method in which i assigned a template to the post so that when the post loads it redirects to the link but it doesn't redirect
my code
<?php
ob_start();
?>
<?php
/**
* Template Name: post Redirection Template
*/
get_header();
$redirecturl = strip_tags(get_field('extlink',$post));
wp_redirect($redirect_url);
get_sidebar();
get_footer();
?>
<?php
ob_end_flush();
?>
What you should do, is insert the external link as a custom field in the post editor, then display the custom field value in place of the_permalink(). You could use a plugin such as Advanced Custom Fields to grab the URL from the custom field.
EDIT 1: More clarification using the Advanced Custom Fields plugin as an example. The field name for this example is url.
You should use this wherever you want the custom permalink to appear throughout your site, such as in your archive.php, category.php, etc. Replace the code that looks something like this:
<?php the_title(); ?>
with this:
<?php
$value = get_field( "url" );
if( $value ) { ?>
<?php the_title(); ?>
<?php } else { ?>
<?php the_title(); ?>
<?php } ?>
EDIT 2: Clarifying additional information.
You can add a function to the header.php of your theme that checks if the url is set, then redirects to the external link that way, if your user goes directly to the permalink, it will still redirect them. In fact, you could use this code without using the above code to display the external link.
<?php
$value = get_field( "url" );
if( $value ) {
header('Location: '.$value);
die();
} else {} ?>
Warning: make sure to use this code before any HTML (or text) has been passed to the browser, or it will not work correctly.

How to add values to a Wordpress template file programmatically?

I'm new to Wordpress & PHP, so kindly excuse the naivety of the question, if any.
I'm building a plugin where I need to select values from the database and create a new HTML page with the values. I'm using a custom template file.
What I've done till now
Extracted the values from database
Load & display my own template in my plugin file
add_action( 'init', 'leb_add_endpoint' );
function leb_add_endpoint()
{
add_rewrite_endpoint( 'result', EP_PERMALINK );
}
add_action( 'template_include', 'leb_render_template' );
function leb_render_template($default_template) {
//some code removed for brevity
if ( ! is_singular() || !isset($wp_query->query_vars['result']) )
{
return $default_template;
}
$sample_result = $wpdb->get_var($wpdb->prepare($sql));
$default_template = plugin_dir_path(__FILE__) . '/my-custom-template.php';
return $default_template;
}
The content of my-custom-template.php is as follows
<?php
/* Template Name: My Template*/
echo '<h1>Testing</h1>';
?>
The page gets displayed without any problem. All I want is to insert $sample_result and other similar results pulled form database into my-custom-template.php
I need to generate dynamic pages based on values pulled from DB. So each time, the final page created might be different. E.g. if one hits www.example.com/sample-post/result, a page will be shown with values pulled from the DB. If one hits www.example.com/another-sample-post/result, a different page will be shown with different values. Both these pages will have the same design, only a few values will be different. This is what I'm trying to achieve.
How can I do that? Please help me. I'm stuck. :(
You need to define "result" in query vars.
Use EP_ROOT Endpoint Mask ( result/{var} is located in the root )
Inside template_include hook, you can find result value inside $wp_query object.
I've already tested the code
// Add a new var to query vars
function result_add_query_vars( $vars ){
$vars[] = 'result';
return $vars;
}
add_filter( 'query_vars', 'result_add_query_vars' );
// Add endpoint
function result_add_endpoint() {
add_rewrite_endpoint( 'result', EP_ROOT );
}
add_action( 'init', 'result_add_endpoint');
// change the template
function result_render_template($template)
{
global $wp_query;
if ( array_key_exists( 'result', $wp_query->query_vars ) ) {
$result = get_query_var('result');
$new_template = plugin_dir_path(__FILE__) . '/my-custom-template.php';
return $new_template;
} else {
return $template;
}
}
add_action( 'template_include', 'result_render_template' );
Now you can retrieve the query var in your custom template
/*
* Template Name: My Custom Template
*/
$result = get_query_var('result');
echo $result;
Well why don't you use $wp_query Inside your my-custom-template.php
<?php
/* Template Name: My Template*/
global $wp_query;
echo '<pre>';
print_r($wp_query); // Use this in case you want to see what else do you have with you.
echo '<pre/>';
// Now you can use $wp_query to build your dynamic query at run time.
// This will allow you to perform task at run time
?>
To Retrieve Meta
If you have saved something as a meta then
<?php
$meta_values = get_post_meta( $post_id, $key, $single );
?>
To Retrieve Child Post
If you want to retrieve child posts then
<?php
if ( have_posts() ) :
// Start the Loop.
while ( have_posts() ) : the_post();
// Do your stuff here such as below
the_title();
the_content();
endwhile;
else:
echo 'No Post Found';
endif;
?>
1) Write this function in function.php in your active template.
function leb_render_template() {
//some code removed for brevity
//$sql = 'YOUR_QUERY_CODE'
$sample_result = $wpdb->get_var($wpdb->prepare($sql));
return $my_template;
}
add_action('wp_ajax_leb_render_template', 'leb_render_template');
add_action('wp_ajax_nopriv_leb_render_template', 'leb_render_template');
2) Call function in your custom template.
<?php
/* Template Name: My Template*/
echo '<h1>Testing</h1>';
$result = leb_render_template();
print_r($result); // Print Your function output.
?>

Trying to add two different strings in PHP

I came up with an solution for not showing an sidebar in Wordpress when this is not filled with widgets. I did this by calling for the slug from the current page and named my sidebars the same as the slugs from my pages.
I use the Custom Sidebars plugin to add sidebars. This plugin adds 'cs-' in the id of a sidebar before the name of the sidebar. So for example I've named my sidebar 'Test' than the id of the sidebar will be 'cs-test'.
Now I want my php code to check if the sidebar is named the same as the slug from the page. So I called the_slug and before the slug I want to add cs-. With some help I came up with this:
<?php if ( is_active_sidebar( 'cs-'.the_slug(false) ) ) { ?>
<?php dynamic_sidebar( is_active_sidebar( 'cs-'.the_slug(false) ) ) ?>
<?php } else { ?>
<?php } ?>
But that doesn't seems to help. Any thoughts how to fix this? Thanks already!
Your are concatenating a string cs- with a function the_slug(false). This might cause the error, depending on what the function is returning.
Solution 1:
You could call and save the function beforehand and concate two vars:
<?php
$slug = the_slug(false); //Get return value
$slug = (string)$slug; //Force string conversion
$slug = 'cs-'.$slug; //Concate
if ( is_active_sidebar( $slug ) ) { ?>
<?php dynamic_sidebar( is_active_sidebar( $slug ) ) ?>
<?php } else { ?>
<?php } ?>
.
Solution 2:
If you need this type of functionality often try to add a string parameter to the the_slug() function (should be a custom function in your functions.php) and do the concatenating within the function itself:
function the_slug($boolen, $string='') {
//Your code
return $string.$your_var;
}
Your sidebar code would look like this:
<?php if ( is_active_sidebar( the_slug(false, 'cs-') ) ) { ?>
<?php dynamic_sidebar( is_active_sidebar( the_slug(false, 'cs-') ) ) ?>
<?php } else { ?>
<?php } ?>

Wordpress php: Way to test if pages are children of a parent page?

Working on my first Wordpress site so I'm sure this is a really basic question. I'm struggling to write a conditional php statement that performs a certain action when a page is a child of a parent page.
For example, rather than just specifying one page, as below, I'd like to specify all pages that have the 'About Us' page as a parent:
<?php if (is_page('About Us')) echo 'Hello World!'; ?>
I've tried the "child_of" function but it wasn't as straightforward as I'd hoped.
When I use the below, I get a syntax error - probably just me not knowing how to use the function:
<?php if (child_of('About Us')) echo 'Hello World!'; ?>
Any suggestions?
Add the following function to your functions.php theme file:
function is_tree($pid) { // $pid = The ID of the page we're looking for pages underneath
global $post; // load details about this page
$anc = get_post_ancestors( $post->ID );
foreach($anc as $ancestor) {
if(is_page() && $ancestor == $pid) {
return true;
}
}
if(is_page()&&(is_page($pid)))
return true; // we're at the page or at a sub page
else
return false; // we're elsewhere
};
Then you can use the following:
if(is_tree('2')){ // 2 being the parent page id
// Do something if the parent page of the current page has the id of two
}
Reference: http://codex.wordpress.org/Conditional_Tags
You're getting an error because there is no such thing as a child_of() function in WordPress.
child_of() is a way of searching using the get_pages() function.
$pages = get_pages('child_of=##');
where ## is the numeric ID (not the name) of the 'About us' page.
Simple solution where you want to link to the parent page from the child page; $post->post_parent holds the ID of a page's parent if there is one or it is zero if there is not one:
<?php
if($post->post_parent !== 0){
print '← Back';
}
?>
so for this case you would want to change the if() to check if $post->post_parent == $id_of_about_page.
This is the final code that worked for me - not sure if it's the proper way to do what I'm trying to do, but will post for the benefit of anyone with my same question.
I have a set of right hand columns, each specific to a section of the site (each parent page representing a section of the site).
I want the parent page and all of that parent's child pages to pull the same specific right hand column.
Here's what I did:
<?php
if (is_page('Page Name 1') || $post->post_parent == '##') {
include (TEMPLATEPATH . '/right-1.php');
} elseif (is_page('Page Name 2') || $post->post_parent == '##') {
include (TEMPLATEPATH . '/right-2.php');
} elseif (is_page('Page Name 3') || $post->post_parent == '##') {
include (TEMPLATEPATH . '/right-3.php');
} elseif (is_page('Page Name 4') || $post->post_parent == '##')
include (TEMPLATEPATH . '/right-4.php');
?>
Where the ## represents the ID # of the page.
This code solved the problem for me guys, incase any one is wondering for a alernative:
<?php
global $post;
if ($post->post_parent == 9) {
echo 'blah blah';
}; ?>
"9" is the id of the parent page.

Categories