How to mark wordpress posts as read? - wordpress

I want to make something similar to what Techcrunch have on their site. For now I use wordpress plugin that mark posts as new and think to modified it to achieve similar functionality but the plugin won't work for ajax loading.
What I want to make is when user open new post, automatically after he returns to the front page, title and excerpt of the post to be color faded. How to make this with setting cookie and make it to work for title and excerpt on any page (for post list, grids etc.), instead of single post page. And also I need this to work when new posts are loaded with ajax.
I tried this function and It's work ok, but now I need text label to change to Old after user open the post, and then to inject some css to the title. Also, this is not perfect, because I want all posts to be New on first visit, an then to change to Old after user open them.
function wpb_lastvisit_set_cookie() {
if ( ! is_admin() && ! isset( $_COOKIE['lastvisit'] ) ) {
setcookie( 'lastvisit', $current, time() + 3600 * 24 * 100, COOKIEPATH, COOKIE_DOMAIN, false );
}
}
add_action( 'init', 'wpb_lastvisit_set_cookie');
function wpb_lastvisit_the_title ( $title, $id ) {
if ( !in_the_loop() || is_singular() || get_post_type( $id ) == 'page' ) return $title;
// if no cookie then just return the title
if ( !isset($_COOKIE['lastvisit']) || $_COOKIE['lastvisit'] == '' ) return $title;
$lastvisit = $_COOKIE['lastvisit'];
$publish_date = get_post_time( 'U', true, $id );
if ($publish_date > $lastvisit) $title .= ' New';
if ($publish_date < $lastvisit) $title .= ' Old';
return $title;
}
add_filter( 'the_title', 'wpb_lastvisit_the_title', 10, 2);

Related

WordPress plugin to tag category while posting

I'm not a big programmer, but this week get in touch with Openai. It's my first experience with AI. I tried to create code that works as a Wordpress plugin to meet a need.
I make a lot of posts and each post I have to mark the same category. Then I thought that there should be a plugin to mark the category so that when I need to post again, the category would already have its checkbox checked, so I wouldn't need to scroll the selection box of the categories and mark the same category.
Openai generated this code, it didn't work, from what I noticed the cookie is not being created.
Plugin Name: Category Marker
Description: Checks the checkbox of the previously marked category when making a post
Version: 0.1
Author:
*/
//This is the first function
function catemarcada_create_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Create cookie when making a post
if ( isset( $post->ID ) ) {
$categoryID = get_post_meta($post->ID, '_category_id', true);
setcookie( 'catemarcada', $categoryID, time() + (86400 * 30), "/"); // 86400 = 1 day
}
}
}
add_action( 'wp_loaded', 'catemarcada_create_cookie' );
//This is the second function
function catemarcada_get_cookie() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Get cookie when accessing the post-new.php file
if ( isset( $_COOKIE['catemarcada'] ) ) {
$categoryfound = $_COOKIE['catemarcada'];
}
}
}
add_action( 'wp_loaded', 'catemarcada_get_cookie' );
//This is the third function
function catemarcada_check_category() {
global $post;
if ( isset( $post ) && 'post-new.php' == basename( $_SERVER['SCRIPT_FILENAME'] ) ) {
// Compare the value of the cookie with the category IDs in the WordPress database
$categories = get_categories();
foreach ( $categories as $category ) {
if ( $categoryfound == $category->cat_ID ) {
// Check the checkbox field of the category in the WordPress database
echo '<input type="checkbox" name="'.$category->cat_ID.'" checked="checked" />';
}
}
}
}
add_action( 'wp_loaded', 'catemarcada_check_category' );
// Redirect to post-new.php
add_action('post_updated', 'redirect_post_new', 10, 3);
function redirect_post_new( $post_id, $post, $update ){
if( $update ){
wp_redirect( admin_url( 'post-new.php' ) );
exit();
}
}
This is the description of the plugin I asked to be generated:
Write PHP code that works as a Wordpress plugin. The plugin will only work when I access the “post-new.php” file.
First function:
When making a post, the plug-in will create a cookie with the name “catemarcada”.
This cookie will store the selected category ID during text posting. The cookie must expire within 360 days.
Second function:
When accessing the “post-new.php” file, check if the cookie named “catemarcada” already exists. If it exists, do not create it again.
And every time I access the “post-new.php” file, the plug-in will look up the ID that was recorded in the cookie named “catemarcada” and record the ID in a variable called “categoryfound”.
Third function:
The plug-in should compare the ID that is in the variable called “categoryfound” with the IDs of the categories in the Wordpress database.
If the ID that is in the variable called “categoryfound” is the same as the ID of any of the categories in the Wordpress database, check the checkbox field of the category in the Wordpress database in question.
When making a post, redirect to the post-new.php file.

how to change edit url with "Id" to edit url with "Slug" in Wordpress

I have this is WordPress Post editing Url:
https://example.com/wp-admin/post.php?post=ID&action=edit
and I want to change it to Slug Not the ID Like This:
https://example.com/wp-admin/post.php?post=Slug&action=edit
I was trying to edit the post with this Url but is not working:
https://example.com/wp-admin/post.php?post=MyPostSlug&action=edit
In order to change the edit post link structure, you can use the get_edit_post_link filter like so:
add_filter( 'get_edit_post_link', 'so_73914075_get_edit_post_link', 10, 3);
function so_73914075_get_edit_post_link($link, $post_id, $context) {
$post = get_post( $post_id );
if ( ! in_array( $post->post_type, array( 'post', 'page' ) ) ) {
return $link;
}
$post_type_object = get_post_type_object( $post->post_type );
if ( 'revision' === $post->post_type ) {
$action = '';
} elseif ( 'display' === $context ) {
$action = '&action=edit';
} else {
$action = '&action=edit';
}
if ( 'display' === $context ) {
$post_type = '&post-type=' . $post->post_type;
} else {
$post_type = '&post-type=' . $post->post_type;
}
$custom_edit_link = str_replace( '?post=%d', '?post-name=%s', $post_type_object->_edit_link );
return admin_url( sprintf( $custom_edit_link . $action . $post_type, $post->post_name ) );
}
This will change the edit links for regular posts and pages to something like this:
https://example.com/wp-admin/post.php?post-name=the-post-slug&action=edit&post-type=post
WARNING: make sure you limit this to only the post types you need to change the URL for. Making this change global will almost surely
have unintended effects over other plugins
However, making the admin panel actually load the edit screen is not that easy.
Looking at the source code of the wp-admin/post.php file, you will see that there is no way to hook into the flow and populate the $post_id variable with the post id matching the slug you are sending through.
That means you have 2 options:
RECOMMENDED Update the edit link to whatever format you want and then create an admin redirect function that pulls the slug from the initial URL and redirects to the actual edit page with the ?post=%d in it.
NOT RECOMMENDED Create a new admin edit page that will understand your URL structure and include the wp-admin/post.php after the code that pulls the $post_id based on the slug.
The 2nd method might come with lots of extra code you need to write to cover all the cases and all the instances a post reaches the post.php in the admin panel

Apply the_title filter to post titles AND backend auto social-sharing plugin, but not nav menu

The Challenge
I have been trying to write a filter that applies (prepends a string) to (a) post titles of a certain post type and (b) to that same post type WordPress admin backend for use by an auto social sharing plugin.
I've gotten really close. I've achieved:
1. prepending only to custom post_type post titles
2. prepending to custom_post type titles AND all nav menu items
3. prepending to ALL titles (post, page, nav menu, and backend auto-sharing plugin)
The final, 3rd attempt got me very hopeful, but yet still, no matter the function, conditional statement, or combination I use, I can't get custom_post title AND backend social sharing plugin, but not nav menu items.
My Code - what I've tried
I've tried different conditionals, like is_admin() and !is_nav_menu with all nav menu IDs. I've also tried comparing the ID of the post to the ID of the menu. Finally, I've also tried adding the filter only to loop_start and that seems promising if combined with other statements. I will clean up my code for your review but I leave it this way for now in hopes it helps to see what I've tried and maybe where I went wrong with any of those methods.
// , $id = NULL
function append_album_review_to_title( $title ) {
global $post;
global $dont_apply_title_filter;
$text = 'Album Review: ';
$prepended_title = $text . $title;
/*
$nav_menus_obj = wp_get_nav_menus();
$nav_menu_ids = '';
foreach( $nav_menus_obj as $nav_menu ) {
$nav_menu_ids .= $nav_menu->term_id . ',';
}
rtrim($nav_menu_ids, ',');
*/
// if ( get_post_type( $post->ID ) == 'album_review' && in_the_loop() ){
// if ( get_post_type( $post->ID ) == 'album_review' && $id == get_the_ID() ){
// if ( !is_nav_menu( '32057,32058,35135,32054,32056' ) ) {
// if ( get_post_type( $post->ID ) == 'album_review' && is_nav_menu( $id ) ) {
if ( get_post_type( $post->ID ) == 'album_review' && !$dont_apply_title_filter ) {
//print_r( $nav_menu_ids );
//print_r( is_nav_menu( $nav_menu_ids ) );
return $prepended_title;
/*
} elseif ( get_post_type( $post->ID ) == 'album_review' ) {
return $title;
*/
} else {
return $title;
};
}
add_filter('the_title', 'append_album_review_to_title');
//add_action('save_post', 'custom_post_type_title', 100);
/*
function set_custom_title() {
add_filter( 'the_title', 'append_album_review_to_title', 10, 2 );
}
add_action( 'loop_start', 'set_custom_title' );
*/
Solution
function append_album_review_to_title( $title, $id = NULL ) {
if ($id) {
if ( get_post_type( $id ) == 'album_review' ){
return 'Album Review: ' . $title;
} else {
return $title;
}
} else {
return 'Album Review: ' . $title;
};
}
add_filter('the_title', 'append_album_review_to_title', 10, 2);
Explanation
First trying this:
function append_album_review_to_title( $title, $id ) {
if ( get_post_type( $id ) == 'album_review' ){
return 'Album Review: ' . $title;
} else {
return $title;
}
}
add_filter('the_title', 'append_album_review_to_title', 10, 2);
I noticed that on the backend, the social sharing plugin I am using to auto-share posts would return warnings like missing parameter 2 and Notice: Trying to get property of non-object..., and so it occurred to me that unlike the front end (nav menu and the loop), in the backend, apparently an $id is not being passed to the_title and so I can use this as a conditional.
Checking for $id will, for my purposes, tell me that if it is true, we are on front end, if it is false, then we are at backend post view.
This code accomplishes what I need (ie, modify post title in the loop, do NOT modify nav menu items, and modify the_title for use by a backend social sharing plugin):

Multiple Content Filters Gravity View Plugin For Gravity Forms Plugin For WordPress

We are working with filters using the Gravity View plugin for Gravity Forms for WordPress. Not super good at filters yet, so hoping to get a little help with this if possible. We have a filter when added, that filters out certain content, based on the Gravity Form field ID. In the example below, we are filtering out the Gravity Form field with an ID of 18.
Example:
add_filter( 'gravityview/fields/custom/content_before', 'my_gv_custom_content_before', 10, 1 );
function my_gv_custom_content_before( $content ) {
$id = '18';
global $gravityview_view;
extract( $gravityview_view->field_data );
if( empty( $entry[ (string)$id ] ) ) {
return '';
}
return $content;
}
This works. Then taking it a step further, we are told we can add something to this filter to filter out multiple Gravity Form field ids using this something like this added to our example above. In this example, filtering Field 18 & 26:
if( ( false !== strpos( $content, '{MY_FIELD_NAME:18}') && empty( $entry['18'] ) ) || ( ( false !== strpos( $content, '{MY_FIELD_NAME:26}') && empty( $entry['26'] ) ) ) {
return '';
}
What would the two look like combined? For example, if we wanted to filter field id 18, 26 and perhaps a third field 34? Using the first part of the code example and then the second example, what would they look like combined? Could anyone provide an example?
Have been playing with this and not having much luck combining it all into one filter. Keep getting errors and I am sure we don't have something quite right. Thank you in advance.
Got it worked out, here is the code in case anyone needs it.
/** Modify the content returned from the Custom Content field */
add_filter( 'gravityview/fields/custom/content_before', 'my_gv_custom_content_before', 10, 1 );
/**
* Removes the custom content field's content in case a certain entry field is empty
*
* #param string $content Custom Content field content
* #return string
*/
function my_gv_custom_content_before( $content ) {
global $gravityview_view;
extract( $gravityview_view->field_data );
// field_id => merge_tag
$validation = array(
'18' => '{Custom Background:18}',
'26' => '{New YouTube Video Test:26}',
'28' => '{New Vimeo:28}'
);
foreach( $validation as $id => $merge ) {
if( false !== strpos( $content, $merge ) && empty( $entry[ (string)$id ] ) ) {
return '';
}
}
return $content;
}

How do you add_filter to only one instance of the_title()

I created a filter that modifies the_title() of a post, but the problem I'm having is that it's modifying every instance of the_title(). I got most of the problem sorted out with the in_the_loop() function, however any theme that has "next post" "previous post" navigation links within the loop are still having the filter applied (understandably so). How can I apply the filter to only the the_title() of the current post?
function xyz_the_title( $the_title ) {
if( !in_the_loop() )
return $the_title;
$location = get_post_meta( get_the_ID(), 'location', true );
$the_title .= ' - ' . $location;
return $the_title;
}
add_filter( 'the_title', 'xyz_the_title' );
do it with jQuery
Something like this should do the trick:
$(document).ready(function() {
$('#entry-header').text(function(i, oldText) {
return oldText === 'Popular Science' ? 'New word' : oldText;
});
});
This only replaces the content when it is Popular Science. See text in the jQuery API.
Rather than filtering the_title you could edit your template file instead and append the location to your returned the_title().
echo "<h1>" . get_the_title() . " - " . $location . "</h1>";
Ran into a similar situation and was hoping this thread could save me...
Anyways this is what I managed to do thus far in
add_filter( 'the_title', function( $title, $id ){
/**
* don't run in the backend
*/
if( is_admin() ) {
return $title;
}
/**
* invalid values received
*/
if( empty( $title ) || $id < 1 ){
return $title;
}
global $post;
if ( ! $post instanceof WP_Post ){
return $title;
}
/**
* PREVENTATIVE MEASURE...
* only apply the filter to the current page's title,
* and not to the other title's on the current page
*/
global $wp_query;
if( $id !== $wp_query->queried_object_id ){
return $title;
}
/**
* Don't run this filter if wp_head calls it
*/
if( doing_action( 'wp_head' ) ){
return $title;
}
return 'MODIFIED - '.$title;
});
Here are the shortfalls:
If you have the same post being displayed on the current page, somewhere else, it's gonna modify THAT post title as well
Currently thinking about having a look at the call stack to detect if the call is coming from the theme...
but I would suggest you find another solution bud...
Ah, didn't know it was for a plugin. In which case, I think you should be ok to use if_filter then. This checks whether the filter has been run x times on the page in question. So, we check if it has run once on the page and if so it won't run again. Also, I have assumed you only want this to run on single post pages. This is untested.
function xyz_the_title( $the_title ) {
if( is_single() AND did_filter('the_title') === 1 ) {
if( !in_the_loop() )
return $the_title;
$location = get_post_meta( get_the_ID(), 'location', true );
$the_title .= ' - ' . $location;
return $the_title;
}
}
add_filter( 'the_title', 'xyz_the_title' );

Resources