„Gravity Forms for WordPress is a full featured contact form plugin that features a drag and drop interface, advanced notification routing, lead capture, conditional logic fields, multi-page forms, pricing calculations and the ability to create posts from external forms.“
There are multiple options how to handle the confirmation page. Gravity form allows you to send query parameters to the page it is redirecting to.
You can send all form information in the clear, via query variables, but that looks really messy. Its better to use something like this .. lead_id={entry_id} and query form information on the actual confirmation page.
This will output the submitted form data as an array, with all fields linked by field id.
1 2 |
$lead_id = intval( $_GET['lead_id'] ); $lead = RGFormsModel::get_lead($lead_id); |
When you are reusing the field data for your own purposes, its easier to deal with field names than with fields ids. So we get the form meta data
1 2 3 4 5 6 7 8 9 10 |
$form = RGFormsModel::get_form_meta( $lead['form_id'] ); foreach( $form['fields'] as $field ) { $values[$field['id']] = array( 'id' => $field['id'], 'label' => $field['label'], 'value' => $lead[ $field['id'] ], ); } |
and extend the lead array.
1 2 3 4 5 6 |
foreach($lead as $key => $val){ if(is_numeric($key)){ $lead_key = str_replace(" ", "_", strtolower($values[$key]['label'])); $lead[$lead_key] = $val; } } |
Before you needed to know the actual field id to get its value. Now you can use the generated lead key to get that value.
1 2 |
$field_key = 10; echo $lead[$field_key]; |
1 2 |
$field_key = "e-mail"; echo $lead[$field_key]; |
Much easier to reuse and remember :)
I am starting a small list of Material Design resources. If you have anything to share, let me know in the comments.
Sometimes we need to debug a WordPress plugin, even though the website is live.
This would display the errors for anyone.
1 |
define('WP_DEBUG', true); |
Gladly WordPress provides options to do this more subtle.
1 2 3 4 5 6 7 8 9 10 11 |
// Turns WordPress debugging on define('WP_DEBUG', true); // Tells WordPress to log everything to the /wp-content/debug.log file define('WP_DEBUG_LOG', true); // Doesn't force the PHP 'display_errors' variable to be on define('WP_DEBUG_DISPLAY', false); // Hides errors from being displayed on-screen @ini_set('display_errors', 0); |
metisMenu offers a lot of options to tweak layout and usage. The plugin provides options for
„Gisto is a code snippet manager that runs on GitHub Gists and adds additional features such as searching, tagging and sharing gists while including a rich code editor. All your data is stored on GitHub and you can access it from GitHub Gists at any time with changes carrying over to Gisto.“
The application is multi-platform.
validate_file
issue.)target
and video
/audio
attributes.Again another Google AMP article, this time dealing with Syntax Highlighting. If you have a code centric website, this is important.
In one of my last articles I talked about a Generic Syntax Highlighter. This time I want to show you, how to add Syntax Highlighting with GeSHi to a custom template in AMP-WP.
Please read up on documentation, as I am not diving into every detail.
1 2 3 4 5 6 7 8 |
add_filter( 'amp_post_template_file', 'xyz_amp_set_custom_template', 10, 3 ); function xyz_amp_set_custom_template( $file, $type, $post ) { if ( 'single' === $type ) { $file = dirname( __FILE__ ) . '/templates/my-amp-template.php'; } return $file; } |
1 2 |
add_action( 'pre_amp_render_post', 'xyz_amp_add_custom_actions' ); add_action( 'amp_post_template_css', 'xyz_amp_my_additional_css_styles' ); |
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 |
// Load phpQuery require ('my-libs/phpQuery/phpQuery.php'); // Load GesSHi require ('my-libs/geshi/geshi.php'); // Get AMP content and add it to phpQuery $doc = phpQuery::newDocumentHTML($this->get('post_amp_content')); $highlight = array(); // Loop through the code snippets (pre tags) foreach(pq('pre') as $snippet) { // Get classes of tag $class = pq($snippet)->attr("class"); // Check for Crayon Syntax Highlighter Class if (strpos($class, "lang:") !== false && strpos($class, "lang:default") === false) { preg_match("/lang:(?P<lang>\w+)/", $class, $catch); } else { // Fallback, if no language is detected $catch['lang'] = "php"; } // New Syntax Highlighter for each code snippet, with the correct language set // Storing for later stylesheet output. This makes also sure that stylesheets are only loaded once. $highlight[$catch['lang']] = new GeSHi(pq($snippet)->text() , $catch['lang']); // Uses Classes and no inlien styles $highlight[$catch['lang']]->enable_classes(); // Update code snippet $html = pq($snippet)->html($highlight[$catch['lang']]->parse_code()); } |
1 2 3 4 5 6 7 8 9 10 11 12 |
<style amp-custom> <?php $this->load_parts( array( 'style' ) ); ?><?php do_action( 'amp_post_template_css', $this ); // Load Stylesheets for highlighted languages foreach($highlight as $store){ echo $store->get_stylesheet(); } ?> </style> |
1 2 3 4 5 6 7 |
<div class="amp-wp-content"> <h1 class="amp-wp-title"><?php echo wp_kses_data( $this->get( 'post_title' ) ); ?></h1> <ul class="amp-wp-meta"> <?php $this->load_parts( apply_filters( 'amp_post_template_meta_parts', array( 'meta-author', 'meta-time', 'meta-taxonomy' ) ) ); ?> </ul> <?php echo $doc->html(); // amphtml content; no kses ?> </div> |
The AMP (Accelerated Mobile Pages Project) plugin for WordPress is still pretty young and under heavy development.
There are little things that can help to fix current validation problems. I have a couple of fresh AMP pages, that are already indexed by Google.
The currently registered Microformats template (schema.org-NewsArticle) requires an image.
The AMP-WP documentation explains how to add a featured image to your pages (documentation).
I extended that a bit, to link a default attachment image, I uploaded before. This needs to be added to your themes functions.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
function xyz_amp_add_custom_actions() { add_filter( 'the_content', 'xyz_amp_add_featured_image' ); } function xyz_amp_add_featured_image( $content ) { $your_attachment_id = 2016; if ( has_post_thumbnail() ) { $image = sprintf( '<p class="xyz-featured-image">%s</p>', get_the_post_thumbnail() ); }else{ $image = sprintf( '<p class="xyz-featured-image">%s</p>', wp_get_attachment_image( $your_attachment_id, 1280) ); $content = $image . $content ; } $content = $image . $content ; return preg_replace('/(<br>\s*){2,}/', '<br/>',$content); } |
Next we adjust the Microformats definition. This needs to be added to your themes functions.php.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
add_filter( 'amp_post_template_metadata', 'xyz_amp_modify_json_metadata', 10, 2 ); function xyz_amp_modify_json_metadata( $metadata, $post ) { if(empty($metadata['image'])){ $your_attachment_id = 2016; $imgMeta = wp_get_attachment_metadata($your_attachment_id ); $metadata['image'] = array( '@type' => 'ImageObject', 'url' => wp_get_attachment_url( $your_attachment_id ), 'height' => $imgMeta['height'], 'width' => $imgMeta['width'], ); } return $metadata; } |
Read the AMP-WP documentation first :) This forces AMP-WP to override the core template with your own. Use the default template as a reference.
1 2 3 4 5 6 7 8 |
add_filter( 'amp_post_template_file', 'xyz_amp_set_custom_template', 10, 3 ); function xyz_amp_set_custom_template( $file, $type, $post ) { if ( 'single' === $type ) { $file = dirname( __FILE__ ) . '/amp/amp_template.php'; } return $file; } |
Normally the core sanitizer should take care of that. I am sure a filter will be added in the future. For now, this is a quick workaround. You can use a RegExp or DOMDocument to alter the amp-content in your custom template and filter things that break validation.
1 2 3 4 |
$attributes = $element->attributes; while ($attributes->length) { $element->removeAttribute($attributes->item(0)->name); } |
I am using phpQuery for now, as it allows me to add quick fixes. DOMNode or QueryPath works nicely as well :) Will be looking at the core sanitizer and options later this week. All of this is currently added to the custom template.
1 2 |
require('your-libs/phpQuery/phpQuery.php'); $doc = phpQuery::newDocumentHTML($this->get( 'post_amp_content' )); |
1 |
$doc['.prettyphoto']->removeAttr("rel"); |
1 |
$doc['*']->removeAttr("align"); |
1 |
$doc['a[target="new"]']->attr("target","_blank"); |
Finally output the fixed content as HTML.
1 |
echo $doc->html(); // amphtml content; no kses |
The above examples need to be tweaked to your specific content requirements.
The custom template „post_amp_content“ before:
1 |
echo $this->get( 'post_amp_content'); // amphtml content; no kses |
The custom template „post_amp_content“ after:
1 2 3 4 5 6 |
require('your-libs/phpQuery/phpQuery.php'); $doc = phpQuery::newDocumentHTML($this->get( 'post_amp_content' )); $doc['.prettyphoto']->removeAttr("rel")->removeAttr("href"); $doc['*']->removeAttr("align"); $doc['a[target="new"]']->attr("target","_blank"); echo $doc->html(); // amphtml content; no kses |
From the AMP specification :“Note, that AMP document may also be linked to directly…“
This is being added to the custom template as well.
Next:
1 2 3 4 5 6 7 |
global $query_string; $posts = query_posts($query_string); if (have_posts()) : while (have_posts()) : the_post(); $next_post = get_next_post(); if (!empty( $next_post )): echo '<a class="next" href="'.amp_get_permalink( $next_post->ID ).'"> ↜ '.$next_post->post_title.'</a>'; endif; |
Previous:
1 2 3 4 5 |
$prev_post = get_previous_post(); if (!empty( $prev_post )): echo '<a class="prev" href="'.amp_get_permalink( $prev_post->ID ).'"> ↜ '.$prev_post->post_title.'</a>'; endif; |
You can find a simple pure PHP highlighter here. Not perfect, but a start. Don not forget to include the CSS :)
1 2 3 4 5 |
require_once("your-lib/SyntaxHighlight/SyntaxHighlight.php"); foreach(pq('pre') as $code) { pq($code)->html(SyntaxHighlight::process(pq($code)->text())); } |
I will extend on this as new validation errors or tweaks come up. The core sanitizer of AMP-WP still needs some work and should allow us to do some of the above directly, when the content is parsed / converted for AMP.
Google’s AMP is here to save us from slow mobile content delivery, by enforcing strict standards and limiting what is allowed within AMP pages. The pages only allow a subset of tags and introduce their own tags for fast prefetching of content (images, videos … AMP Specs)
„The Accelerated Mobile Pages (“AMP”) Project is an open source initiative that came out of discussions between publishers and technology companies about the need to improve the entire mobile content ecosystem for everyone – publishers, consumer platforms, creators, and users.
Today, the expectation is that content should load super fast and be easy to explore. The reality is that content can take several seconds to load, or, because the user abandons the slow page, never fully loads at all. Accelerated Mobile Pages are web pages designed to load instantaneously – they are a step towards a better mobile web for all.“
AMP pages are cached within the AMP Cache, providing even faster delivery of your content. The core libs validate your implementation and highlight any problems by pushing errors to the console.
The documentation lists all components currently supported within a page and experimental components in development as well.
I have already added AMP support to our blog posts:
Google’s Webmaster Tools also integrates a new section for AMP, to see how they perform.
AMP is not supposed to replace your webpage, but offer a faster access point to presented content. It will not solve all use cases, but offer better performance for your simple reading pleasure for now. Its a start and lets see how it evolves ;)
Simple way to do some Visual Composer Grid cleanup, when you are using Bootstrap within your theme. This removes and cleans up classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
add_filter('vc_shortcodes_css_class', function ($class_string, $tag) { $tags_to_clean = [ 'vc_row', 'vc_column', 'vc_row_inner', 'vc_column_inner' ]; if (in_array($tag, $tags_to_clean)) { $class_string = str_replace(' wpb_row', '', $class_string); $class_string = str_replace(' vc_row-fluid', '', $class_string); $class_string = str_replace(' vc_column_container', '', $class_string); $class_string = str_replace('wpb_column', '', $class_string); // replace vc_, but exclude any custom css // attached via vc_custom_XXX (negative lookahead) $class_string = preg_replace('/vc_(?!custom)/i', '', $class_string); // replace all vc_ // $class_string = preg_replace('/vc_/i', '', $class_string); } $class_string = preg_replace('|col-sm|', 'col-sm', $class_string); return $class_string; }, 10, 2); |
Visual Composer for WordPress
Bootstrap / Bootstrap Sass