├── .editorconfig ├── .gitignore ├── .jshintrc ├── README.md ├── assets └── scripts │ ├── gfembed.js │ ├── gfembed.min.js │ └── settings.js ├── classes ├── AbstractPlugin.php ├── AbstractProvider.php ├── Addon.php ├── Plugin.php └── Provider │ ├── I18n.php │ └── Setup.php ├── composer.json ├── gravity-forms-iframe.php ├── includes ├── deprecated.php └── functions.php ├── languages └── gravity-forms-iframe.pot ├── package.json ├── screenshot-1.png └── templates └── gravity-forms-iframe.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # https://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | 16 | [{.esformatter,.jshintrc,*.json,*.yml}] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [{*.txt}] 21 | end_of_line = crlf 22 | 23 | [*.md] 24 | trim_trailing_whitespace = false 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json 4 | release 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "boss": true, 3 | "browser": true, 4 | "bitwise": true, 5 | "browser": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "eqnull": true, 9 | "immed": true, 10 | "jquery": true, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "smarttabs": true, 15 | "sub": true, 16 | "trailing": true, 17 | "undef": true, 18 | "globals": { 19 | "console": false, 20 | "exports": true, 21 | "module": false, 22 | "require": false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gravity Forms Iframe Add-on 2 | 3 | Embed a Gravity Form in an iframe on any site. 4 | 5 | __Contributors:__ [Brady Vercher](https://github.com/bradyvercher) 6 | __License:__ [GPL-2.0+](http://www.gnu.org/licenses/gpl-2.0.html) 7 | 8 | The typical process to embed a Gravity Form on a site where the plugin isn't installed requires: 9 | 10 | 1. Developing a custom page template with necessary code to output form scripts and styles. 11 | 2. Creating a new page in WordPress. 12 | 3. Inserting the form shortcode in the new page. 13 | 4. Manually writing an iframe tag with the page permalink and giving it a static height. 14 | 15 | With the _Gravity Forms Iframe_ add-on, just enable a setting to allow the form to be embedded and copy the code snippet. That's it. As a bonus, the iframe automatically resizes whenever the form height changes -- for instance, when fields are shown or hidden due to conditional logic. 16 | 17 | ## Features 18 | 19 | * Selectively enable embedding for individual forms. 20 | * Auto-resizing iframes. 21 | * Override embed templates in a theme or child theme. 22 | * Override settings via the embed src query string. 23 | * Extends the Gravity Forms add-on API to seamlessly integrate with the WordPress and Gravity Forms interface. 24 | * Protocol-relative URLs for embedding on secure sites (both sites need SSL). 25 | 26 | ## Settings 27 | 28 | The form title and description can be hidden independent of regular form display by toggling a checkbox after enabling the embedding setting. 29 | 30 | ![Form Iframe Settings Screenshot](https://raw.github.com/bradyvercher/gravity-forms-iframe/master/screenshot-1.png) 31 | _The form's iframe settings panel._ 32 | 33 | ### Overrides for Individual Iframes 34 | 35 | If the title and description settings need to be changed per embed, they can be modified in the iframe `src` query string. 36 | 37 | * **`dt`:** Set to `1` to display the form title; `0` to hide. 38 | * **`dd`:** Set to `1` to display the form description; `0` to hide. 39 | 40 | _**Example:** gfembed/?f=1&dt=0&dd=0_ 41 | 42 | ### Auto-resizing Script 43 | 44 | If the auto-resizing functionality isn't needed for a particular form, adjust the iframe's height attribute to accomodate the form and don't include the `'; 186 | 187 | $tooltip = ''; 188 | if ( isset( $choice['tooltip'] ) ) { 189 | $tooltip = gform_tooltip( $choice['tooltip'], rgar( $choice, 'tooltip_class'), true ); 190 | } 191 | 192 | $html = ''; 193 | 194 | if ( $echo ) { 195 | echo $html; 196 | } 197 | 198 | return $html; 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /classes/Plugin.php: -------------------------------------------------------------------------------- 1 | addon = new GravityFormsIframe_Addon( $this ); 45 | } 46 | 47 | /** 48 | * Add custom rewrite rules. 49 | * 50 | * @since 1.0.0 51 | */ 52 | public function register_rewrite_rules() { 53 | // The PHP extension is deprecated. 54 | add_rewrite_rule( '(gfembed(.php)?)/?$', 'index.php?gfiframe=$matches[1]', 'top' ); 55 | } 56 | 57 | /** 58 | * Whitelist custom query vars. 59 | * 60 | * @since 1.0.0 61 | * 62 | * @param array $vars Allowed query vars. 63 | * @return array 64 | */ 65 | public function query_vars( $vars ) { 66 | $vars[] = 'gfiframe'; 67 | return $vars; 68 | } 69 | 70 | /** 71 | * Handle requests for form iframes. 72 | * 73 | * @since 1.0.0 74 | */ 75 | public function template_redirect() { 76 | global $wp; 77 | 78 | if ( empty( $wp->query_vars['gfiframe'] ) || ( 'gfembed' != $wp->query_vars['gfiframe'] && 'gfembed.php' != $wp->query_vars['gfiframe'] ) ) { 79 | return; 80 | } 81 | 82 | $form_id = null; 83 | if ( ! empty( $_GET['f'] ) ) { 84 | $form_id = absint( $_GET['f'] ); 85 | } else { 86 | // The request needs an 'f' query arg with the form id. 87 | wp_die( esc_html__( 'Invalid form id.', 'gravity-forms-iframe' ) ); 88 | } 89 | 90 | $form = GFFormsModel::get_form_meta( $form_id ); 91 | $settings = $this->addon->get_form_settings( $form ); 92 | 93 | // Make sure the form can be embedded. 94 | if ( empty( $settings['is_enabled'] ) || ! $settings['is_enabled'] ) { 95 | wp_die( esc_html__( 'Embedding is disabled for this form.', 'gravity-forms-iframe' ) ); 96 | } 97 | 98 | // Disable the toolbar in case the form is embedded on the same domain. 99 | add_filter( 'show_admin_bar', '__return_false', 100 ); 100 | 101 | require_once( GFCommon::get_base_path() . '/form_display.php' ); 102 | 103 | // Settings may be overridden in the query string (querystring -> form settings -> default). 104 | $args = wp_parse_args( $_GET, array( 105 | 'dt' => empty( $settings['display_title'] ) ? false : (bool) $settings['display_title'], 106 | 'dd' => empty( $settings['display_description'] ) ? false : (bool) $settings['display_description'], 107 | ) ); 108 | 109 | // @todo Need to convert query string values to boolean. 110 | $display_title = (bool) $args['dt']; 111 | $display_description = (bool) $args['dd']; 112 | 113 | unset( $args ); 114 | unset( $settings ); 115 | 116 | // Templates can be customized in parent or child themes. 117 | $templates = array( 118 | 'gravity-forms-iframe-' . $form_id . '.php', 119 | 'gravity-forms-iframe.php', 120 | ); 121 | 122 | $template = gfiframe_locate_template( $templates ); 123 | include( $template ); 124 | exit; 125 | } 126 | 127 | /** 128 | * Handle config collection. 129 | * 130 | * This is usually called in wp_enqueue_scripts, but because the iframe 131 | * template doesn't call wp_head(), some Gravity Forms scripts aren't 132 | * localized, which causes JavaScript errors. 133 | * 134 | * @see Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider 135 | * 136 | * @since 2.0.3 137 | */ 138 | public function handle_config_collection() { 139 | $container = GFForms::get_service_container(); 140 | $config_collection = Gravity_Forms\Gravity_Forms\Config\GF_Config_Service_Provider::CONFIG_COLLECTION; 141 | 142 | $container->get( $config_collection )->handle(); 143 | } 144 | 145 | /** 146 | * Add a script to send the parent the iframe's size via postMessage. 147 | * 148 | * @since 1.0.0 149 | */ 150 | public function wp_footer() { 151 | if ( ! is_gfiframe_template() && ! apply_filters( 'gfiframe_print_resize_ping_script', false ) ) { 152 | return; 153 | } 154 | ?> 155 | 175 | load_textdomain(); 28 | } else { 29 | add_action( 'init', array( $this, 'load_textdomain' ) ); 30 | } 31 | } 32 | 33 | /** 34 | * Load the text domain to localize the plugin. 35 | * 36 | * @since 2.0.0 37 | */ 38 | public function load_textdomain() { 39 | $plugin_rel_path = dirname( $this->plugin->get_basename() ) . '/languages'; 40 | load_plugin_textdomain( $this->plugin->get_slug(), false, $plugin_rel_path ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /classes/Provider/Setup.php: -------------------------------------------------------------------------------- 1 | plugin->get_file(), array( $this, 'activate' ) ); 25 | add_action( 'wp_loaded', array( $this, 'maybe_flush_rewrite_rules' ) ); 26 | } 27 | 28 | /** 29 | * Flush the rewrite rules after activation. 30 | * 31 | * @since 2.0.0 32 | */ 33 | public function maybe_flush_rewrite_rules() { 34 | if ( ! is_network_admin() && 'yes' == get_option( 'gfiframe_flush_rewrite_rules' ) ) { 35 | update_option( 'gfiframe_flush_rewrite_rules', 'no' ); 36 | flush_rewrite_rules(); 37 | } 38 | } 39 | 40 | /** 41 | * Activation routine. 42 | * 43 | * @since 2.0.0 44 | */ 45 | public function activate() { 46 | update_option( 'gfiframe_flush_rewrite_rules', 'yes' ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cedaro/gravity-forms-iframe", 3 | "description": "Embed a Gravity Form on any site using an iframe.", 4 | "keywords": [ 5 | "wordpress", 6 | "gravity forms", 7 | "iframe" 8 | ], 9 | "type": "wordpress-plugin", 10 | "homepage": "https://github.com/cedaro/gravity-forms-iframe", 11 | "license": "GPL-2.0+", 12 | "authors": [ 13 | { 14 | "name": "Brady Vercher", 15 | "email": "brady@blazersix.com", 16 | "homepage": "http://www.cedaro.com/" 17 | } 18 | ], 19 | "support": { 20 | "issues": "https://github.com/cedaro/gravity-forms-iframe/issues", 21 | "source": "https://github.com/cedaro/gravity-forms-iframe" 22 | }, 23 | "require": { 24 | "composer/installers": "^1.0 || ^2.0" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /gravity-forms-iframe.php: -------------------------------------------------------------------------------- 1 | set_basename( plugin_basename( __FILE__ ) ) 66 | ->set_directory( plugin_dir_path( __FILE__ ) ) 67 | ->set_file( __FILE__ ) 68 | ->set_slug( 'gravity-forms-iframe' ) 69 | ->set_url( plugin_dir_url( __FILE__ ) ) 70 | ->register_hooks( new GravityFormsIframe_Provider_Setup() ) 71 | ->register_hooks( new GravityFormsIframe_Provider_I18n() ); 72 | 73 | /** 74 | * Include helper functions and backward compatibility files. 75 | */ 76 | include( $gfiframe->get_path( 'includes/deprecated.php' ) ); 77 | include( $gfiframe->get_path( 'includes/functions.php' ) ); 78 | 79 | /** 80 | * Load the plugin. 81 | */ 82 | add_action( 'plugins_loaded', array( $gfiframe, 'load_plugin' ) ); 83 | -------------------------------------------------------------------------------- /includes/deprecated.php: -------------------------------------------------------------------------------- 1 | get_path() ); 22 | 23 | /** 24 | * URL to the plugin directory. 25 | * 26 | * @since 1.0.0 27 | * @var string GFIFRAME_URI Plugin URL. 28 | */ 29 | define( 'GFIFRAME_URI', gfiframe()->get_url() ); 30 | 31 | /** 32 | * The main plugin class. 33 | * 34 | * @package GravityFormsIframe 35 | * @author Brady Vercher 36 | * @since 1.0.0 37 | */ 38 | class GravityFormsIframe { 39 | /** 40 | * Retrieve the main GravityFormsIframe_Addon instance. 41 | * 42 | * @since 1.0.0 43 | * 44 | * @return GravityFormsIframe 45 | */ 46 | public static function instance() { 47 | return gfiframe(); 48 | } 49 | 50 | /** 51 | * Constructor method to initialize the plugin. 52 | * 53 | * @since 1.0.0 54 | */ 55 | private function __construct() {} 56 | } 57 | -------------------------------------------------------------------------------- /includes/functions.php: -------------------------------------------------------------------------------- 1 | query_vars['gfiframe'] ) && ( 'gfembed' == $wp->query_vars['gfiframe'] || 'gfembed.php' == $wp->query_vars['gfiframe'] ); 24 | } 25 | 26 | /** 27 | * Retrieve the name of the highest priority template file that exists. 28 | * 29 | * Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which 30 | * inherit from a parent theme can just overload one file. Falls back to the 31 | * built-in template. 32 | * 33 | * @since 1.1.0 34 | * @see locate_template() 35 | * 36 | * @param string|array $template_names Template file(s) to search for, in order. 37 | * @param bool $load If true the template file will be loaded if it is found. 38 | * @param bool $require_once Whether to require_once or require. Default true. Has no effect if $load is false. 39 | * @return string The template path if one is located. 40 | */ 41 | function gfiframe_locate_template( $template_names, $load = false, $require_once = true ) { 42 | $template = ''; 43 | 44 | foreach ( (array) $template_names as $template_name ) { 45 | if ( ! $template_name ) { 46 | continue; 47 | } 48 | 49 | if ( file_exists( get_stylesheet_directory() . '/' . $template_name ) ) { 50 | $template = get_stylesheet_directory() . '/' . $template_name; 51 | break; 52 | } elseif ( file_exists( get_template_directory() . '/' . $template_name ) ) { 53 | $template = get_template_directory() . '/' . $template_name; 54 | break; 55 | } elseif ( file_exists( gfiframe()->get_path( 'templates/' . $template_name ) ) ) { 56 | $template = gfiframe()->get_path( 'templates/' . $template_name ); 57 | break; 58 | } 59 | } 60 | 61 | if ( $load && ! empty( $template ) ) { 62 | load_template( $template, $require_once ); 63 | } 64 | 65 | return $template; 66 | } 67 | -------------------------------------------------------------------------------- /languages/gravity-forms-iframe.pot: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Cedaro 2 | # This file is distributed under the GPL-2.0+. 3 | msgid "" 4 | msgstr "" 5 | "Project-Id-Version: Gravity Forms Iframe Add-on 2.0.5\n" 6 | "Report-Msgid-Bugs-To: " 7 | "https://wordpress.org/support/plugin/gravity-forms-iframe\n" 8 | "POT-Creation-Date: 2024-11-24 17:50:06+00:00\n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=utf-8\n" 11 | "Content-Transfer-Encoding: 8bit\n" 12 | "PO-Revision-Date: 2024-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "X-Generator: node-wp-i18n 1.2.7\n" 16 | 17 | #: classes/Addon.php:57 18 | msgid "Gravity Forms Iframe Add-On" 19 | msgstr "" 20 | 21 | #: classes/Addon.php:58 22 | msgid "Iframe" 23 | msgstr "" 24 | 25 | #: classes/Addon.php:104 26 | msgid "Iframe Settings" 27 | msgstr "" 28 | 29 | #: classes/Addon.php:108 30 | msgid "Enable embedding" 31 | msgstr "" 32 | 33 | #: classes/Addon.php:115 34 | msgid "Allow this form to be embedded in an iframe" 35 | msgstr "" 36 | 37 | #: classes/Addon.php:121 classes/Addon.php:128 38 | msgid "Display title" 39 | msgstr "" 40 | 41 | #: classes/Addon.php:134 classes/Addon.php:141 42 | msgid "Display description" 43 | msgstr "" 44 | 45 | #: classes/Addon.php:147 46 | msgid "Embed Code" 47 | msgstr "" 48 | 49 | #: classes/Plugin.php:87 50 | msgid "Invalid form id." 51 | msgstr "" 52 | 53 | #: classes/Plugin.php:95 54 | msgid "Embedding is disabled for this form." 55 | msgstr "" 56 | 57 | #. Plugin Name of the plugin/theme 58 | msgid "Gravity Forms Iframe Add-on" 59 | msgstr "" 60 | 61 | #. Plugin URI of the plugin/theme 62 | msgid "https://github.com/cedaro/gravity-forms-iframe" 63 | msgstr "" 64 | 65 | #. Description of the plugin/theme 66 | msgid "Easily embed Gravity Forms in an auto-resizing iframe on external sites." 67 | msgstr "" 68 | 69 | #. Author of the plugin/theme 70 | msgid "Cedaro" 71 | msgstr "" 72 | 73 | #. Author URI of the plugin/theme 74 | msgid "http://www.cedaro.com/" 75 | msgstr "" -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gravity-forms-iframe", 3 | "version": "2.0.5", 4 | "description": "A WordPress plugin to allow embedding Gravity Forms in auto-resizing iframes on external sites.", 5 | "license": "GPL-2.0+", 6 | "repository": "cedaro/gravity-forms-iframe", 7 | "scripts": { 8 | "build": "npm run lint && npm run uglify && npm run makepot", 9 | "lint": "jshint assets/scripts/*.js --exclude=assets/scripts/*.min.js", 10 | "makepot": "wpi18n makepot", 11 | "uglify": "uglifyjs assets/scripts/gfembed.js --compress --mangle --output assets/scripts/gfembed.min.js" 12 | }, 13 | "devDependencies": { 14 | "jshint": "^2.9.2", 15 | "node-wp-i18n": "github:cedaro/node-wp-i18n#develop", 16 | "uglify-js": "^3.19.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /screenshot-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cedaro/gravity-forms-iframe/acc77716abc8924189c0349664ee31e14852be71/screenshot-1.png -------------------------------------------------------------------------------- /templates/gravity-forms-iframe.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <?php echo esc_html( $form['title'] ); ?> 6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | --------------------------------------------------------------------------------