Blogs
Web Design
Resources & Other
Fonts
Free
Paid
- TypekitNEW
- Lost Type
- Font Spring
- Ten Dollar Fonts
- MyFonts
- Adobe Type
- Font Haus
- Fonts.com
- Linotype
- Font Shop
For SEO reasons, you might always remove (or use) the www prefix in your urls. The following snippet will remove the www from your website url and redirect any url with the www to the non-www version.
RewriteEngine On RewriteCond %{HTTP_HOST} !^your-site.com$ [NC] RewriteRule ^(.*)$ http://your-site.com/$1 [L,R=301]
Hotlinking is a bad practice that consist of using the images from another site on yours. When you’re hotlinked by someone else, your bandwidth is used for someone else profit. Of course, you may want to prevent hotlinkers. Just add the following snippet to your .htaccess
file after replacing the example urls by your own urls.
RewriteEngine On #Replace ?mysite\.com/ with your blog url RewriteCond %{HTTP_REFERER} !^http://(.+\.)?mysite\.com/ [NC] RewriteCond %{HTTP_REFERER} !^$ #Replace /images/nohotlink.jpg with your "don't hotlink" image url RewriteRule .*\.(jpe?g|gif|bmp|png)$ /images/nohotlink.jpg [L]
Most bloggers are using Feedburner, a web service that lets you know how many people are reading your blog via feeds. If you’re using WordPress, you should redirect all WordPress feeds (rss, atom, etc) to your feedburner feed. Modify lines 2 and 3, and then paste this code to your .htaccess
file.
<IfModule mod_alias.c> RedirectMatch 301 /feed/(atom|rdf|rss|rss2)/?$ http://feedburner.com/yourfeed/ RedirectMatch 301 /comments/feed/(atom|rdf|rss|rss2)/?$ http://feedburner.com/yourfeed/ </IfModule>
Tired of the old errors pages of your site? Just create some html files with the look you want, upload them to your server, and add the following to your .htaccess
file:
ErrorDocument 400 /errors/badrequest.html ErrorDocument 401 /errors/authreqd.html ErrorDocument 403 /errors/forbid.html ErrorDocument 404 /errors/notfound.html ErrorDocument 500 /errors/serverr.html
File extensions may be useful to developers, but there’s absolutely no need for your site visitors to be able to see them. This snippet will remove the .html
extension on any html
files. Of course, this code can be easily adapted to remove extensions from other file extensions such as php.
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html # Replace html with your file extension, eg: php, htm, asp
Do you know that it is possible to send compressed data to the visitors, which will be decompressed by the client? This code will definitely save you (and your visitor) bandwidth and reduce your pages weight.
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/javascript text/css application/x-javascript BrowserMatch ^Mozilla/4 gzip-only-text/html BrowserMatch ^Mozilla/4.0[678] no-gzip BrowserMatch bMSIE !no-gzip !gzip-only-text/html
In order to avoid encoding problems, you can force a specific encoding directly on your .htaccess file. That way, you’ll ensure that your html documents will always render correctly, even if your forget to add a <meta http-equiv="Content-Type">
directive on your html pages.
<FilesMatch "\.(htm|html|css|js)$"> AddDefaultCharset UTF-8 </FilesMatch>
<?php the_content() ?> ..... Displays the content of the post/page <?php the_excerpt() ?> ..... Displays the excerpt of the current post/page <?php the_time() ?> ..... Displays the time of the current post/page <?php the_date() ?> ..... Displays the date of a post or set of post/page <?php the_permalink() ?> ..... Displays the URL for the Permalink <?php the_category() ?> ..... Displays the category of a post <?php the_author() ?> ..... Displays the author of the post <?php the_ID() ?> ..... Displays the numeric ID of the current post <?php wp_list_pages() ?> ..... Displays all the pages
If you want to display the “accept terms and conditions” on the left side you can use following code:
#payment .terms { text-align: left !important; }
If you want to increase the font size, adjust the font weight, etc. use:
#payment .terms { font-size: 15px !important; font-weight: bold; }
Article wroted by Ron Ventura at engagewp.com
All the code snippets bellow are to be used in functions.php
Things you’ll need for this tutorial include a Gravity Forms Developer license (includes the payment gateway add-ons needed to accept payment), Advanced Custom Fields Pro (it has the “Repeater” field for creating invoices with multiple products/services) and the Genesis Framework (optional but it will make presentation a lot easier).
Create Invoice Custom Post Type
The first step I want to take is creating the Invoice custom post type. This code registers the Invoice post type without an archive and excluded from search queries on your site. This means that users will need to have a direct URL to access an invoice post.
<?php //* Mind this opening PHP tag /** * Register Invoice Type * * @author Ren Ventura * @link http://www.engagewp.com/create-invoices-gravty-forms-wordpress */ add_action( 'init', 'rv_invoice_cpt' ); function rv_invoice_cpt() { $labels = array( 'name' => _x( 'Invoice', 'post type general name', 'engwp' ), 'singular_name' => _x( 'Invoice', 'post type singular name', 'engwp' ), 'menu_name' => _x( 'Invoices', 'admin menu', 'engwp' ), 'name_admin_bar' => _x( 'Invoice', 'add new on admin bar', 'engwp' ), 'add_new' => _x( 'Add New', 'Invoice', 'engwp' ), 'add_new_item' => __( 'Add New Invoice', 'engwp' ), 'new_item' => __( 'New Invoice', 'engwp' ), 'edit_item' => __( 'Edit Invoice', 'engwp' ), 'view_item' => __( 'View Invoice', 'engwp' ), 'all_items' => __( 'All Invoices', 'engwp' ), 'search_items' => __( 'Search Invoices', 'engwp' ), 'parent_item_colon' => __( 'Parent Invoice:', 'engwp' ), 'not_found' => __( 'No Invoices found.', 'engwp' ), 'not_found_in_trash' => __( 'No Invoices found in Trash.', 'engwp' ) ); $args = array( 'description' => __( 'Invoice', 'engwp' ), 'labels' => $labels, 'supports' => array( 'title' ), 'hierarchical' => false, 'public' => true, 'publicly_queryable' => true, 'query_var' => true, 'rewrite' => array( 'slug' => 'invoice' ), 'show_ui' => true, 'menu_icon' => 'dashicons-media-spreadsheet', 'show_in_menu' => true, 'show_in_nav_menus' => false, 'show_in_admin_bar' => true, // 'menu_position' => 5, 'can_export' => true, 'has_archive' => false, 'exclude_from_search' => true, 'capability_type' => 'post', ); register_post_type( 'invoice', $args ); }
Create Invoice Custom Fields
Next, we need to create some custom fields for the Invoice post type. For this tutorial (and all of my custom field work), I will be using Advanced Custom Fields Pro. There is a free version of Advanced Custom Fields but this particular project will require the Repeater field for adding multiple services to a single invoice.
For this tutorial, I’ve uploaded an importable JSON file for you to quickly import the fields. If you would like to use this file, you can download it from GitHub. That said, let’s walk through creating the fields manually.
Create a field group called “Invoice Fields” or whatever you’d like to name it. In this group, we’ll be creating three fields (key is in parentheses):
Client Name (invoice_client_name) – This is where we’ll add the client’s name.
Client Email (invoice_client_email) – This is where we’ll add the client’s email address.
Invoice Services (invoice_services) – A repeater field that will allow us to add multiple services to each invoice.
Service Name (invoice_service_name) – The title of your service/product.
Service Amount (invoice_service_amount) – Amount to bill client for each service.
Service Quantity (invoice_service_quantity) – How many of each service/product.
Up next is to create the form that will be used by your clients to pay an invoice. This is now where we’ll get into Gravity Forms. To begin, create a new form and call it “Invoice” or whatever you prefer. This may be one of the most advanced forms you’ve ever created with Gravity Forms but it’s not too bad. I’m going to break it up into different sections.
In the Form Editor, we need to create five form fields:
This area is optional. You can disable confirmations or just keep the default Gravity Forms confirmation (although I don’t know why you would). I always like to display a confirmation so I’ll set one up. Nothing too fancy here. I’m just going to confirm that payment for their invoice ID was received. This will happen after the client lands back on my site after completing payment in PayPal.
Your payment for Invoice ID <strong>{Invoice ID:1}</strong> was submitted successfully.
As with the Confirmation, I’ll send a simple notice via email as well so the client has multiple confirmations that the payment was received. For the sake of demonstrating what’s possible with Gravity Forms merge tags, I’ll send a little more information to the client in the email.
{client_name:3}, Your payment was received successfully. Here are your invoice details: Invoice ID - {Invoice ID:1} Invoice Amount - {Invoice Total (Price):5.2} Date Paid - {date_mdy} If you have any questions, just reply to this email. Sincerely, WPGuru.info
Configure the rest of your notifications and you’re ready for the next step.
We’re halfway there! Next, we need to get our form working with a payment gateway. Since it’s the most widely used and easiest to set up, I’m going to be using PayPal. You will need to install and activate the Gravity Forms PayPal add-on. Once you’ve done that, the PayPal options you’ll need to access are found under the Form Settings section of your invoice form.
Create a new PayPal feed for the invoice form and enter the required information. Since this initial step is very simple and Gravity Forms provides good help boxes, I’m going to move onto the next part of integrating the form with PayPal.
After you’ve created the feed, you’ll be presented with more options. The most important of these options is the “Payment Amount” field. From this dropdown, you can select “Invoice Total” (our product field) or “Form Total.” Since we only have one product with no options, these two will be the same so it doesn’t matter which one you select. Go ahead and sync up any other field you wish by populating it with the information that should be sent to PayPal and finish up the remaining settings. I suggest not prompting the buyer/client to enter a note or shipping address unless absolutely necessary and to only send notification emails after payment has been received.
If you’ve made it this far, you now have an Invoice custom post type with custom fields for client details and invoiced services. You also have a form connected with PayPal to accept payment from the client for the items contained in the invoice. Now, we need to display this invoice and form to the client. To do this, we need to create an invoice template. Since I use Genesis for my development, it’s what I’ll be using to show you the single-invoice.php template I put together for this tutorial.
If you don’t use Genesis, you can still use the important parts but some of the code won’t apply to you (I’ll point out what you can ignore). Your best option would be to copy your theme’s single.php file and rename it single-invoice.php.
To begin, here’s my single-invoice.php template. Take a look and I’ll give a thorough explanation next.
<?php //* Mind this opening PHP tag /** * Single invoice template * * @author Ren Ventura * @link http://www.engagewp.com/create-invoices-gravty-forms-wordpress */ //* Define running total global variable $running_total = 0; //* Remove post info, post meta, breadcrumbs and title (Genesis specific hooks) remove_action( 'genesis_entry_header', 'genesis_do_post_title' ); remove_action( 'genesis_entry_header', 'genesis_post_info', 12 ); remove_action( 'genesis_entry_footer', 'genesis_post_meta' ); remove_action( 'genesis_before_loop', 'genesis_do_breadcrumbs' ); // Output invoice details add_action( 'genesis_entry_content', 'rv_invoice_details', 999 ); // (Genesis specific hook) function rv_invoice_details() { //* Set variables $invoice_id = get_the_title(); $name = get_field( 'invoice_client_name' ); $email = get_field( 'invoice_client_email' ); ?> <div class="invoice"> <h2>Invoice Number <?php echo $invoice_id; ?></h2> <p>Bill to: <strong><?php echo $name; ?></strong></p> <?php if ( have_rows( 'invoice_services' ) ): //* Start the table if services are listed ?> <table class="services"> <tr> <th>Service</th> <th>Price</th> <th>Quantity</th> </tr> <?php while ( have_rows( 'invoice_services' ) ) : the_row(); ?> <?php //* Set repeater variables $service_name = get_sub_field( 'invoice_service_name' ); $service_amount = '$' . number_format( get_sub_field( 'invoice_service_amount' ), 2 ); $service_quantity = get_sub_field( 'invoice_service_quantity' ); ?> <?php //* Output a details row for each service ?> <tr class="service"> <td class="name"><?php echo $service_name; ?></td> <td class="amount"><?php echo $service_amount; ?></td> <td class="quantity"><?php echo $service_quantity; ?></td> </tr> <?php global $running_total; $running_total += get_sub_field( 'invoice_service_amount' ) * get_sub_field( 'invoice_service_quantity' ); ?> <?php endwhile; ?> </table> <?php else : echo 'No services listed'; ?> <?php endif; ?> </div> <div class="payment-form"> <?php echo do_shortcode( '' ); ?> </div> <?php } add_filter( 'gform_field_value_client_name', 'gf_filter_client_name' ); function gf_filter_client_name() { return esc_attr( get_field( 'invoice_client_name' ) ); } add_filter( 'gform_field_value_invoice_amount', 'gf_filter_amount' ); function gf_filter_amount() { global $running_total; return esc_attr( number_format( $running_total, 2 ) ); } genesis(); // (Genesis specific function)
A nice feature to have is to automatically send an email to the client with a link to the invoice as soon as you publish the invoice. This step is not completely necessary but I’ve included some code specifically for it.
Recall that in step two, we created a Client Email field. We added this field for two reasons: we want to associate the client with an email address and to automatically send an email to them when an invoice is created. Since we set the field to be viewable by the admin only, we need to have it dynamically populated so that the field contains an email when it’s submitted. I chose not to have this field dynamically populated via a filter like Client Name and Invoice Amount because, since these invoices are technically viewable to anyone (don’t worry, not many people are looking to pay other peoples’ invoices), the client’s email would be viewable to anyone who was able to access the invoice and skilled enough to know where to look. Therefore, I’d prefer to populate this field via a query string that is included in the email sent to the client. That way, it would be very simple for the client to populate this field (perhaps without even knowing it) and their email would not be visible to anyone who accessed the invoice.
This snippet composes an email to send to the client after an invoice is generated and sends it to the email we entered when we created it. In the email’s body, it includes a link to the invoice and dynamically appends a query string that will populate the Client Email field. Everything is still just as simple for the client but much safer.
<?php //* Mind this opening PHP tag /** * Send an email to the invoice_client_email custom field in the Invoice post type * The acf/save_post hook is specific to the Advanced Custom Fields plugin * * @author Ren Ventura * @link http://www.engagewp.com/create-invoices-gravty-forms-wordpress */ //* Send a notice to the user when CPT is created add_action( 'acf/save_post', 'send_invoice_notice', 20 ); function send_invoice_notice( $post_id ) { if ( 'invoice' == get_post_type( $post_id ) ) { // Get client's first name $name = get_field( 'invoice_client_name', $post_id ); $first_name = explode( ' ', $name ); // Get client's email $to = get_field( 'invoice_client_email', $post_id ); // Get invoice link with client's email passed as query string $permalink = trailingslashit( get_permalink( $post_id ) ) . '?client_email=' . $to; // Set email subject $subject = 'Your EngageWP Service Invoice'; // Set email message $message = 'Hi, ' . $first_name[0] . '. An invoice was just created and assigned to you on EngageWP. Click here to view invoice details: ' . $permalink; // Send email wp_mail( $to, $subject, $message ); } }
Whew! You think your worn out from following these instructions? Try writing this entire post (over 2,000 words) in one sitting! You’ve now set up a custom invoice system using a simple custom post type, some custom fields and Gravity Forms as your payment processor. Feel free to modify it as you wish. If you come up with any neat additions, please post them in the comments! Thanks for reading.
Cookie | Duration | Description |
---|---|---|
cookielawinfo-checkbox-analytics | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics". |
cookielawinfo-checkbox-functional | 11 months | The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional". |
cookielawinfo-checkbox-necessary | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary". |
cookielawinfo-checkbox-others | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other. |
cookielawinfo-checkbox-performance | 11 months | This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance". |
viewed_cookie_policy | 11 months | The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data. |