Plugin Directory

Changeset 3282645


Ignore:
Timestamp:
04/27/2025 09:35:29 AM (10 months ago)
Author:
contentpen
Message:

Release version 1.0.2: Added feature update post.

Location:
contentpen
Files:
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • contentpen/tags/1.0.2/README.txt

    r3266188 r3282645  
    44Requires at least: 5.8
    55Tested up to: 6.7
    6 Stable tag: 1.0.1
     6Stable tag: 1.0.2
    77Requires PHP: 7.4
    88License: GPLv2 or later
  • contentpen/tags/1.0.2/assets/css/contentpen.css

    r3266178 r3282645  
    22.contentpen-wrap {
    33  max-width: 800px;
    4   margin: 20px 20px 20px 0;
     4  margin: 40px auto;
    55}
    66
     
    1010  justify-content: space-between;
    1111  margin-bottom: 20px;
     12  padding: 24px;
    1213}
    1314
     
    2930.contentpen-box {
    3031  background: white;
    31   border-radius: 8px;
    32   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    33   padding: 24px;
     32  padding: 15px;
     33  border: 1px solid rgba(200, 215, 225, 0.5);
     34  text-align: center;
     35  border-radius: 0;
     36  box-shadow: none;
    3437}
    3538
    36 .box-header {
    37   margin-bottom: 24px;
    38   padding-bottom: 16px;
    39   border-bottom: 1px solid #e0e0e0;
     39.contentpen-box h2 {
     40  margin: 0 0 15px;
     41  font-size: 20px;
     42  font-weight: 500;
    4043}
    4144
    42 .box-header h2 {
    43   margin: 0 0 8px;
    44   font-size: 20px;
    45 }
    46 
    47 .box-header p {
    48   margin: 0;
     45.contentpen-box p {
     46  margin: 0 0 24px;
    4947  color: #666;
    5048}
     
    5856  margin-bottom: 8px;
    5957  font-weight: 500;
     58  text-align: left;
    6059}
    6160
     
    6766.input-group input {
    6867  flex: 1;
    69   padding: 8px 12px;
    70   border: 2px solid #ddd;
    71   border-radius: 4px;
     68  padding: 12px;
     69  border: 1px solid #ccc;
     70  border-radius: 0;
    7271  font-size: 14px;
    7372}
     
    8079.form-actions {
    8180  margin-top: 24px;
     81  text-align: right;
     82}
     83
     84.contentpen-settings-form .button-primary {
     85  margin-right: 0;
    8286}
    8387
     
    8892
    8993.help-links a {
    90   color: #1e88e5;
    91   text-decoration: none;
     94  color: #0073aa;
     95  text-decoration: underline;
    9296}
    9397
    9498.help-links .separator {
    95   margin: 0 8px;
    96   color: #ddd;
     99  display: none;
    97100}
    98101
     
    129132}
    130133
    131 /* Notice styling */
     134.contentpen-logo {
     135  display: block;
     136  margin: 0 auto 20px;
     137  max-width: 150px;
     138  height: auto;
     139}
     140
    132141.notice {
    133142  margin: 20px 0;
  • contentpen/tags/1.0.2/contentpen-plugin.php

    r3266188 r3282645  
    55 * Plugin URI: https://contentpen.ai
    66 * Description: Contentpen is an AI-powered content writing assistant designed to help businesses create, optimize, and publish SEO-friendly blog posts at scale. By combining deep research with your brand's unique voice, Contentpen crafts high-impact articles that outperform your competition.
    7  * Version: 1.0.1
     7 * Version: 1.0.2
    88 * Requires at least: 5.8
    99 * Requires PHP: 7.4
     
    2020}
    2121
    22 define('CONTENTPEN_VERSION', '1.0.0');
     22define('CONTENTPEN_VERSION', '1.0.2');
    2323define('CONTENTPEN_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2424define('CONTENTPEN_PLUGIN_URL', plugin_dir_url(__FILE__));
  • contentpen/tags/1.0.2/includes/class-contentpen-api.php

    r3266178 r3282645  
    3131    ));
    3232
     33    // Get Categories and Authors endpoint
     34    register_rest_route($this->namespace, '/categories_authors', array(
     35      'methods' => 'GET',
     36      'callback' => array($this, 'get_authors_and_categories'),
     37      'permission_callback' => array($this, 'check_api_key')
     38    ));
     39
    3340    // Get Authors endpoint
    3441    register_rest_route($this->namespace, '/authors', array(
     
    5865      'permission_callback' => array($this, 'check_api_key')
    5966    ));
     67
     68    // Update Post endpoint
     69    register_rest_route($this->namespace, '/posts/(?P<id>\d+)', array(
     70      'methods' => WP_REST_Server::EDITABLE, // PUT or PATCH
     71      'callback' => array($this, 'update_post'),
     72      'permission_callback' => array($this, 'check_api_key'),
     73      'args' => array(
     74        'id' => array(
     75          'validate_callback' => function ($param, $request, $key) {
     76            return is_numeric($param);
     77          }
     78        ),
     79      ),
     80    ));
    6081  }
    6182
     
    6485    return new WP_REST_Response(array(
    6586      'status' => 'success',
    66       'message' => 'API key is valid'
     87      'message' => 'API key is valid',
     88      'meta_data' => array(
     89        'site_name'      => get_bloginfo('name'),
     90        'site_url'       => get_site_url(),
     91        'wordpress_version' => get_bloginfo('version'),
     92      )
    6793    ), 200);
    6894  }
    6995
    70   public function get_authors($request)
     96  public function get_authors_and_categories($request)
     97  {
     98    $authors = $this->get_authors();
     99    $categories = $this->get_categories();
     100
     101    return new WP_REST_Response(array(
     102      'authors' => $authors,
     103      'categories' => $categories
     104    ), 200);
     105  }
     106
     107  public function get_authors($request = null)
    71108  {
    72109    $authors = get_users(array(
    73110      'who' => 'authors',
    74       'has_published_posts' => true,
    75111      'capability' => array('publish_posts', 'edit_posts')
    76112    ));
     
    89125      }
    90126    }
     127    if(!$request) {
     128      return $formatted_authors;
     129    }
    91130
    92131    return new WP_REST_Response($formatted_authors, 200);
    93132  }
    94133
    95   public function get_categories($request)
     134  public function get_categories($request = null)
    96135  {
    97136    $args = array(
     
    112151    }
    113152
     153    if(!$request) {
     154      return $formatted_categories;
     155    }
    114156    return new WP_REST_Response($formatted_categories, 200);
    115157  }
     
    164206    // Handle SEO metadata
    165207    if (!empty($params['meta_title'])) {
    166       add_post_meta($post_id, 'contentstudio_wpseo_title', sanitize_text_field($params['meta_title']), true);
     208      add_post_meta($post_id, 'contentpen_wpseo_title', sanitize_text_field($params['meta_title']), true);
    167209    }
    168210    if (!empty($params['meta_description'])) {
    169       add_post_meta($post_id, 'contentstudio_wpseo_description', sanitize_text_field($params['meta_description']), true);
     211      add_post_meta($post_id, 'contentpen_wpseo_description', sanitize_text_field($params['meta_description']), true);
    170212    }
    171213
     
    528570
    529571    if ($api_key !== $stored_key) {
    530       return new WP_Error('invalid_api_key', 'Invalid API key', array('status' => 403, 'api_key' => $stored_key));
     572      return new WP_Error('invalid_api_key', 'Invalid API key', array('status' => 403, 'headers' => $headers));
    531573    }
    532574
    533575    return true;
    534576  }
    535 }
     577
     578  /**
     579   * Callback for the /posts/{id} endpoint (PUT/PATCH method).
     580   * Updates an existing post.
     581   *
     582   * @param WP_REST_Request $request Full details about the request.
     583   * @return WP_REST_Response|WP_Error Response object on success, or WP_Error on failure.
     584   */
     585  public function update_post(WP_REST_Request $request)
     586  {
     587    $post_id = (int) $request['id'];
     588
     589    // Check if post exists
     590    $post = get_post($post_id);
     591    if (!$post) {
     592      return new WP_Error('post_not_found', 'Post not found.', array('status' => 404));
     593    }
     594
     595    $post_data = array(
     596      'ID' => $post_id,
     597    );
     598
     599    // Get parameters from the request and add them to post_data if they exist
     600    $params = $request->get_params();
     601
     602    if (isset($params['title'])) {
     603      $post_data['post_title'] = sanitize_text_field($params['title']);
     604    }
     605    if (isset($params['content'])) {
     606      $post_data['post_content'] = wp_kses_post($params['content']);
     607    }
     608    if (isset($params['status'])) {
     609      $post_data['post_status'] = sanitize_text_field($params['status']);
     610    }
     611    // Add more fields as needed (e.g., categories, tags, custom fields)
     612
     613    $updated_post_id = wp_update_post($post_data, true); // Pass true to return WP_Error on failure
     614
     615    if (is_wp_error($updated_post_id)) {
     616      // If wp_update_post returns 0, it means no changes were made or the post doesn't exist
     617      if ($updated_post_id->get_error_code() === 'invalid_post') {
     618        return new WP_Error('update_failed', 'Failed to update post. Invalid post ID or no changes detected.', array('status' => 400));
     619      }
     620      return $updated_post_id; // Return the WP_Error object
     621    }
     622
     623
     624    // Handle SEO metadata
     625    if (!empty($params['meta_title'])) {
     626      add_post_meta($post_id, 'contentpen_wpseo_title', sanitize_text_field($params['meta_title']), true);
     627    }
     628    if (!empty($params['meta_description'])) {
     629      add_post_meta($post_id, 'contentpen_wpseo_description', sanitize_text_field($params['meta_description']), true);
     630    }
     631
     632    // Set post slug
     633    $this->set_post_slug($post_id, isset($params['custom_slug']) ? $params['custom_slug'] : null);
     634
     635    // Handle Yoast SEO if active
     636    if ($this->is_yoast_active()) {
     637      $this->set_yoast_seo($post_id, $params);
     638    }
     639
     640    // Handle All in One SEO if active
     641    if ($this->is_all_in_one_seo_active()) {
     642      $this->set_all_in_one_seo($post_id, $params);
     643    }
     644
     645    // Handle featured image
     646    $image_response = array();
     647    if (!empty($params['featured_image'])) {
     648      $image_result = $this->set_featured_image($post_id, $params['featured_image'], $params['title']);
     649      if (!$image_result['status']) {
     650        $image_response = array(
     651          'warning_message' => $image_result['message']
     652        );
     653      }
     654    }
     655
     656
     657    // Optionally return the updated post data or just a success message
     658    $response_data = array(
     659      'message' => 'Post updated successfully.',
     660      'post_id' => $updated_post_id,
     661      'post_url' => get_permalink($updated_post_id),
     662      'image_response' => $image_response
     663    );
     664    return new WP_REST_Response($response_data, 200); // 200 OK status
     665  }
     666} // End class ContentPen_API
  • contentpen/tags/1.0.2/page.php

    r3266178 r3282645  
    105105?>
    106106    <div class="wrap contentpen-wrap">
    107       <div class="contentpen-header">
    108         <h1>ContentPen Settings</h1>
    109         <?php if ($has_api_key) : ?>
    110           <div class="api-status-badge">
    111             <span class="dashicons dashicons-yes-alt"></span> API Key Connected
    112           </div>
    113         <?php endif; ?>
    114       </div>
     107      <img src="<?php echo plugin_dir_url(__FILE__) . 'assets/icon-128x128.png'; ?>" alt="ContentPen Logo" class="contentpen-logo">
     108
     109
    115110
    116111      <div class="contentpen-box">
    117         <div class="box-header">
    118           <h2><?php echo $has_api_key ? 'Update API Key' : 'Connect Your Website'; ?></h2>
    119           <p><?php echo $has_api_key ? 'Your website is connected to ContentPen. You can update your API key below if needed.' : 'Enter your ContentPen API key to connect your website'; ?></p>
    120         </div>
     112        <h2><?php echo $has_api_key ? 'ContentPen' : 'Connect Website'; ?></h2>
     113
     114        <?php if (!$has_api_key) : ?>
     115          <p>Enter your Website API key to connect with ContentPen</p>
     116        <?php else : ?>
     117          <p>Your website is connected to ContentPen. You can update your API key below if needed.</p>
     118        <?php endif; ?>
    121119
    122120        <form method="post" action="options.php" class="contentpen-settings-form">
    123121          <?php settings_fields('contentpen_settings'); ?>
    124122          <div class="form-row">
    125             <label for="contentpen_api_key">API Key</label>
     123            <label for="contentpen_api_key">API Key:</label>
    126124            <div class="input-group">
    127125              <input type="text" id="contentpen_api_key" name="contentpen_api_key" placeholder="Enter your API key" value="<?php echo esc_attr($api_key); ?>" class="regular-text">
     
    139137            <div class="help-links">
    140138              <a href="https://contentpen.ai" target="_blank">Don't have an API key?</a>
    141               <span class="separator">|</span>
    142               <a href="https://docs.contentpen.ai" target="_blank">What is an API key?</a>
    143139            </div>
    144140          </div>
  • contentpen/trunk/README.txt

    r3266188 r3282645  
    44Requires at least: 5.8
    55Tested up to: 6.7
    6 Stable tag: 1.0.1
     6Stable tag: 1.0.2
    77Requires PHP: 7.4
    88License: GPLv2 or later
  • contentpen/trunk/assets/css/contentpen.css

    r3266178 r3282645  
    22.contentpen-wrap {
    33  max-width: 800px;
    4   margin: 20px 20px 20px 0;
     4  margin: 40px auto;
    55}
    66
     
    1010  justify-content: space-between;
    1111  margin-bottom: 20px;
     12  padding: 24px;
    1213}
    1314
     
    2930.contentpen-box {
    3031  background: white;
    31   border-radius: 8px;
    32   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
    33   padding: 24px;
     32  padding: 15px;
     33  border: 1px solid rgba(200, 215, 225, 0.5);
     34  text-align: center;
     35  border-radius: 0;
     36  box-shadow: none;
    3437}
    3538
    36 .box-header {
    37   margin-bottom: 24px;
    38   padding-bottom: 16px;
    39   border-bottom: 1px solid #e0e0e0;
     39.contentpen-box h2 {
     40  margin: 0 0 15px;
     41  font-size: 20px;
     42  font-weight: 500;
    4043}
    4144
    42 .box-header h2 {
    43   margin: 0 0 8px;
    44   font-size: 20px;
    45 }
    46 
    47 .box-header p {
    48   margin: 0;
     45.contentpen-box p {
     46  margin: 0 0 24px;
    4947  color: #666;
    5048}
     
    5856  margin-bottom: 8px;
    5957  font-weight: 500;
     58  text-align: left;
    6059}
    6160
     
    6766.input-group input {
    6867  flex: 1;
    69   padding: 8px 12px;
    70   border: 2px solid #ddd;
    71   border-radius: 4px;
     68  padding: 12px;
     69  border: 1px solid #ccc;
     70  border-radius: 0;
    7271  font-size: 14px;
    7372}
     
    8079.form-actions {
    8180  margin-top: 24px;
     81  text-align: right;
     82}
     83
     84.contentpen-settings-form .button-primary {
     85  margin-right: 0;
    8286}
    8387
     
    8892
    8993.help-links a {
    90   color: #1e88e5;
    91   text-decoration: none;
     94  color: #0073aa;
     95  text-decoration: underline;
    9296}
    9397
    9498.help-links .separator {
    95   margin: 0 8px;
    96   color: #ddd;
     99  display: none;
    97100}
    98101
     
    129132}
    130133
    131 /* Notice styling */
     134.contentpen-logo {
     135  display: block;
     136  margin: 0 auto 20px;
     137  max-width: 150px;
     138  height: auto;
     139}
     140
    132141.notice {
    133142  margin: 20px 0;
  • contentpen/trunk/contentpen-plugin.php

    r3266188 r3282645  
    55 * Plugin URI: https://contentpen.ai
    66 * Description: Contentpen is an AI-powered content writing assistant designed to help businesses create, optimize, and publish SEO-friendly blog posts at scale. By combining deep research with your brand's unique voice, Contentpen crafts high-impact articles that outperform your competition.
    7  * Version: 1.0.1
     7 * Version: 1.0.2
    88 * Requires at least: 5.8
    99 * Requires PHP: 7.4
     
    2020}
    2121
    22 define('CONTENTPEN_VERSION', '1.0.0');
     22define('CONTENTPEN_VERSION', '1.0.2');
    2323define('CONTENTPEN_PLUGIN_DIR', plugin_dir_path(__FILE__));
    2424define('CONTENTPEN_PLUGIN_URL', plugin_dir_url(__FILE__));
  • contentpen/trunk/includes/class-contentpen-api.php

    r3266178 r3282645  
    3131    ));
    3232
     33    // Get Categories and Authors endpoint
     34    register_rest_route($this->namespace, '/categories_authors', array(
     35      'methods' => 'GET',
     36      'callback' => array($this, 'get_authors_and_categories'),
     37      'permission_callback' => array($this, 'check_api_key')
     38    ));
     39
    3340    // Get Authors endpoint
    3441    register_rest_route($this->namespace, '/authors', array(
     
    5865      'permission_callback' => array($this, 'check_api_key')
    5966    ));
     67
     68    // Update Post endpoint
     69    register_rest_route($this->namespace, '/posts/(?P<id>\d+)', array(
     70      'methods' => WP_REST_Server::EDITABLE, // PUT or PATCH
     71      'callback' => array($this, 'update_post'),
     72      'permission_callback' => array($this, 'check_api_key'),
     73      'args' => array(
     74        'id' => array(
     75          'validate_callback' => function ($param, $request, $key) {
     76            return is_numeric($param);
     77          }
     78        ),
     79      ),
     80    ));
    6081  }
    6182
     
    6485    return new WP_REST_Response(array(
    6586      'status' => 'success',
    66       'message' => 'API key is valid'
     87      'message' => 'API key is valid',
     88      'meta_data' => array(
     89        'site_name'      => get_bloginfo('name'),
     90        'site_url'       => get_site_url(),
     91        'wordpress_version' => get_bloginfo('version'),
     92      )
    6793    ), 200);
    6894  }
    6995
    70   public function get_authors($request)
     96  public function get_authors_and_categories($request)
     97  {
     98    $authors = $this->get_authors();
     99    $categories = $this->get_categories();
     100
     101    return new WP_REST_Response(array(
     102      'authors' => $authors,
     103      'categories' => $categories
     104    ), 200);
     105  }
     106
     107  public function get_authors($request = null)
    71108  {
    72109    $authors = get_users(array(
    73110      'who' => 'authors',
    74       'has_published_posts' => true,
    75111      'capability' => array('publish_posts', 'edit_posts')
    76112    ));
     
    89125      }
    90126    }
     127    if(!$request) {
     128      return $formatted_authors;
     129    }
    91130
    92131    return new WP_REST_Response($formatted_authors, 200);
    93132  }
    94133
    95   public function get_categories($request)
     134  public function get_categories($request = null)
    96135  {
    97136    $args = array(
     
    112151    }
    113152
     153    if(!$request) {
     154      return $formatted_categories;
     155    }
    114156    return new WP_REST_Response($formatted_categories, 200);
    115157  }
     
    164206    // Handle SEO metadata
    165207    if (!empty($params['meta_title'])) {
    166       add_post_meta($post_id, 'contentstudio_wpseo_title', sanitize_text_field($params['meta_title']), true);
     208      add_post_meta($post_id, 'contentpen_wpseo_title', sanitize_text_field($params['meta_title']), true);
    167209    }
    168210    if (!empty($params['meta_description'])) {
    169       add_post_meta($post_id, 'contentstudio_wpseo_description', sanitize_text_field($params['meta_description']), true);
     211      add_post_meta($post_id, 'contentpen_wpseo_description', sanitize_text_field($params['meta_description']), true);
    170212    }
    171213
     
    528570
    529571    if ($api_key !== $stored_key) {
    530       return new WP_Error('invalid_api_key', 'Invalid API key', array('status' => 403, 'api_key' => $stored_key));
     572      return new WP_Error('invalid_api_key', 'Invalid API key', array('status' => 403, 'headers' => $headers));
    531573    }
    532574
    533575    return true;
    534576  }
    535 }
     577
     578  /**
     579   * Callback for the /posts/{id} endpoint (PUT/PATCH method).
     580   * Updates an existing post.
     581   *
     582   * @param WP_REST_Request $request Full details about the request.
     583   * @return WP_REST_Response|WP_Error Response object on success, or WP_Error on failure.
     584   */
     585  public function update_post(WP_REST_Request $request)
     586  {
     587    $post_id = (int) $request['id'];
     588
     589    // Check if post exists
     590    $post = get_post($post_id);
     591    if (!$post) {
     592      return new WP_Error('post_not_found', 'Post not found.', array('status' => 404));
     593    }
     594
     595    $post_data = array(
     596      'ID' => $post_id,
     597    );
     598
     599    // Get parameters from the request and add them to post_data if they exist
     600    $params = $request->get_params();
     601
     602    if (isset($params['title'])) {
     603      $post_data['post_title'] = sanitize_text_field($params['title']);
     604    }
     605    if (isset($params['content'])) {
     606      $post_data['post_content'] = wp_kses_post($params['content']);
     607    }
     608    if (isset($params['status'])) {
     609      $post_data['post_status'] = sanitize_text_field($params['status']);
     610    }
     611    // Add more fields as needed (e.g., categories, tags, custom fields)
     612
     613    $updated_post_id = wp_update_post($post_data, true); // Pass true to return WP_Error on failure
     614
     615    if (is_wp_error($updated_post_id)) {
     616      // If wp_update_post returns 0, it means no changes were made or the post doesn't exist
     617      if ($updated_post_id->get_error_code() === 'invalid_post') {
     618        return new WP_Error('update_failed', 'Failed to update post. Invalid post ID or no changes detected.', array('status' => 400));
     619      }
     620      return $updated_post_id; // Return the WP_Error object
     621    }
     622
     623
     624    // Handle SEO metadata
     625    if (!empty($params['meta_title'])) {
     626      add_post_meta($post_id, 'contentpen_wpseo_title', sanitize_text_field($params['meta_title']), true);
     627    }
     628    if (!empty($params['meta_description'])) {
     629      add_post_meta($post_id, 'contentpen_wpseo_description', sanitize_text_field($params['meta_description']), true);
     630    }
     631
     632    // Set post slug
     633    $this->set_post_slug($post_id, isset($params['custom_slug']) ? $params['custom_slug'] : null);
     634
     635    // Handle Yoast SEO if active
     636    if ($this->is_yoast_active()) {
     637      $this->set_yoast_seo($post_id, $params);
     638    }
     639
     640    // Handle All in One SEO if active
     641    if ($this->is_all_in_one_seo_active()) {
     642      $this->set_all_in_one_seo($post_id, $params);
     643    }
     644
     645    // Handle featured image
     646    $image_response = array();
     647    if (!empty($params['featured_image'])) {
     648      $image_result = $this->set_featured_image($post_id, $params['featured_image'], $params['title']);
     649      if (!$image_result['status']) {
     650        $image_response = array(
     651          'warning_message' => $image_result['message']
     652        );
     653      }
     654    }
     655
     656
     657    // Optionally return the updated post data or just a success message
     658    $response_data = array(
     659      'message' => 'Post updated successfully.',
     660      'post_id' => $updated_post_id,
     661      'post_url' => get_permalink($updated_post_id),
     662      'image_response' => $image_response
     663    );
     664    return new WP_REST_Response($response_data, 200); // 200 OK status
     665  }
     666} // End class ContentPen_API
  • contentpen/trunk/page.php

    r3266178 r3282645  
    105105?>
    106106    <div class="wrap contentpen-wrap">
    107       <div class="contentpen-header">
    108         <h1>ContentPen Settings</h1>
    109         <?php if ($has_api_key) : ?>
    110           <div class="api-status-badge">
    111             <span class="dashicons dashicons-yes-alt"></span> API Key Connected
    112           </div>
    113         <?php endif; ?>
    114       </div>
     107      <img src="<?php echo plugin_dir_url(__FILE__) . 'assets/icon-128x128.png'; ?>" alt="ContentPen Logo" class="contentpen-logo">
     108
     109
    115110
    116111      <div class="contentpen-box">
    117         <div class="box-header">
    118           <h2><?php echo $has_api_key ? 'Update API Key' : 'Connect Your Website'; ?></h2>
    119           <p><?php echo $has_api_key ? 'Your website is connected to ContentPen. You can update your API key below if needed.' : 'Enter your ContentPen API key to connect your website'; ?></p>
    120         </div>
     112        <h2><?php echo $has_api_key ? 'ContentPen' : 'Connect Website'; ?></h2>
     113
     114        <?php if (!$has_api_key) : ?>
     115          <p>Enter your Website API key to connect with ContentPen</p>
     116        <?php else : ?>
     117          <p>Your website is connected to ContentPen. You can update your API key below if needed.</p>
     118        <?php endif; ?>
    121119
    122120        <form method="post" action="options.php" class="contentpen-settings-form">
    123121          <?php settings_fields('contentpen_settings'); ?>
    124122          <div class="form-row">
    125             <label for="contentpen_api_key">API Key</label>
     123            <label for="contentpen_api_key">API Key:</label>
    126124            <div class="input-group">
    127125              <input type="text" id="contentpen_api_key" name="contentpen_api_key" placeholder="Enter your API key" value="<?php echo esc_attr($api_key); ?>" class="regular-text">
     
    139137            <div class="help-links">
    140138              <a href="https://contentpen.ai" target="_blank">Don't have an API key?</a>
    141               <span class="separator">|</span>
    142               <a href="https://docs.contentpen.ai" target="_blank">What is an API key?</a>
    143139            </div>
    144140          </div>
Note: See TracChangeset for help on using the changeset viewer.