I am trying to create a Wordpress dashboard metabox which lists the 5 most recent pages created by the currently logged in user. Each page would be listed as a link to the individual page. Any help in doing this would be much appreciated.
The code I've created lists posts but not pages.
Here is an example:
add_action('wp_dashboard_setup', 'recent_pages');
function recent_pages() {
global $wp_meta_boxes;
wp_add_dashboard_widget('My Recent Pages', 'My Recent Pages', 'my_recent_pages');
}
function my_recent_pages() {
if ( is_user_logged_in() ):
global $current_user;
wp_get_current_user();
$author_query = array('posts_per_page' => '5,','author' => $current_user->ID);
$author_pages = new WP_Query($author_query);
while($author_pages->have_posts()) : $author_pages->the_post();
?>
<p><?php the_title(); ?></p>
<?php
endwhile;
else :
echo "not logged in";
endif;
}
Related
So I have a Custom WordPress Theme I am developing and upon installation of it in a new WordPress setup I would like a MENU auto-generated along with 3 pages, i.e:
Products
Policy
Services
that is my theme will heavily depend on.
I will already have 3 template pages made for these in the custom theme files, i.e:
page-products.php
page-policy.php
page-services.php
So when the theme is installed these are auto-created so it's a no brainer for the client.
I know Twig but very little PHP and if some could write this up so I could just drop it into my functions.php file.
I would be very, very grateful and many thanks!!
EDIT
Additional questions
Also I will be having a Home and a News page auto created as well. Would there be a quick code to auto set these up as the default Homepage and default Posts page? Or is it more complicated than that?
You could use after_switch_theme action hook and wp_insert_post function to achieve what you're looking for.
after_switch_themeDocs
wp_insert_postDocs
So to generate these three pages, first, we create a function that incorporates wp_insert_post function. Our custom function will take two arguments and first checks whether the page you're trying to create exists or not. If the page exists it will return false, otherwise, it'll create the page and return the id of that page.
The following code goes to the functions.php file of your active theme.
function your_theme_create_page($page_title, $page_content)
{
$page_obj = get_page_by_title($page_title, 'OBJECT', 'page');
if ($page_obj) {
return false;
exit();
}
$page_args = array(
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => ucwords($page_title),
'post_name' => strtolower(trim($page_title)),
'post_content' => $page_content,
);
$page_id = wp_insert_post($page_args);
return $page_id;
}
Now, on after_switch_theme action hook we run another custom function. This time we will create an associative array to hold our page titles as well as page contents. Then we feed that array to the function we created above using a foreach loop.
The following code also goes to the functions.php of your active theme.
add_action('after_switch_theme', 'my_custom_pages_on_theme_activation');
function my_custom_pages_on_theme_activation()
{
$pages_array = array(
'products page' => '<h3>Hello from products page</h3>',
'policy page' => '<h3>Hello from policy page</h3>',
'services page' => '<h3>Hello from services page</h3>'
);
foreach ($pages_array as $page_title => $page_content) {
$current_page = your_theme_create_page($page_title, $page_content);
if (false != $current_page) {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-success is-dismissible">
<p><?php echo "Done! {$page_title} has been created"; ?></p>
</div>
<?php
});
} else {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-warning is-dismissible">
<p><?php echo "{$page_title} was not created! Check whether it already exists"; ?></p>
</div>
<?php
});
}
}
}
Note that i used admin_notices action hook to give the user a visual message.
if generating those pages was successful, then user sees the following messages:
If, on the other hand, those pages were not generated or they already exist, then the user will see the following messages:
Now we have our pages created, you could see them on the pages menu on the admin screen:
And here's the page content for example:
Now, you could take this one step further and create more complex templates and feed them to that assortative array.
So for example, you have page-products.php, page-policy.php and page-services.php files inside a folder called, let's say, inc. So your folder structure would be something like this:
Your-theme-folder
|
|css-folder
| |
| some-css.css
|
|javascript-folder
| |
| some-js.js
|
|inc-folder
|
page-products.php
page-policy.php
page-services.php
Then your associative array would be something like this:
add_action('after_switch_theme', 'my_custom_pages_on_theme_activation');
function my_custom_pages_on_theme_activation()
{
$products_page_title = 'products page';
$policy_page_title = 'policy page';
$services_page_title = 'services page';
$products_page_content = file_get_contents(__DIR__ . '\inc\page-products.php');
$policy_page_content = file_get_contents(__DIR__ . '\inc\page-policy.php');
$services_page_content = file_get_contents(__DIR__ . '\inc\page-services.php');
$pages_array = array(
$products_page_title => $products_page_content,
$policy_page_title => $policy_page_content,
$services_page_title => $services_page_content
);
foreach ($pages_array as $page_title => $page_content) {
$current_page = your_theme_create_page($page_title, $page_content);
if (false != $current_page) {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-success is-dismissible">
<p><?php echo "Done! {$page_title} has been created"; ?></p>
</div>
<?php
});
} else {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-warning is-dismissible">
<p><?php echo "{$page_title} was not created! Check whether it already exists"; ?></p>
</div>
<?php
});
}
}
}
Let me know if you have any question.
Answer to the additional questions
Yes it's feasible to do so. Wordpress keeps track of the blog posts page under page_for_posts option. It also store the info for front page under page_on_front and show_on_front options. So to assign your pages to the blog and front pages, you'll update those options.
So when the custom function fires off in the after_switch_theme action hook, after the foreach loop you could add the following code to assign your pages:
$blog_page = get_page_by_title('news', 'OBJECT', 'page');
if ($blog_page) {
update_option('page_for_posts', $blog_page->ID);
}
$front_home_page = get_page_by_title('home', 'OBJECT', 'page');
if ($front_home_page) {
update_option('page_on_front', $front_home_page->ID);
update_option('show_on_front', 'page');
}
get_page_by_titleDocs
So the entire custom function for the after_switch_theme action hook would be something like this:
add_action('after_switch_theme', 'my_custom_pages_on_theme_activation');
function my_custom_pages_on_theme_activation()
{
$pages_array = array(
'products page' => '',
'policy page' => '',
'services page' => ''
);
foreach ($pages_array as $page_title => $page_content) {
$current_page = your_theme_create_page($page_title, $page_content);
if (false != $current_page) {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-success is-dismissible">
<p><?php echo "Done! {$page_title} has been created"; ?></p>
</div>
<?php
});
} else {
add_action('admin_notices', function () use ($page_title) {
?>
<div class="notice notice-warning is-dismissible">
<p><?php echo "{$page_title} was not created! Check whether it already exists"; ?></p>
</div>
<?php
});
}
}
$blog_page = get_page_by_title('news', 'OBJECT', 'page');
if ($blog_page) {
update_option('page_for_posts', $blog_page->ID);
}
$front_home_page = get_page_by_title('home', 'OBJECT', 'page');
if ($front_home_page) {
update_option('page_on_front', $front_home_page->ID);
update_option('show_on_front', 'page');
}
}
I wanted to know how to get the information of a widget instance, to be able to get all its information from another widget. Try the Get Widget ID plugin but it returns "temp" as a result and I also tried with this code block:
https://wordpress.stackexchange.com/questions/240327/how-to-access-widget-data-from-outside-widget
But I still get the same result.
My idea is the following:
I am modifying a Wordpress widget so that it selects a static post in order to fulfill the function of a featured post in a digital newspaper ... The widget has already been modified and is already working. That same widget is repeated in several places on my website, that is, I use it several times (each with a different selected post).
My idea is to show the featured posts with that widget (those selected by the editor) and modify another widget, that shows me all the posts except the ones that are selected in those widgets. For that I want to know how to get the instance of said widgets that select the featured post, to be able to get the ID of the selected post in each widget and show all the posts except those that are already as featured posts.
In summary ... I just want to see no news that is selected as featured again.
Clarification: This is not a widget written by me, it is a template that I bought and since it did not have this functionality, I am trying to create it.
I leave the code of my widget, in case it is of any use:
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
add_action('widgets_init', 'seleccion_subtitulo');
function seleccion_subtitulo() {
register_widget('seleccion_subtitulo');
}
class seleccion_subtitulo extends WP_Widget {
/*-----------------------------------------------------------------------------------*/
/* Widget Setup
/*-----------------------------------------------------------------------------------*/
public function __construct() {
$widget_ops = array(
'classname' => 'seleccion_subtitulo',
'description' => esc_html__('Seleccionar noticia con titulo y subtitulo', 'disto')
);
parent::__construct('seleccion_subtitulo', esc_html__('Noticias: Noticia titulo + subtitulo [Estilo 1]', 'disto'), $widget_ops);
}
/*-----------------------------------------------------------------------------------*/
/* Display Widget
/*-----------------------------------------------------------------------------------*/
function widget($args, $instance) {
extract($args);
$featured_post = isset($instance["featured_post"]) ? $instance["featured_post"] : '';
$posts = null;
$args = array(
'p' => $featured_post,
'posts_per_page' => 1,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'ignore_sticky_posts' => true
);
$posts_query = new WP_Query;
$posts = $posts_query->query($args);
$unique_block_id = rand(10000, 900000);
echo '<div class="jl_large_builder jl_nonav_margin jelly_homepage_builder jl-post-block-'.esc_html($unique_block_id).'">';
if (!empty($instance['titles'])) {?>
<div class="homepage_builder_title">
<h2 class="builder_title_home_page">
<?php echo esc_attr($instance["titles"]);?>
</h2>
</div>
<?php }?>
<?php
while ($posts_query->have_posts()) {
$post_id = get_the_ID();
$posts_query->the_post();
$categories = get_the_category(get_the_ID());
?>
<div class="jl_post_title_top jl_large_format">
<h3 class="image-post-title"><a href="<?php the_permalink(); ?>">
<?php the_title()?></a></h3>
</div>
<div class="post-entry-content">
<div class="post-entry-content-wrapper">
<div class="large_post_content">
<p>
<?php echo wp_trim_words( get_the_content(), 34, '...' );?>
</p>
<!-- <div class="jl_large_sw">
<?php echo esc_html__('Read More', 'disto')?>
<?php if(function_exists('disto_share_footer_link')){echo disto_share_footer_link(get_the_ID());}?>
</div> -->
</div>
</div>
</div>
<div class="box jl_grid_layout1 blog_large_post_style">
<?php if ( has_post_thumbnail()) {?>
<div class="jl_front_l_w">
<?php $slider_large_thumb_id = get_post_thumbnail_id();
$slider_large_image_header = wp_get_attachment_image_src( $slider_large_thumb_id, 'disto_slider_grid_large', true ); ?>
<?php if($slider_large_thumb_id){?>
<span class="image_grid_header_absolute" style="background-image: url('<?php echo esc_url($slider_large_image_header[0]); ?>')"></span>
<?php }else{?>
<span class="image_grid_header_absolute"></span>
<?php }?>
<?php if(get_theme_mod('disable_post_category') !=1){
$categories = get_the_category(get_the_ID());
if ($categories) {
echo '<span class="meta-category-small">';
foreach( $categories as $tag) {
$tag_link = get_category_link($tag->term_id);
$title_bg_Color = get_term_meta($tag->term_id, "category_color_options", true);
$title_reactions = get_term_meta($tag->term_id, "disto_cat_reactions", true);
if($title_reactions){}else{echo '<a class="post-category-color-text" style="background:'.$title_bg_Color.'" href="'.esc_url($tag_link).'">'.$tag->name.'</a>';}
}echo "</span>";}}?>
<?php echo disto_post_type();?>
</div>
<?php }?>
<div class="jl_post_title_top jl_large_format">
<?php echo disto_single_post_meta(get_the_ID()); ?>
</div>
</div>
<?php }
if($post_loadmore == 1){echo '<div class="jl-loadmore-btn-w">'.esc_html__('Load more', 'disto').'</div>';
wp_add_inline_script( 'disto-custom', "(function($){ $(document).ready(function() {'use strict'; var current_page_".esc_js($unique_block_id)." = 1; $('.jl-post-block-".esc_js($unique_block_id)." .jl_btn_load').click(function(e){ e.preventDefault(); e.stopPropagation(); var button = $(this), data = {'action': 'jl_post_more','query': ".json_encode( $posts_query->query_vars , true).",'page' : current_page_".esc_js($unique_block_id).",'cat' : '".esc_js($cats)."','jl_layout' : 'postslarge'}; var button_default_text = button.text(); $.ajax({ url : '".esc_url(site_url())."/wp-admin/admin-ajax.php', data : data, type : 'POST', beforeSend : function ( xhr ) {button.text('');button.addClass('btn-loading'); }, success : function( data ){ if( data ) { button.text( button_default_text ); button.removeClass('btn-loading'); $('.jl-post-block-".esc_js($unique_block_id)." .jl-loadmore-btn-w').before(data); current_page_".esc_js($unique_block_id)."++; if ( current_page_".esc_js($unique_block_id)." == ".esc_js($posts_query->max_num_pages)." ) button.remove(); }else {button.remove();}}});});});})(jQuery);");
}
wp_reset_postdata();
?>
</div>
<?php }
/*-----------------------------------------------------------------------------------*/
/* Update Widget
/*-----------------------------------------------------------------------------------*/
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['featured_post'] = $new_instance['featured_post'];
return $instance;
}
/*-----------------------------------------------------------------------------------*/
/* Widget Settings (Displays the widget settings controls on the widget panel)
/*-----------------------------------------------------------------------------------*/
function form( $instance ) {?>
<h2>Elige una de las ultimas 20 noticias para establecerla como portada secundaria.</h2>
<div class="container">
<p>
<label>
<strong> <?php esc_html_e('Seleccionar noticia destacada:', 'disto');?></strong>
</label>
</p>
<p>
<select id="<?php echo esc_attr( $this->get_field_id( 'featured_post' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'featured_post' ) ); ?>">
<?php
$posts_args = array('posts_per_page' => 20,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'post',
'post_status' => 'publish',
'ignore_sticky_posts' => true);
$last_entries = get_posts($posts_args);
foreach ($last_entries as $entry) {
?>
<option value="<?php echo $entry->ID; ?>" <?php if($instance['featured_post']==$entry->ID){ echo 'selected="selected"'; } ?> ><?php echo $entry->post_title; ?></option>
<?php
}
?>
</select>
</p>
</div>
<?php
}
}
?>
If I do var_dump ($instance) it shows me the following:
array(3) { ["featured_post"]=> string(4) "2970" ["so_sidebar_emulator_id"]=> string(29) "seleccion_subtitulo-421210000" ["option_name"]=> string(26) "widget_seleccion_subtitulo" }
I estimate that the following value tells me the ID of my widget instance:
["so_sidebar_emulator_id"] => string (29) "seleccion_subtitulo-421210000"
but I don't know how to invoke it from another widget, to get the information from it.
When obtaining that information, I try the following code to see what I get (I saw this code in the link that happens first):
$widget_name = 'seleccion_subtitulo';
$widget_instance = '421210000';
$widget_instances = get_option('widget_' . $widget_name);
$data = $widget_instances[$widget_instance];
var_dump($widget_instances);
If I do var_dump($data); I get NULL
If I do var_dump($widget_instances); I get:
array(1) { ["_multiwidget"]=> int(1) }
Lets rephrase your question into 2 parts:
"How to get a widgets settings"
"How to get the list of featured posts as used by that widget for purpose of excluding them from another list of posts"
1. Widget settings:
Widget settings are stored in the database in the wp_options table. If you do a search in phpmyadmin using widget% wildcard in the option name field you will see all widgets and their serialised data arrays.
You may note that they all have a subarray called "_multiwidget" which will contain the instances and their settings. In your example above you dumped this ["_multiwidget"]=> int(1)
This shows that nothing has yet been stored for that widget. The widget is not in a sidebar and/or no featured posts have been defined for that widget.
If the widget had been saved to a sidebar with some settings we would be seeing more details here.
Setup some widget instances so you can see the saved data structures. Then you will be able to see the widget details (either via phpmyadmin or by dumping as before)
2. Get list of featured posts out of a set of widget instances in order to exclude them from a query (in another widget)
For the widget you looking at we would probably see an array of settings one of which would be called "featured_post".
Once the widget has been dragged to some sidebars and has some featured posts defined in a few instances, you can then in your new widget do something like (pseudo code):
$widget_name = 'seleccion_subtitulo'; //if that's the widget name in the db.
$widget_settings = get_option('widget_' . $widget_name);
$featured_posts = array();
if (!empty($widget_settings)) {
if (!empty($widget_settings["_multiwidget"])) {
$instances = $widget_settings["_multiwidget"];
foreach ( $instances as $wid => $instance) {
$featured_posts[] = $instance['featured_post']; // if that is how it is stored in the widget details
}
}
}
You can then use https://developer.wordpress.org/reference/functions/get_posts/ and pass the array $featured_posts
in the argument array as
'exclude' => $featured_posts
Note that It is not necessary to know the 'instance' or the 'widget id' for what you say to want to achieve, one simply has to loop through all the instances for that widget.
I am having an issue with my custom post type and pagination. My custom post type is "vacancies".
I have created a custom archive template "archive-vacancies.php"
The page URL is "mydomain.com/vacancies"
Here is my code:
global $wp_query, $paged;
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args = array_merge( $wp_query->query_vars, array( 'posts_per_page' => 3, 'paged'=>$paged ) );
query_posts( $args );
if ( have_posts() ) :
while ( have_posts() ) : the_post();
//display code goes here
endwhile;
else :
get_template_part( 'includes/no-results', 'index' );
endif;
?>
<?php wp_pagenavi(); ?>
Everything works when I am on the main page i.e. mydomain.com/vacancies and the pagination shows the correct links but when I click on page 2 of the pagination links it goes to mydomain.com/vacancies/page/2 and the template defaults to archive.php and I get a "No Results" message.
Any help is much appreciated.
If anyone comes across this issue, you can add this to your functions.php code
add_filter('redirect_canonical','pif_disable_redirect_canonical');
function pif_disable_redirect_canonical($redirect_url) {
if (is_singular()) $redirect_url = false;
return $redirect_url;
}
remember to change is_singular () to is_tax / is_home or the type of page on which the loop is being made
https://wordpress.stackexchange.com/questions/129486/using-paged-redirects-page-2-to-page-1
Looking for your help and advices.
I have a list of links to single in Wordpress. I need to place class active only to li of active page.
Should be like on this image
But it is:
My wp-code:
<ul class="inline-list medium-6 large-4 skill-items">
<?php
$id = get_the_ID();
// echo $id;
$class;
$skills = new WP_Query( array(
'post_type' => 'skills',
'order' => 'ASC'
));
if ($skills->have_posts()) : while ($skills->have_posts()) : $skills->the_post();
// echo $post->ID;
if( $id == $post->ID) {$class = 'active';} else {$class = '';}
?>
<li class="<?php echo $class; ?>"><?php the_title(); ?></li>
<?php endwhile; endif; wp_reset_query();
?>
</ul>
That's not the proper way to do a menu in Wordpress. You should use wp_nav_menu instead of doing a custom WP_Query.
First, in functions.php add the following to register a new menu:
add_action('after_setup_theme', 'register_my_menu');
function register_my_menu() {
register_nav_menu('skills_menu', __( 'Skills menu', 'your-theme-name' ));
}
Then log in your administration, you will see that new menu placement under Appearance > Menu. Create a new menu for that placement - you have the possibility to automatically add top level new pages to this menu.
Then in your template add the following in order to display the menu:
<?php wp_nav_menu(array('theme_location' => 'skills_menu')); ?>
Wordpress will automatically handle the active class by adding current-menu-item to the appropriate li. No need for any filter for that.
Found an answer for my question using Javascript/jQuery
jQuery(document).ready(function($){
var pgurl = window.location.href;
$("ul.skill-items li").each(function(){
if($(this).find('a').attr("href") == pgurl || $(this).find('a').attr("href") == '' )
$(this).addClass("active");
})
});
pgurl contains your current url. After that for each item we are looking for anchor and its link. Then we are comapring those links, and if their are equal, we add class active to li
You may try this:
function my_alter_classes_on_li( $classes, $item ){
global $post;
if( in_array( $post->post_type, $classes ) ) $classes[] = 'current-menu-item';
return $classes;
}
add_filter( 'nav_menu_css_class', 'my_alter_classes_on_li', 10, 2 );
I'm trying to make the front-end login for Wordpress redirect to the post (in a custom post type) that was automatically created when they registered.
I can get the URL I want to redirect them with a wp_query. I imagine this is not the best way to do it, but I don't know enough php to figure it out. Here's my current attempt, but it just prints the url (the right one, at least!) on a blank page with the same login url they were already at:
function my_login_redirect( $redirect_to, $request, $user ){
global $user, $post;
$args = array(
'author' => $current_user->ID,
'post_type' => 'course-providers',
'showposts' => 1,
'caller_get_posts' => 1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ($my_query->have_posts()) : $my_query->the_post(); ?>
<?php wp_redirect ( the_permalink () ); ?>
<?php
endwhile;
} else {
echo "This User Has no Profile";
}
}
add_filter("login_redirect", "my_login_redirect", 10, 3);
Also, I imagine I don't need the wp_redirect and that I should just be using the login_redirect filter itself, but again, I'm pretty lost right now and just taking lots of shots in the dark.
Thanks for the help, and let me know if there's additional info that would make this more helpful for others or easier to answer. Thanks!
I ended up using a template redirect to make this work. I assume there's technically a better way to do it, but it's loading extremely fast and doing exactly what I need it to.
So, now, when a user logs in it goes to a direct url- /profiles - and the template on that page is just a redirect. I used the ideas and some sample code from this smashing magazine post on random redirects to make it work.
Here's the function I used in my functions.php file for the template to make the redirect happen:
function profile_redirect() {
// This is a template redirect
// Whenever someone goes to /profile (or any page using the profile template)
// this function gets run
if ( is_user_logged_in() ) {
global $current_user, $post;
$args = array(
'author' => $current_user->ID,
'post_type' => 'profile',
'posts_per_page' => 1
);
$my_query = null;
$my_query = new WP_Query($args);
if( $my_query->have_posts() ) {
while ( $my_query->have_posts() )
$my_query->the_post();
//We have a post! Send them to their profile post.
wp_redirect ( get_permalink () );
exit;
} else {
// If there are no posts, send them to the homepage
wp_redirect ( get_bloginfo('url') );
exit;
}
wp_reset_query();
} else {
// If they're not logged in, send them to the homepage
wp_redirect ( get_bloginfo('url') );
exit;
}
}
Then, on my profile template, I put this at the top with the opening php tag to run the function:
profile_redirect(); ?>
This is working for me, so I'll leave it as is for now :)