Add page to menu programmatically after creation - php

I have been trying to figure this out for hours and I've had no luck. I know it's something easy that I'm missing, but I cannot find it anywhere on StackOverflow.
What I want to is add the page that is being created here to either the existing menu (which will be blank), or remove the current menu, create a new menu and add the page that way, whichever is easier.
Here is the code I'm using to add a page (and editing / saving) from a plugin interface:
$titlep2 = $_REQUEST['titlep2'];
$post_text2 = $_REQUEST['post_text2'];
if($titlep2 != ""){
$posthwe_id2 = get_option("hwepag2");
if($posthwe_id2 == ""){
$hwea2 = array('post_title' => $titlep2,
'post_content' => $post_text2,
'post_status' => 'publish',
'post_type' => 'page');
$post_idp2 = wp_insert_post($hwea2);
update_option("hwepag2",$post_idp2);
}else{
$my_post2 = array('ID' => $posthwe_id2,
'post_title' => $titlep2,
'post_content' => $post_text2,
);
wp_update_post( $my_post2 );
}
}
I have tried many variations of wp_update_nav_menu_item, but I cannot get it to work. I have an existing menu, but it will be blank when adding this post (this is for new/fresh sites that I develop offline). That being the case, it seems the menuID, which is "menu-top" does not exist in the UL before adding an element to the menu.
So, it's fine if the current menu needs to be deleted, a new one created, then the page I'm adding added to that menu.
Thank you so much!

Try this if not already done:
Go to Appearance > Menus > Select your menu if you have multiple of them > Check the checkbox down below that says "Automatically add new top-level pages to this menu"

Related

Gutenberg having conflict with my plugin short code and seems to be displaying on editor page

I have made my first plugin and it all works on the front end but I am having some weird backend conflict with the gutenberg. I have done two things, made my plugin automatically add the pages / overwrite them when they've checked off, and made the plugin shortcode.
Here is the problem on my gutenberg:
As you can see there are random red diamonds on the page. When I use the inspector I can see it has code from my plugin I created...
Here is how I created my plugin
First inside my functions page I registered a new short code.
add_shortcode('parts_listing_portal', 'portal_parts_list');
function portal_parts_list(){
include "shortcodes/parts_listing_shortcode.php";
return ;
}
Then I made content for inside the shortcode using JS, PHP, and HTML.(this is a big file with includes and API calls)
After the page looked the way I would like, I created a new function to work on my option submit. This function creates the page with the shortcode inside.
//Add parts
if ( get_option( 'parts' ) === "checked") {
$parts_list = array(
'post_title' => 'Parts',
'post_type' => 'page',
'post_name' => 'Parts',
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_content' => '[parts_listing_portal]',
'post_status' => 'publish',
'post_author' => get_user_by( 'id', 1 )->user_id,
'menu_order' => 0
);
// PARTS LIST
if(get_page_by_title('Parts') == null) {
wp_insert_post($parts_list);
}else{
$post_exists = get_page_by_title("Parts" );
$update_post = array('ID' => $post_exists->ID);
$post_update = wp_parse_args($parts_list, $update_post);
wp_update_post($post_update);
}
When my function adds to the page & you go to the gutenberg editor it shows the full page for a split second then goes away. I feel I missed a statement somewhere to only show on "page" but I have no idea where to look. I've spent a lot of time researching it but couldn't find it.
Thank you
Whenever adding a shortcode make sure to check iif in admin area. If in admin area return nothing
function portal_parts_list(){
if ( is_admin()){
return;
}else {
include "shortcodes/parts_listing_shortcode.php";
return ;
}
}
add_shortcode('part_description_portal', 'portal_parts_list');

Add Advanced Custom Field to existing form on Dokan- Add product & edit product page (WordPress/WooCommerce)

I’m using a multi-vendor (Dokan) plugin, and been customizing it. One thing I want to achieve and been struggling is that I want my advanced custom field(also a plugin) for single product to actually appear on the front-end, in one of the Dokan’s seller dashboard form (Edit product section).
I want my seller to be able to select a brand (my acf field) on the fron-end page.
Normally when we add a new acf field group, and assign to the archive, the field will appear on the backend.
I found this to be pretty hard to achieve, especially adding the custom field onto an existing front-end form.
I have trying to customize it and I finally get the field to appear on the form I want to, but then another problem came up, which is the save button from the original form isn’t clickable anymore.
Please see screenshot: https://gyazo.com/dfb20ed90e773723658979c515581730
and here is the code I attempted to add into my Dokan’s single-product-new.php:
<?php acf_form_head(); ?>
<div class=”dokan-form-group”>
<?php
$product_brand = -1;
$term = array();
$term = wp_get_post_terms( $post_id, ‘brand’, array( ‘fields’ => ‘ids’) );
if ( $term ) {
$product_brand = reset( $term );
}
include_once DOKAN_LIB_DIR.’/class.category-walker.php’;
include_once DOKAN_LIB_DIR. ‘acf.php’;
$brand_args = array(
‘hierarchical’ => 1,
‘hide_empty’ => 0,
‘fields’ => array(‘brand’),
‘name’ => ‘brand’,
‘id’ => ‘brand’,
‘taxonomy’ => ‘brand’,
‘title_li’ => ”,
‘class’ => ‘product_brand dokan-form-control dokan-select2’,
‘exclude’ => ”,
‘selected’ => $product_brand,
‘walker’ => new DokanCategoryWalker( $post_id )
);
acf_form($brand_args);
?>
<div class=”dokan-product-cat-alert dokan-hide”>
<?php esc_html_e(‘Please choose a brand!’, ‘dokan-lite’ ); ?>
</div>
</div>
I know this is wrong, but somehow these code helped me to pull the advanced custom field onto the form I want, and it’s actually saving the field data to the product when you click update.
I was thinking maybe should of work around this under child-theme's function.php...
Any help will be really appreciated!
Luke
You can use a free plugin named ACF Frontend Form for Elementor to add / edit products from front end for your sellers / vendors.
https://wordpress.org/plugins/acf-frontend-form-element/
For this you also need to use elementor plugin and create a product page through elementor

Wordpress check if you're on the current page (not menu)

I am creating a little shortcode that acts like the custom menu widget, but I'm choosing the pages from a dropdown list, instead of creating a menus inside the wordpress (I'm also adding a color to it, so I can't just use regular wordpress menus widget).
So far so good, it's just one thing that's bothering me. I want to check if the page I'm on matches the one in my list (on the real page). I googled and searched a bit and found that with
$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
I can get the current page I'm on (the link I see in my browser). Perfect!
So if I want to add a class called current page, all I need to see if my $actual_link matches with my selected link from the dropdown list.
I'm working this within a page bulder plugin The Creator, so I know how to create a working shortcode in it. My pages dropdown is created by making an array that will have page url as key and page name as a value. My loop is:
$args = array (
'post_type' => 'page',
'posts_per_page' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
);
$pages = get_posts($args);
$forms = array();
if(is_array($pages)){
foreach ($pages as $page) {
$forms[$page->url] = $page->post_title;
}
}
And it works perfectly. Except that the url I get from this is of the form:
http://www.example.com/?page_id=150
Whereas I set my permalinks to be nice so the actual link in my browser is
http://www.example.com/my_page_name
The id is correct, and if I click on my 'menu' link I'll get to that page (desired result). But now I cannot just go and say:
$current = ($actual_link == $link) ? 'current_page' : '';
where $link is the variable that holds the link to the page from the dropdown, so that I can append this to my list to check if I'm on the current page (adds a current_page class). I need this class for the styling purposes - if I'm on the page that has this menu shortcode, next to the link that matches this page I'll get chevron (>).
So my question is, how to get the matching urls, no matter what permalink setting I use? Is there a way to specify this in the get_posts() query, or with the $_SERVER[] variable?
I am trying to avoid javascript with this one, and do everything server side.
You need to place get_the_ID() inside get_permalink() it will return the link which you have to match with $actual_link
$link = get_permalink(get_the_ID());
something like this.
Ok, found the answer.
I changed my query to
$args = array (
'post_type' => 'page',
'posts_per_page' => -1,
'orderby' => 'menu_order',
'order' => 'ASC',
);
$pages = get_posts($args);
$forms = array();
if(is_array($pages)){
foreach ($pages as $page) {
$forms[$page->ID] = $page->post_title;
}
}
So that I can get page ID, then use
$link_out = get_permalink($link);
$current = ($actual_link == $link_out) ? 'current_page' : '';
And it works! :D

Wordpress - Imported pages appear, but lost data

I exported just the pages from one WP install to another and it was successful. When I go to the pages list, it displays them all and shows parent/child relationships, but doesn't seem to be recognized anymore when using some custom code in the template. It works on the original site just fine and I compared WP versions; they're the same.
Here is the code I'm using:
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page', 'orderby' => 'date', 'order' => 'ASC'));
// Get the page as an Object
$products = get_page_by_title('Products');
// Filter through all pages and find Products' children
$products_children = get_page_children($products->ID, $all_wp_pages);
// echo what we get back from WP to the browser
echo '<ul id="product-nav">';
foreach($products_children as $child){
echo '<li><a href="'.get_page_link($child->ID).'" title="'.$child->post_title.'">';
echo get_the_post_thumbnail($child->ID).'<span>'.$child->post_title.'</span>';
echo '</a></li>';
}
echo '</ul>';
When I performed a var_dump() on $all_wp_pages, they aren't being displayed there either. It's as if they don't exist, but show up on the back end as expected. Finally, I tried changing one of the child page's parent, then back again in hopes that would reset it, but had the same result.
Any idea why this would be happening?

How to inject a virtual post (i.e. without adding it to the database)

I use a WordPress blog and I want to show a post without adding anything to database.
What I want to say is:
I generate a post when page loads,and prepend it in homepage.
I've searched and found wp_insert_post() function but it also add to database.
How can i do this with php?
For example:
There is a post array which is generated by a query.How can I insert my post to this array before page loaded?
I want clear my idea.Here's step by step what i want.
*1)*Im generating an array like that
$arr['title] = "my title",
$arr['content'] = "my content",
*2)*WP sends a query to database and have the posts am i right? And there is an array,to show on the theme and main page?
At this point i want to add my external array(generated in step1 ) to this array(generated by WP via a query)
3) By this way i will be able to add a post without adding it to my database.
You can simply add your virtual post in one of your theme templates as raw HTML.
Alternatively, if you're feeling adventurous, you could modify the main query results and include your post inside:
add_action('loop_start', function($query){
// create the post and fill up the fields
$post = new WP_Post((object)array(
'ID' => -1,
'post_title' => 'Bla blah',
'post_content' => 'Your content',
));
// add it to the internal cache, so WP doesn't fire a database query for it
// -1 is the ID of your post
if(!wp_cache_get(-1, 'posts'))
wp_cache_set(-1, $post, 'posts');
// prepend it to the query
array_unshift($query->posts, $post);
});
The currently accepted answer causes the new post to delete the last post in the loop, because it doesn't update the post count. Here's my modified version that also includes:
Support for empty categories.
Only one place to declare the new post's ID.
Adding is_main_query() as the person who originally answered mentioned in a comment.
A setting to decide if the new post should be appended or prepended.
Hiding the post's date because otherwise you get something like 00000000. I could have used a dynamic date but it may be bad SEO to keep updating the date without updating the content.
Hiding the post's comment link because it just leads to the homepage.
A setting to control the post type. You might prefer "page" because "post" displays a general category, which I found no way to bypass. "Page" also looks more distinguished among other posts, assuming that's a good thing.
Here's the modified code:
function virtual_post($query) {
$post_type = 'page'; // default is post
if (get_class($query)=='WP')
$query = $GLOBALS['wp_query'];
if ($query->is_main_query()) {
$append = true; // or prepend
// create the post and fill up the fields
$post = new WP_Post((object)array(
'ID' => -1,
'post_title' => 'Dummy post',
'post_content' => 'This is a fake virtual post.',
'post_date' => '',
'comment_status' => 'closed'
));
if ($post_type <> 'post')
$post->post_type = $post_type;
// add it to the internal cache, so WP doesn't fire a database query for it
if(!wp_cache_get($post->ID, 'posts')) {
wp_cache_set($post->ID, $post, 'posts');
if ($query->post_count==0 || $append)
$query->posts[] = $post;
else
array_unshift($query->posts, $post);
$query->post_count++;
}
}
}
$virtual_post_settings = array('enable' => true, 'include_empty_categories' => true);
if ($virtual_post_settings['enable']) {
if ($virtual_post_settings['include_empty_categories'])
add_action('wp', 'virtual_post');
else
add_action('loop_start', 'virtual_post');
}

Categories