How to return the post ID in a WordPress shortcode

This should be so simple and it was it once I found the solution! (duh)

All I wanted to do is create a shortcode that will print (or echo or return – whatever you want to call it) the post ID of the current post.

So I would type something like: [mypostid]

and when the post was saved it would display just the post ID like: 1234

I tried using ‘the_ID’ and ‘get_the_ID’ and even $id, but none of those things worked.

I couldn’t find a straightforward answer to this question so I’m going to share the solution here. It’s really simple!

How to display the post ID in a shortcode:

You can put the code for this function in to the functions.php file of your theme, or preferably, add it to a plugin (details below). With a plugin you won’t lose the functionality of your shortcode if/when you change your WordPress theme.

*It’s a good idea to make a general Custom Functions plugin that is specific to your website and you can use it to house all these little extra functions that you will accumulate over time.

Here’s the basic code for the post ID shortcode:

//[thepostid]
function thepostid_func( $atts ){
         global $post;
         return $post->ID;   
}
add_shortcode( 'thepostid', 'thepostid_func' );

And below is the code to make a plugin out of this function. You should add this code to a plain text file called something like ‘my-custom-functions-plugin.php’, then either upload it to ‘wp-content/plugins/my-custom-functions-plugin/’ via FTP or, add the my-custom-functions-plugin.php file to a .zip file and upload it using the upload feature on the WordPress ‘Add New’ plugin page.

<?php
/*
Plugin Name: My Custom Functions
Plugin URI: http://yourwebsiteaddress.com
Description: A custom site functions plugin for yourwebsiteaddress.com
Version: 1.0
Author: Your Name Here
*/
 
//[thepostid]
function thepostid_func( $atts ){
         global $post;
         return $post->ID;   
}
add_shortcode( 'thepostid', 'thepostid_func' );

So, once you’ve added the code to your theme or plugin, you can simply type [thepostid] in to any post or page and voila! – the post ID will be displayed.

An alternative to TDO Mini Forms for WordPress?

Updated May 2013

(scroll down to see my working solution with free download and instructions).

For a while now I’ve been using the WordPress plugin TDO Mini Forms on a directory website to collect listings in the form of posts from unregistered users.

It was working fine until about 6 months ago when an exploit was discovered and my website (along with other TDO Mini Forms users) was hit by malicious uploads.

I was able to get around this by disabling image uploads from the TDO Mini Forms plugin and asking people to simply email the images to me if they’d like one included in their listing. It wasn’t a perfect solution but it worked temporarily.

Unfortunately I’ve recently had more problems with TDO Mini Forms – submissions simply aren’t coming through. I will receive a couple a week but I have been emailed by multiple people who’ve submitted listings via my site but have received no notifications (and neither did I), and no post appeared in my admin panel.

It’s such as shame as the plugin had so many great features, including:

  • User submissions with no registration required
  • Email notifications to myself and the user submitting the post, both when they submitted it AND when it was published
  • The ability to include any number of custom fields on the form so I could add inputs for things like telephone numbers and lists of services AND the ability to have these display in the new post (without having to code the custom fields in to my template)
  • The ability to upload images via the form

Whilst looking for an alternative to TDO Mini Forms I have regrettably found that my options are very limited! Most WordPress plugins that allow posting for unregistered users from the front end are either:

  • too basic and don’t give all the options I need
  • too old and out of date to rely on
  • have too many bugs reported on the WordPress forums for me to want to try them

So, I’m stumped!

Here’s some links to possible alternatives to TDO Mini Forms for anyone reading this:

  • User Submitted Posts – wordpress.org/extend/plugins/user-submitted-posts/
    I have tested this on WordPress v3.4.1 and it seems to work great but unfortunately it doesn’t the ability to add custom fields to the form which is something I definitely need. There may also be a security issue as I believe it doesn’t include nonce
  • Gravity Forms – http://www.gravityforms.com/
    This is a premium plugin but it seems like the $39 low level version would be worth the money if that’s all you needed although you get a license for 1 year, beyond that you need to pay again for updates and support
  • Post From Site – wordpress.org/extend/plugins/post-from-site/
    I’ve tested this on WordPress v3.4.1 and it worked as it’s supposed to and seemed like you could incorporate custom taxonomies, but it didn’t let me choose multiple tags (no tags were added when I selected multiple) and it didn’t allow the poster to add their own tag which is something I need. Another one for the ‘no’ pile unfortunately
  • WordPress Guest Post – wordpress.org/extend/plugins/wordpress-guest-post/
    This plugin had too many serious sounding bug reports in the support forum for my liking, but if you know a bit more about plugin editing you may be able to make something out of it
  • One Quick Post – wordpress.org/extend/plugins/one-quick-post/
    This plugin is marked ‘broken’ as of WordPress v3.4.1 so it should be avoided but it’s possible it will be fixed at a later date so I’ve included it in this list. I’m not sure whether it allows non-registered users to post

I have considered paying for Gravity Forms. It provides the features I need in that unregistered users can submit a post via a form on the front end of WordPress BUT – the ability to incorporate Paypal so that users can pay for listings appears to only be available on the expensive (about $200) developers license so I’m not sure this would work in the long term as I would like to eventually make my directory a pay for listing type system.

I’m always reluctant to pay for plugins because often there’s a good free alternative and you never know how long the plugin is going to be supported. If I buy something now and 2 years (and multiple WordPress versions) down the line it doesn’t work – I have eaten in to my very slim or usually non-existent profit margin for nothing!

I’ve also considered using a specific Directory WordPress plugin and browsed through a lot of them BUT most don’t use regular WordPress posts to display the listings, they use a custom post type. I have my directory set up to use regular posts and the basic WordPress category and tag system so I’d rather stick with that than have to re-vamp everything.

I may try some sort of hand coded solution to allow users to post from the front end which would avoid the need to reply on plugins, but this would require users to create an account on the site which is another thing I was hoping to avoid.

(*Note – in the end I did come up with a hand coded solution and users don’t have to log in – see the code example further down the page).

I will continue my hunt for an alternative to TDO Mini Forms and report back here if I find anything useful :)


Update 27th September 2012

It works!

After much tinkering and with huge, huge thanks to this “Posting from front end form” WordPress tutorial and some very helpful posts at StackExchange’s WordPress community – I managed to get a solution working.

This is a working alternative to TDO Mini forms, using a simple custom page template that you can put in to your theme and then assign to any page (or it should automatically assign it if you save the custom page template as page-mypagename.php, where ‘mypagename’ is the name of the page where the form will be displayed)

It doesn’t include all the features that TDO Mini Forms had (see my note about future updates at the end of this post) but this form allows anyone (including guests/unregistered users) to submit a new post from the front end including:

  • the post title
  • the post content
  • selecting a category (from existing categories)
  • adding tags
  • adding custom fields

(*This solution also contains some code for uploading files but that feature doesn’t seem to work. I’ve left the code in but commented it out. You’re safe to remove those bits if you want to)

There’s a downloadable custom page template available here – Download listingsubmissionform.php

or you can just copy & paste this code in to a new file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
    /*
    Template Name: Listing Submission Form
    */
?>
<?php
// Check if the form was submitted
 
if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] )) {
 
        // Do some minor form validation to make sure there is content
        if (isset ($_POST['title'])) { 
                $title =  $_POST['title']; 
        } else { 
                echo 'Please enter a title';
        }
        if (isset ($_POST['description'])) { 
                $description = htmlentities(trim(stripcslashes($_POST['description']))); 
    } else {
        echo 'Please enter the content';
        }
 
	$nonce=$_REQUEST['_wpnonce'];
	if (! wp_verify_nonce($nonce, 'new-post') ) die('Well that was naughty.');
 
        $tags = $_POST['post_tags'];
        $customfieldone = $_POST['customfieldone'];
        $customfieldtwo = $_POST['customfieldtwo'];
 
	// You can add more custom fields by replicating the lines above and any other references to customfieldone and customfieldtwo, and changing them to your custom field values
 
        // Add the content of the form to $post as an array
        $type = trim($_POST['Type']);
        $post = array(
                'post_title'    => $title,
                'post_content'  => $description,
                'post_category' =>   array($_POST['cat']),  // Usable for custom taxonomies too 
                'post_status'   => 'pending',               // Choose: publish, preview, future, etc.
                'tags_input'    => array($tags),
                'tax_input'    => array( $type),
                'comment_status' => 'closed',
                'post_author' => '2', 	// Set to 1 for the main admin account as author, provided that is user ID 1
                'customfieldone'    =>   $customfieldone,
                'customfieldtwo'    =>   $customfieldtwo 
        );
        $post_id = wp_insert_post($post);
        wp_set_post_terms($post_id,$type,'Type',true);
	add_post_meta($post_id, 'metatestcustomfieldone', $customfieldone, false);
	add_post_meta($post_id, 'metatestcustomfieldtwo', $customfieldtwo, false);
        wp_redirect( home_url('/listing-submitted/') ); // redirect to this page after submit
        exit();
 
// This bit of code relates to image uploads and it's not working correctly so it's commented out for now
//	if ($_FILES) {
//		foreach ($_FILES as $file => $array) {
//			$newupload = insert_attachment($file,$post_id);
//			//$newupload returns the attachment id of the file that
//			// was just uploaded. Do whatever you want with that now.
//		}
//	}
 
}
 // endIF
 
?>
<?php get_header() ?>
 
            <div id="container">
                <div id="content" role="main">
 
		        <h1 class="page-title">Submit your listing</h1>
 
<!--SUBMIT POST-->
		        <form id="new_post" name="new_post" class="post_work" method="post" enctype="multipart/form-data">
			<?php wp_nonce_field( 'new-post' ); ?>
 
		                <p><label for="title">Title</label><br />
			                <input type="text" id="title" class="required" value="" tabindex="1" size="20" name="title" />
		                </p>
		                <p><label for="description">Description</label><br />
			                <textarea id="description" type="text" class="required" tabindex="3" name="description" cols="50" rows="6"></textarea>
		                </p>
 
		    		<fieldset class="category"> 
			                <label for="cat">Category:</label> 
			                <?php wp_dropdown_categories( 'tab_index=10&taxonomy=category&hide_empty=0' ); ?> 
				</fieldset>
 
<!-- CustomFieldOne --> 
				<fieldset class="customfieldone"> 
					<label for="customfieldone">Custom Field One:</label> 
			                <input type="text" value="" id="customfieldone" tabindex="20" name="customfieldone" /> 
				</fieldset>
 
<!-- CustomFieldTwo --> 
				<fieldset class="customfieldtwo"> 
					<label for="customfieldtwo">Custom Field Two:</label> 
					<input type="text" value="" id="customfieldtwo" tabindex="20" name="customfieldtwo" /> 
				</fieldset> 
 
<!-- This bit of code relates to image uploads and it's not working correctly so it's commented out for now -->
<!--
				<p><label for="attachment">Photos: </label>
					<input type="file" id="attachment">
					<div id="attachment_list"></div></p>
-->
 
				<p>Tags: <input type="text" value="" tabindex="35" name="post_tags" id="post_tags" /></p>
 
<!-- I'm not sure what domande means in the value below, but if I change it to post as you would assume it should be, the form doesn't work -->
				<input type="hidden" name="post_type" id="post_type" value="domande" />
				<input type="hidden" name="action" value="post" />
 
				<p style="text-align:right"><input type="submit" value="Submit" tabindex="6" id="submit" name="submit" /></p>
 
			</form>
 
<!-- This bit of code relates to image uploads and it's not working correctly so it's commented out for now -->
<!--			<script>
			    var multi_selector = new MultiSelector( document.getElementById( 'attachment_list' ), 8 );
			    multi_selector.addElement( document.getElementById( 'attachment' ) );
			</script>
-->
 
<!--SUBMIT POST END-->
 
	        </div><!-- .content -->
	    </div><!-- #container -->
 
<?php get_footer(); ?>

Save the file linked above or copy the code in to a new file and upload it to your active WordPress theme folder, i.e. yourwebsite.com/wp-content/themes/YOUR-THEME/ You may also need to assign the custom page template to your page from the WordPress admin panel.

About the page layout

You will see from the code example above that the form is inside 2 div’s – ‘content’ and ‘container’ – you may need to change this to fit your theme. If in doubt, open some files from your theme (preferably something like page.php or single.php) in a text editor and see what code was used there. You should be able to figure out what to use in your form’s custom page template.

Future updates

I’d like to work on getting the file uploads working in the future and, more importantly for my needs – email notifications when a new post is submitted, preferably one to me as site admin, and one to the person submitting the post (with the email address stored via one of the custom fields in the form).

I will be looking in to this when I get time so stop by at a later date if this is something you need, or leave a comment below and perhaps we can work it out together.

Ok, you’re done!

I hope this has been of help to anyone out there panicking like I have been about TDO Mini Forms not working! It was a great plugin while it lasted but I don’t think it’s going to make a comeback.

This is a good alternative for TDO Mini Forms because it’s built in to your theme instead of using a plugin, so you don’t have to worry about plugins becoming outdated and not being maintained like TDO Mini Forms did.

Good luck with it! Give me a shout in the comments if this was helpful to you or if you have problems with it.