示例#1
0
    /**
     * Print the content of the "No tables found" post meta box
     *
     * @since 1.0.0
     */
    public function postbox_no_tables($data, $box)
    {
        $add_url = TablePress::url(array('action' => 'add'));
        $import_url = TablePress::url(array('action' => 'import'));
        ?>
		<p><?php 
        _e('No tables found.', 'tablepress');
        ?>
</p>
		<p><?php 
        printf(__('You should <a href="%s">add</a> or <a href="%s">import</a> a table to get started!', 'tablepress'), $add_url, $import_url);
        ?>
</p>
		<?php 
    }
示例#2
0
    /**
     * Print a notification about a corrupted table
     *
     * @since 1.4.0
     */
    public function textbox_corrupted_table($data, $box)
    {
        ?>
		<div class="error">
			<p><strong><?php 
        _e('Attention: Unfortunately, an error occured.', 'tablepress');
        ?>
</strong></p>
			<p>
				<?php 
        printf(__('The internal data of table &#8220;%1$s&#8221 (ID %2$s) is corrupted.', 'tablepress'), esc_html($data['table']['name']), esc_html($data['table']['id']));
        echo ' ';
        printf(__('The following error was registered: <code>%s</code>.', 'tablepress'), esc_html($data['table']['json_error']));
        ?>
			</p>
			<p>
				<?php 
        _e('Because of this error, the table can not be edited at this time, to prevent possible further data loss.', 'tablepress');
        echo ' ';
        printf(__('Please see the <a href="%s">TablePress FAQ page</a> for further instructions.', 'tablepress'), 'http://tablepress.org/faq/corrupted-tables/');
        ?>
			</p>
			<p>
				<?php 
        echo '<a href="' . TablePress::url(array('action' => 'list')) . '" class="button">' . __('Back to the List of Tables', 'tablepress') . '</a>';
        ?>
			</p>
		</div>
		<?php 
    }
示例#3
0
 /**
  * Holds the message to be displayed when there are no items in the table
  *
  * @since 1.0.0
  */
 public function no_items()
 {
     _e('No tables found.', 'tablepress');
     if (0 === $this->items_count) {
         $user_can_add_tables = current_user_can('tablepress_add_tables');
         $user_can_import_tables = current_user_can('tablepress_import_tables');
         $add_url = TablePress::url(array('action' => 'add'));
         $import_url = TablePress::url(array('action' => 'import'));
         if ($user_can_add_tables && $user_can_import_tables) {
             echo ' ' . sprintf(__('You should <a href="%s">add</a> or <a href="%s">import</a> a table to get started!', 'tablepress'), $add_url, $import_url);
         } elseif ($user_can_add_tables) {
             echo ' ' . sprintf(__('You should <a href="%s">add</a> a table to get started!', 'tablepress'), $add_url);
         } elseif ($user_can_import_tables) {
             echo ' ' . sprintf(__('You should <a href="%s">import</a> a table to get started!', 'tablepress'), $import_url);
         }
     }
 }
 /**
  * Handle Shortcode [table id=<ID> /] in the_content()
  *
  * @since 1.0.0
  *
  * @param array $shortcode_atts List of attributes that where included in the Shortcode
  * @return string Resulting HTML code for the table with the ID <ID>
  */
 public function shortcode_table($shortcode_atts)
 {
     // For empty Shortcodes like [table] or [table /], an empty string is passed, see Core #26927
     $shortcode_atts = (array) $shortcode_atts;
     $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
     $default_shortcode_atts = $_render->get_default_render_options();
     /**
      * Filter the available/default attributes for the [table] Shortcode.
      *
      * @since 1.0.0
      *
      * @param array $default_shortcode_atts The [table] Shortcode default attributes.
      */
     $default_shortcode_atts = apply_filters('tablepress_shortcode_table_default_shortcode_atts', $default_shortcode_atts);
     // parse Shortcode attributes, only allow those that are specified
     $shortcode_atts = shortcode_atts($default_shortcode_atts, $shortcode_atts);
     // Optional third argument left out on purpose. Use filter in the next line instead.
     /**
      * Filter the attributes that were passed to the [table] Shortcode.
      *
      * @since 1.0.0
      *
      * @param array $shortcode_atts The attributes passed to the [table] Shortcode.
      */
     $shortcode_atts = apply_filters('tablepress_shortcode_table_shortcode_atts', $shortcode_atts);
     // check, if a table with the given ID exists
     $table_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id']);
     if (!TablePress::$model_table->table_exists($table_id)) {
         $message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
         /**
          * Filter the "Table not found" message.
          *
          * @since 1.0.0
          *
          * @param string $message  The "Table not found" message.
          * @param string $table_id The current table ID.
          */
         $message = apply_filters('tablepress_table_not_found_message', $message, $table_id);
         return $message;
     }
     // load the table
     $table = TablePress::$model_table->load($table_id, true, true);
     // Load table, with table data, options, and visibility settings
     if (is_wp_error($table)) {
         $message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
         /**
          * Filter the "Table could not be loaded" message.
          *
          * @since 1.0.0
          *
          * @param string   $message  The "Table could not be loaded" message.
          * @param string   $table_id The current table ID.
          * @param WP_Error $table    The error object for the table.
          */
         $message = apply_filters('tablepress_table_load_error_message', $message, $table_id, $table);
         return $message;
     }
     if (isset($table['is_corrupted']) && $table['is_corrupted']) {
         $message = "<div>Attention: The internal data of table &#8220;{$table_id}&#8221; is corrupted!</div>";
         /**
          * Filter the "Table data is corrupted" message.
          *
          * @since 1.0.0
          *
          * @param string $message    The "Table data is corrupted" message.
          * @param string $table_id   The current table ID.
          * @param string $json_error The JSON error with information about the corrupted table.
          */
         $message = apply_filters('tablepress_table_corrupted_message', $message, $table_id, $table['json_error']);
         return $message;
     }
     /**
      * Filter whether the "datatables_custom_commands" Shortcode parameter is disabled.
      *
      * By default, the "datatables_custom_commands" Shortcode parameter is disabled for security reasons.
      *
      * @since 1.0.0
      *
      * @param bool $disable Whether to disable the "datatables_custom_commands" Shortcode parameter. Default true.
      */
     if (!is_null($shortcode_atts['datatables_custom_commands']) && apply_filters('tablepress_disable_custom_commands_shortcode_parameter', true)) {
         $shortcode_atts['datatables_custom_commands'] = null;
     }
     // determine options to use (if set in Shortcode, use those, otherwise use stored options, i.e. "Edit Table" screen)
     $render_options = array();
     foreach ($shortcode_atts as $key => $value) {
         // have to check this, because strings 'true' or 'false' are not recognized as boolean!
         if ('true' == strtolower($value)) {
             $render_options[$key] = true;
         } elseif ('false' == strtolower($value)) {
             $render_options[$key] = false;
         } elseif (is_null($value) && isset($table['options'][$key])) {
             $render_options[$key] = $table['options'][$key];
         } else {
             $render_options[$key] = $value;
         }
     }
     // generate unique HTML ID, depending on how often this table has already been shown on this page
     if (!isset($this->shown_tables[$table_id])) {
         $this->shown_tables[$table_id] = array('count' => 0, 'instances' => array());
     }
     $this->shown_tables[$table_id]['count']++;
     $count = $this->shown_tables[$table_id]['count'];
     $render_options['html_id'] = "tablepress-{$table_id}";
     if ($count > 1) {
         $render_options['html_id'] .= "-no-{$count}";
     }
     /**
      * Filter the ID of the table HTML element.
      *
      * @since 1.0.0
      *
      * @param string $html_id  The ID of the table HTML element.
      * @param string $table_id The current table ID.
      * @param string $count    Number of copies of the table with this table ID on the page.
      */
     $render_options['html_id'] = apply_filters('tablepress_html_id', $render_options['html_id'], $table_id, $count);
     // generate "Edit Table" link
     $render_options['edit_table_url'] = '';
     /**
      * Filter whether the "Edit" link below the table shall be shown.
      *
      * The "Edit" link is only shown to logged-in users who possess the necessary capability to edit the table.
      *
      * @since 1.0.0
      *
      * @param bool   $show     Whether to show the "Edit" link below the table. Default true.
      * @param string $table_id The current table ID.
      */
     if (is_user_logged_in() && apply_filters('tablepress_edit_link_below_table', true, $table['id']) && current_user_can('tablepress_edit_table', $table['id'])) {
         $render_options['edit_table_url'] = TablePress::url(array('action' => 'edit', 'table_id' => $table['id']));
     }
     /**
      * Filter the render options for the table.
      *
      * The render options are determined from the settings on a table's "Edit" screen and the Shortcode parameters.
      *
      * @since 1.0.0
      *
      * @param array $render_options The render options for the table.
      * @param array $table          The current table.
      */
     $render_options = apply_filters('tablepress_table_render_options', $render_options, $table);
     // eventually add this table to list of tables which have a JS library enabled and thus are to be included in the script's call in the footer
     if ($render_options['use_datatables'] && $render_options['table_head'] && count($table['data']) > 1) {
         // get options for the DataTables JavaScript library from the table's render options
         $js_options = array();
         foreach (array('alternating_row_colors', 'datatables_sort', 'datatables_paginate', 'datatables_paginate', 'datatables_paginate_entries', 'datatables_lengthchange', 'datatables_filter', 'datatables_info', 'datatables_scrollx', 'datatables_scrolly', 'datatables_locale', 'datatables_custom_commands') as $option) {
             $js_options[$option] = $render_options[$option];
         }
         /**
          * Filter the JavaScript options for the table.
          *
          * The JavaScript options are determined from the settings on a table's "Edit" screen and the Shortcode parameters.
          * They are part of the render options and can be overwritten with Shortcode parameters.
          *
          * @since 1.0.0
          *
          * @param array  $js_options     The JavaScript options for the table.
          * @param string $table_id       The current table ID.
          * @param array  $render_options The render options for the table.
          */
         $js_options = apply_filters('tablepress_table_js_options', $js_options, $table_id, $render_options);
         $this->shown_tables[$table_id]['instances'][$render_options['html_id']] = $js_options;
         $this->_enqueue_datatables();
     }
     // check if table output shall and can be loaded from the transient cache, otherwise generate the output
     if ($render_options['cache_table_output'] && !is_user_logged_in()) {
         $table_hash = md5(json_encode($render_options));
         // hash the Render Options array to get a unique cache identifier
         $transient_name = 'tablepress_' . $table_hash;
         // Attention: This string must not be longer than 45 characters!
         $output = get_transient($transient_name);
         if (false === $output || '' == $output) {
             // render/generate the table HTML, as it was not found in the cache
             $_render->set_input($table, $render_options);
             $output = $_render->get_output();
             // save output to a transient
             set_transient($transient_name, $output, DAY_IN_SECONDS);
             // store $output in a transient, set cache timeout to 24 hours
             // update output caches list transient (necessary for cache invalidation upon table saving)
             $caches_list_transient_name = 'tablepress_c_' . md5($table_id);
             $caches_list = get_transient($caches_list_transient_name);
             if (false === $caches_list) {
                 $caches_list = array();
             } else {
                 $caches_list = json_decode($caches_list, true);
             }
             if (!in_array($transient_name, $caches_list, true)) {
                 $caches_list[] = $transient_name;
             }
             set_transient($caches_list_transient_name, json_encode($caches_list), 2 * DAY_IN_SECONDS);
         } else {
             /**
              * Filter the cache hit comment message.
              *
              * @since 1.0.0
              *
              * @param string $comment The cache hit comment message.
              */
             $output .= apply_filters('tablepress_cache_hit_comment', "<!-- #{$render_options['html_id']} from cache -->");
         }
     } else {
         // render/generate the table HTML, as no cache is to be used
         $_render->set_input($table, $render_options);
         $output = $_render->get_output();
     }
     // Maybe print a list of used render options
     if ($render_options['shortcode_debug'] && is_user_logged_in()) {
         $output .= '<pre>' . var_export($render_options, true) . '</pre>';
     }
     return $output;
 }
示例#5
0
    /**
     * Render the navigation menu with links to the possible actions, highlighting the current one.
     *
     * @since 1.0.0
     */
    protected function print_nav_tab_menu()
    {
        ?>
		<h1 id="tablepress-nav" class="nav-tab-wrapper">
			<?php 
        echo '<span class="plugin-name">' . __('TablePress', 'tablepress') . '</span><span class="separator"></span>';
        foreach ($this->data['view_actions'] as $action => $entry) {
            // Special case: Add a separator before the group that starts with "Plugin Options", for some spacing.
            if ('options' === $action) {
                echo '<span class="separator"></span><span class="separator"></span>';
            }
            if ('' === $entry['nav_tab_title']) {
                continue;
            }
            if (!current_user_can($entry['required_cap'])) {
                continue;
            }
            $url = esc_url(TablePress::url(array('action' => $action)));
            $active = $action === $this->action ? ' nav-tab-active' : '';
            echo "<a class=\"nav-tab{$active}\" href=\"{$url}\">{$entry['nav_tab_title']}</a>";
        }
        ?>
		</h1>
		<?php 
    }
示例#6
0
 /**
  * Test that the screen URLs for toplevel admin menu entries are correct.
  *
  * @since 1.1.0
  */
 public function test_url_toplevel()
 {
     TablePress::$controller->is_top_level_page = true;
     TablePress::$controller->parent_page = 'middle';
     $this->assertSame('http://example.org/wp-admin/admin.php?page=tablepress', TablePress::url());
     $this->assertSame('http://example.org/wp-admin/admin.php?page=tablepress', TablePress::url(array(), false));
 }
    /**
     * Print the content of the "Cancel Saving" text box.
     *
     * @since 1.0.0
     *
     * @param array $data Data for this screen.
     * @param array $box  Information about the text box.
     */
    public function textbox_proceed_no_file_saving(array $data, array $box)
    {
        ?>
		<h3><?php 
        _e('Proceed without saving a file', 'tablepress');
        ?>
</h3>
		<p>
			<?php 
        _e('To proceed without trying to save the &#8220;Custom CSS&#8221; to a file, click the button below.', 'tablepress');
        ?>
			<?php 
        _e('Your &#8220;Custom CSS&#8221; will then be loaded inline.', 'tablepress');
        ?>
		</p><p>
			<a href="<?php 
        echo TablePress::url(array('action' => 'options', 'message' => 'success_save_error_custom_css'));
        ?>
" class="button button-large"><?php 
        _e('Proceed without saving &#8220;Custom CSS&#8221; to a file', 'tablepress');
        ?>
</a>
		</p>
		<?php 
    }
 /**
  * Copy a table.
  *
  * @since 1.0.0
  */
 public function handle_get_action_copy_table()
 {
     $table_id = !empty($_GET['item']) ? $_GET['item'] : false;
     TablePress::check_nonce('copy_table', $table_id);
     $return = !empty($_GET['return']) ? $_GET['return'] : 'list';
     $return_item = !empty($_GET['return_item']) ? $_GET['return_item'] : false;
     // Nonce check should actually catch this already.
     if (false === $table_id) {
         TablePress::redirect(array('action' => $return, 'message' => 'error_copy', 'table_id' => $return_item));
     }
     if (!current_user_can('tablepress_copy_table', $table_id)) {
         wp_die(__('You do not have sufficient permissions to access this page.', 'default'), 403);
     }
     $this->init_i18n_support();
     // for the translation of "Copy of".
     $copy_table_id = TablePress::$model_table->copy($table_id);
     if (is_wp_error($copy_table_id)) {
         TablePress::redirect(array('action' => $return, 'message' => 'error_copy', 'table_id' => $return_item));
     } else {
         $return_item = $copy_table_id;
     }
     /*
      * Slightly more complex redirect method, to account for sort, search, and pagination in the WP_List_Table on the List View,
      * but only if this action succeeds, to have everything fresh in the event of an error.
      */
     $sendback = wp_get_referer();
     if (!$sendback) {
         $sendback = TablePress::url(array('action' => $return, 'message' => 'success_copy', 'table_id' => $return_item));
     } else {
         $sendback = remove_query_arg(array('action', 'message', 'table_id'), $sendback);
         $sendback = add_query_arg(array('action' => $return, 'message' => 'success_copy', 'table_id' => $return_item), $sendback);
     }
     wp_redirect($sendback);
     exit;
 }
示例#9
0
    /**
     * Print the content of the "Admin Options" post meta box.
     *
     * @since 1.0.0
     *
     * @param array $data Data for this screen.
     * @param array $box  Information about the text box.
     */
    public function textbox_uninstall_tablepress(array $data, array $box)
    {
        ?>
		<h1 style="margin-top:40px;"><?php 
        _e('Uninstall TablePress', 'tablepress');
        ?>
</h1>
		<p><?php 
        echo __('Uninstalling <strong>will permanently delete</strong> all TablePress tables and options from the database.', 'tablepress') . '<br />' . __('It is recommended that you create a backup of the tables (by exporting the tables in the JSON format), in case you later change your mind.', 'tablepress') . '<br />' . __('You will manually need to remove the plugin&#8217;s files from the plugin folder afterwards.', 'tablepress') . '<br />' . __('Be very careful with this and only click the button if you know what you are doing!', 'tablepress');
        ?>
</p>
		<p><a href="<?php 
        echo TablePress::url(array('action' => 'uninstall_tablepress'), true, 'admin-post.php');
        ?>
" id="uninstall-tablepress" class="button"><?php 
        _e('Uninstall TablePress', 'tablepress');
        ?>
</a></p>
		<?php 
    }
 /**
  * Handle Shortcode [table id=<ID> /] in the_content()
  *
  * @since 1.0.0
  *
  * @param array $shortcode_atts List of attributes that where included in the Shortcode
  * @return string Resulting HTML code for the table with the ID <ID>
  */
 public function shortcode_table($shortcode_atts)
 {
     $_render = TablePress::load_class('TablePress_Render', 'class-render.php', 'classes');
     $default_shortcode_atts = $_render->get_default_render_options();
     $default_shortcode_atts = apply_filters('tablepress_shortcode_table_default_shortcode_atts', $default_shortcode_atts);
     // parse Shortcode attributes, only allow those that are specified
     $shortcode_atts = shortcode_atts($default_shortcode_atts, $shortcode_atts);
     $shortcode_atts = apply_filters('tablepress_shortcode_table_shortcode_atts', $shortcode_atts);
     // check, if a table with the given ID exists
     $table_id = preg_replace('/[^a-zA-Z0-9_-]/', '', $shortcode_atts['id']);
     if (!$this->model_table->table_exists($table_id)) {
         $message = "[table &#8220;{$table_id}&#8221; not found /]<br />\n";
         $message = apply_filters('tablepress_table_not_found_message', $message, $table_id);
         return $message;
     }
     // load the table
     $table = $this->model_table->load($table_id);
     if (false === $table) {
         $message = "[table &#8220;{$table_id}&#8221; could not be loaded /]<br />\n";
         $message = apply_filters('tablepress_table_load_error_message', $message, $table_id);
         return $message;
     }
     // Disable the "datatables_custom_commands" Shortcode parameter by default, for security reasons
     if (!is_null($shortcode_atts['datatables_custom_commands']) && apply_filters('tablepress_disable_custom_commands_shortcode_parameter', true)) {
         $shortcode_atts['datatables_custom_commands'] = null;
     }
     // determine options to use (if set in Shortcode, use those, otherwise use stored options, i.e. "Edit Table" screen)
     $render_options = array();
     foreach ($shortcode_atts as $key => $value) {
         // have to check this, because strings 'true' or 'false' are not recognized as boolean!
         if ('true' == strtolower($value)) {
             $render_options[$key] = true;
         } elseif ('false' == strtolower($value)) {
             $render_options[$key] = false;
         } elseif (is_null($value) && isset($table['options'][$key])) {
             $render_options[$key] = $table['options'][$key];
         } else {
             $render_options[$key] = $value;
         }
     }
     // generate unique HTML ID, depending on how often this table has already been shown on this page
     if (!isset($this->shown_tables[$table_id])) {
         $this->shown_tables[$table_id] = array('count' => 0, 'instances' => array());
     }
     $this->shown_tables[$table_id]['count']++;
     $count = $this->shown_tables[$table_id]['count'];
     $render_options['html_id'] = "tablepress-{$table_id}";
     if ($count > 1) {
         $render_options['html_id'] .= "-no-{$count}";
     }
     $render_options['html_id'] = apply_filters('tablepress_html_id', $render_options['html_id'], $table_id, $count);
     // generate "Edit Table" link
     $render_options['edit_table_url'] = '';
     if (is_user_logged_in() && apply_filters('tablepress_edit_link_below_table', true) && current_user_can('tablepress_edit_table', $table['id'])) {
         $render_options['edit_table_url'] = TablePress::url(array('action' => 'edit', 'table_id' => $table['id']));
     }
     $render_options = apply_filters('tablepress_table_render_options', $render_options, $table);
     // eventually add this table to list of tables which have a JS library enabled and thus are to be included in the script's call in the footer
     if ($render_options['use_datatables'] && $render_options['table_head'] && count($table['data']) > 1) {
         // get options for the DataTables JavaScript library from the table's render options
         $js_options = array();
         foreach (array('alternating_row_colors', 'datatables_sort', 'datatables_paginate', 'datatables_paginate', 'datatables_paginate_entries', 'datatables_lengthchange', 'datatables_filter', 'datatables_info', 'datatables_scrollx', 'datatables_scrolly', 'datatables_locale', 'datatables_custom_commands') as $option) {
             $js_options[$option] = $render_options[$option];
         }
         $js_options = apply_filters('tablepress_table_js_options', $js_options, $table_id, $render_options);
         // need this filter to e.g. set JS parameters depending on Shortcode attributes
         $this->shown_tables[$table_id]['instances'][$render_options['html_id']] = $js_options;
         $this->_enqueue_datatables();
     }
     // check if table output shall and can be loaded from the transient cache, otherwise generate the output
     if ($render_options['cache_table_output'] && !is_user_logged_in()) {
         $table_hash = md5(json_encode($render_options));
         // hash the Render Options array to get a unique cache identifier
         $transient_name = 'tablepress_' . $table_hash;
         // Attention: This string must not be longer than 45 characters!
         $output = get_transient($transient_name);
         if (false === $output || '' == $output) {
             // render/generate the table HTML, as it was not found in the cache
             $_render->set_input($table, $render_options);
             $output = $_render->get_output();
             // save output to a transient
             set_transient($transient_name, $output, DAY_IN_SECONDS);
             // store $output in a transient, set cache timeout to 24 hours
             // update output caches list transient (necessary for cache invalidation upon table saving)
             $caches_list_transient_name = 'tablepress_c_' . md5($table_id);
             $caches_list = get_transient($caches_list_transient_name);
             if (false === $caches_list) {
                 $caches_list = array();
             } else {
                 $caches_list = json_decode($caches_list, true);
             }
             if (!in_array($transient_name, $caches_list, true)) {
                 $caches_list[] = $transient_name;
             }
             set_transient($caches_list_transient_name, json_encode($caches_list), 2 * DAY_IN_SECONDS);
         } else {
             $output .= apply_filters('tablepress_cache_hit_comment', "<!-- #{$render_options['html_id']} from cache -->");
         }
     } else {
         // render/generate the table HTML, as no cache is to be used
         $_render->set_input($table, $render_options);
         $output = $_render->get_output();
     }
     return $output;
 }
示例#11
0
    /**
     * Print the content of the "Table Options" post meta box
     *
     * @since 1.0.0
     */
    public function postbox_table_options($data, $box)
    {
        $options = $data['table']['options'];
        ?>
<table class="tablepress-postbox-table fixed">
<tbody>
	<tr>
		<th class="column-1" scope="row"><?php 
        _e('Table Head Row', 'tablepress');
        ?>
:</th>
		<td class="column-2"><label for="option-table-head"><input type="checkbox" id="option-table-head" name="table[options][table_head]" value="true"<?php 
        checked($options['table_head']);
        ?>
 /> <?php 
        _e('The first row of the table is the table header.', 'tablepress');
        ?>
</label></td>
	</tr>
	<tr class="bottom-border">
		<th class="column-1" scope="row"><?php 
        _e('Table Foot Row', 'tablepress');
        ?>
:</th>
		<td class="column-2"><label for="option-table-foot"><input type="checkbox" id="option-table-foot" name="table[options][table_foot]" value="true"<?php 
        checked($options['table_foot']);
        ?>
 /> <?php 
        _e('The last row of the table is the table footer.', 'tablepress');
        ?>
</label></td>
	</tr>
	<tr class="top-border">
		<th class="column-1" scope="row"><?php 
        _e('Alternating Row Colors', 'tablepress');
        ?>
:</th>
		<td class="column-2"><label for="option-alternating-row-colors"><input type="checkbox" id="option-alternating-row-colors" name="table[options][alternating_row_colors]" value="true"<?php 
        checked($options['alternating_row_colors']);
        ?>
 /> <?php 
        _e('The background colors of consecutive rows shall alternate.', 'tablepress');
        ?>
</label></td>
	</tr>
	<tr class="bottom-border">
		<th class="column-1" scope="row"><?php 
        _e('Row Hover Highlighting', 'tablepress');
        ?>
:</th>
		<td class="column-2"><label for="option-row-hover"><input type="checkbox" id="option-row-hover" name="table[options][row_hover]" value="true"<?php 
        checked($options['row_hover']);
        ?>
 /> <?php 
        _e('Highlight a row while the mouse cursor hovers above it by changing its background color.', 'tablepress');
        ?>
</label></td>
	</tr>
	<tr class="top-border">
		<th class="column-1" scope="row"><?php 
        _e('Print Table Name', 'tablepress');
        ?>
:</th>
		<?php 
        $position_select = '<select id="option-print-name-position" name="table[options][print_name_position]">';
        $position_select .= '<option' . selected('above', $options['print_name_position'], false) . ' value="above">' . __('above', 'tablepress') . '</option>';
        $position_select .= '<option' . selected('below', $options['print_name_position'], false) . ' value="below">' . __('below', 'tablepress') . '</option>';
        $position_select .= '</select>';
        ?>
		<td class="column-2"><input type="checkbox" id="option-print-name" name="table[options][print_name]" value="true"<?php 
        checked($options['print_name']);
        ?>
 /> <?php 
        printf(__('The table name shall be written %s the table.', 'tablepress'), $position_select);
        ?>
</td>
	</tr>
	<tr class="bottom-border">
		<th class="column-1" scope="row"><?php 
        _e('Print Table Description', 'tablepress');
        ?>
:</th>
		<?php 
        $position_select = '<select id="option-print-description-position" name="table[options][print_description_position]">';
        $position_select .= '<option' . selected('above', $options['print_description_position'], false) . ' value="above">' . __('above', 'tablepress') . '</option>';
        $position_select .= '<option' . selected('below', $options['print_description_position'], false) . ' value="below">' . __('below', 'tablepress') . '</option>';
        $position_select .= '</select>';
        ?>
		<td class="column-2"><input type="checkbox" id="option-print-description" name="table[options][print_description]" value="true"<?php 
        checked($options['print_description']);
        ?>
 /> <?php 
        printf(__('The table description shall be written %s the table.', 'tablepress'), $position_select);
        ?>
</td>
	</tr>
	<tr class="top-border">
		<th class="column-1" scope="row"><?php 
        _e('Extra CSS Classes', 'tablepress');
        ?>
:</th>
		<td class="column-2"><label for="option-extra-css-classes"><input type="text" id="option-extra-css-classes" class="large-text" name="table[options][extra_css_classes]" value="<?php 
        echo esc_attr($options['extra_css_classes']);
        ?>
" title="<?php 
        esc_attr_e('This field can only contain letters, numbers, spaces, hyphens (-), and underscores (_).', 'tablepress');
        ?>
" pattern="[A-Za-z0-9- _]*" /><p class="description"><?php 
        echo __('Additional CSS classes for styling purposes can be entered here.', 'tablepress') . ' ' . sprintf(__('This is NOT the place to enter <a href="%s">Custom CSS</a> code!', 'tablepress'), TablePress::url(array('action' => 'options')));
        ?>
</p></label></td>
	</tr>
</tbody>
</table>
<?php 
    }