{"id":96,"date":"2024-11-15T02:45:15","date_gmt":"2024-11-15T02:45:15","guid":{"rendered":"https:\/\/rhwbaldwin.com\/blog\/?p=96"},"modified":"2024-12-07T20:27:20","modified_gmt":"2024-12-07T20:27:20","slug":"leveraging-cloving-clis-chat-feature-to-build-a-rails-react-and-ai-powered-micro-app","status":"publish","type":"post","link":"https:\/\/rhwbaldwin.com\/blog\/2024\/11\/15\/leveraging-cloving-clis-chat-feature-to-build-a-rails-react-and-ai-powered-micro-app\/","title":{"rendered":"Leveraging Cloving CLI&#8217;s Chat Feature to Build a Rails, React, and AI-Powered Micro App"},"content":{"rendered":"\n<p>Modern development tools like <a href=\"https:\/\/cloving.ai\/\">Cloving<\/a> <a href=\"https:\/\/www.npmjs.com\/package\/cloving\" data-type=\"link\" data-id=\"https:\/\/www.npmjs.com\/package\/cloving\">CLI<\/a> are revolutionizing how developers interact with AI in their workflows. <a href=\"https:\/\/www.npmjs.com\/package\/cloving\">Cloving CLI&#8217;s<\/a> chat functionality offers a streamlined and interactive way to incorporate AI into development tasks, including creating micro apps. This blog post demonstrates how to use Cloving CLI&#8217;s chat feature to build a Rails-based micro app that integrates a WordPress API, React frontend, and AI for content enhancement.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Project Overview<\/h3>\n\n\n\n<p>Our micro app enables users to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Search for WordPress posts via a Rails API.<\/li>\n\n\n\n<li>View and select posts in a React app.<\/li>\n\n\n\n<li>Modify posts using AI-enhanced suggestions via Rails.<\/li>\n\n\n\n<li>Save the updated posts back to WordPress.<\/li>\n<\/ol>\n\n\n\n<p>This workflow will focus on Cloving CLI&#8217;s <strong>interactive chat<\/strong> feature to scaffold components, refine APIs, and facilitate AI interactions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Section 1: Initializing the Project with Cloving CLI<\/h3>\n\n\n\n<p>Cloving CLI simplifies project scaffolding with context-aware AI commands. To start, set up the Rails backend and configure it to communicate with WordPress. Use the <code>cloving generate code<\/code> command to scaffold the necessary components.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving init --model openai<\/code><\/pre>\n\n\n\n<p>After initializing the project, you can generate code directly using Cloving CLI:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Generate a Rails controller for connecting to the WordPress REST API and handling search requests.\"<\/code><\/pre>\n\n\n\n<p>This command instructs Cloving to generate the code for a Rails controller that connects to the WordPress REST API and handles search requests. Cloving uses AI to create code snippets based on the provided prompt, streamlining the development process.<\/p>\n\n\n\n<p><strong>Generated Rails Controller Example:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class Api::V1::PostsController &lt; ApplicationController\n  require 'httparty'\n\n  # GET \/api\/v1\/posts\/search?query=your_search_term\n  def search\n    query = params&#91;:query]\n    wordpress_api_url = \"https:\/\/your-wordpress-site.com\/wp-json\/wp\/v2\/posts?search=#{query}\"\n\n    response = HTTParty.get(wordpress_api_url)\n\n    if response.success?\n      render json: response.parsed_response, status: :ok\n    else\n      render json: { error: 'Failed to fetch posts from WordPress' }, status: :bad_request\n    end\n  end\nend<\/code><\/pre>\n\n\n\n<p>In this controller:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Namespace<\/strong>: The controller is namespaced under <code>Api::V1<\/code> to indicate versioning for your API.<\/li>\n\n\n\n<li><strong>HTTParty<\/strong>: Utilizes the HTTParty gem to make HTTP requests to the WordPress REST API.<\/li>\n\n\n\n<li><strong>Search Action<\/strong>: The <code>search<\/code> method accepts a <code>query<\/code> parameter from the frontend, constructs a request to the WordPress API, and returns the JSON response.<\/li>\n\n\n\n<li><strong>Error Handling<\/strong>: Includes basic error handling to manage unsuccessful API requests.<\/li>\n<\/ul>\n\n\n\n<p>With this controller in place, your Rails API can handle search requests from the React frontend, query the WordPress API, and send back the search results in a structured format.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Section 2: Handling API Responses and Structuring Data<\/h3>\n\n\n\n<p>With our Rails controller now set up to fetch posts from the WordPress API, the next step is ensuring the data returned from WordPress is properly structured and ready to send to the React frontend. This involves processing the API response to include only the necessary information and organizing it into a consistent format.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Formatting API Responses<\/h4>\n\n\n\n<p>WordPress posts retrieved through the API often contain a wealth of metadata, much of which may not be needed in the React frontend. To streamline this data, we can use a serializer in Rails to extract only the relevant fields. For example, we might include fields like the post title, excerpt, content, and permalink.<\/p>\n\n\n\n<p>To handle this, create a serializer using the Active Model Serializers gem:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>bundle add active_model_serializers<\/code><\/pre>\n\n\n\n<p><strong>Generate the Serializer:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rails generate serializer Post<\/code><\/pre>\n\n\n\n<p><strong>Modify the Serializer:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class PostSerializer &lt; ActiveModel::Serializer\n  attributes :id, :title, :excerpt, :content, :permalink\n\n  def title\n    object&#91;'title']&#91;'rendered']\n  end\n\n  def excerpt\n    object&#91;'excerpt']&#91;'rendered']\n  end\n\n  def content\n    object&#91;'content']&#91;'rendered']\n  end\n\n  def permalink\n    object&#91;'link']\n  end\nend<\/code><\/pre>\n\n\n\n<p>Here, the serializer maps the relevant fields from the WordPress API response to attributes that the React frontend can use.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Updating the Controller to Use the Serializer<\/h4>\n\n\n\n<p>Next, update the <code>search<\/code> action in the <code>PostsController<\/code> to use the <code>PostSerializer<\/code> for formatting the response before sending it back to the frontend.<\/p>\n\n\n\n<p><strong>Updated Controller Action:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>def search\n  query = params&#91;:query]\n  wordpress_api_url = \"https:\/\/your-wordpress-site.com\/wp-json\/wp\/v2\/posts?search=#{query}\"\n\n  response = HTTParty.get(wordpress_api_url)\n\n  if response.success?\n    posts = JSON.parse(response.body)\n    render json: posts.map { |post| PostSerializer.new(post).as_json }, status: :ok\n  else\n    render json: { error: 'Failed to fetch posts from WordPress' }, status: :bad_request\n  end\nend<\/code><\/pre>\n\n\n\n<p>In this version:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>JSON Parsing<\/strong>: The response body from WordPress is parsed into a Ruby hash.<\/li>\n\n\n\n<li><strong>Serializer Application<\/strong>: Each post in the response is passed through the <code>PostSerializer<\/code> to extract and format only the necessary fields.<\/li>\n\n\n\n<li><strong>Array Mapping<\/strong>: The serialized posts are returned as an array of structured JSON objects.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Preparing for the React Frontend<\/h4>\n\n\n\n<p>Now that the Rails API is returning clean, structured data, we\u2019re ready to send this data to the React frontend in Section 3. The frontend will fetch these results, display them in a user-friendly format, and allow users to select a post for further actions.<\/p>\n\n\n\n<p>This structured approach ensures that the Rails API remains a reliable intermediary between WordPress and React, offloading data processing and allowing the frontend to focus on user interaction.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Section 3: Setting Up the React Frontend with Cloving CLI<\/h3>\n\n\n\n<p>With our Rails API configured to retrieve and format WordPress posts, the next step is to set up a React frontend that can fetch and display these results. Here, we\u2019ll use Cloving CLI to scaffold a React app, generate components for interacting with the Rails API, and handle user interactions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Generating the React App and Components with Cloving CLI<\/h4>\n\n\n\n<p>Cloving CLI\u2019s code generation feature can expedite the process of building out our frontend components. Start by using Cloving to initialize a new React app:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Initialize a new React app for fetching and displaying data from a Rails API.\"<\/code><\/pre>\n\n\n\n<p>This command sets up the structure for a React app, including dependencies for communicating with APIs. Once the base app is ready, you can use Cloving\u2019s code generation to create a component for displaying the search results from WordPress.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Creating the Post Search Component<\/h4>\n\n\n\n<p>To create the <code>PostSearch<\/code> component, prompt Cloving CLI to generate code that fetches data from an API and displays it in a list:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Create a React component to fetch and display posts from a Rails API.\"<\/code><\/pre>\n\n\n\n<p>This command provides a scaffolded component that fetches posts from our Rails API and displays them in a list. You can then refine this component with Cloving\u2019s interactive chat feature:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving chat<\/code><\/pre>\n\n\n\n<p><strong>Example Cloving Chat Interaction:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><em>Prompt<\/em>: \u201cGenerate a React component that fetches search results from an API, displays them in a list, and allows the user to select a post.\u201d<\/li>\n<\/ul>\n\n\n\n<p>Cloving CLI will generate code for a component like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ src\/components\/PostSearch.js\nimport React, { useState } from 'react'\nimport axios from 'axios'\n\nconst PostSearch = () =&gt; {\n  const &#91;query, setQuery] = useState('')\n  const &#91;posts, setPosts] = useState(&#91;])\n  const &#91;selectedPost, setSelectedPost] = useState(null)\n\n  \/\/ Handle form submission to search for posts\n  const handleSearch = async (e) =&gt; {\n    e.preventDefault()\n    try {\n      const response = await axios.get(`http:\/\/localhost:3001\/api\/v1\/posts\/search`, {\n        params: { query }\n      })\n      setPosts(response.data)\n    } catch (error) {\n      console.error('Error fetching posts:', error)\n    }\n  }\n\n  \/\/ Handle post selection\n  const handleSelectPost = (post) =&gt; {\n    setSelectedPost(post)\n  }\n\n  return (\n    &lt;div&gt;\n      &lt;form onSubmit={handleSearch}&gt;\n        &lt;input\n          type=\"text\"\n          value={query}\n          onChange={(e) =&gt; setQuery(e.target.value)}\n          placeholder=\"Search WordPress posts...\"\n        \/&gt;\n        &lt;button type=\"submit\"&gt;Search&lt;\/button&gt;\n      &lt;\/form&gt;\n\n      &lt;div&gt;\n        {posts.length &gt; 0 &amp;&amp; (\n          &lt;ul&gt;\n            {posts.map((post) =&gt; (\n              &lt;li key={post.id} onClick={() =&gt; handleSelectPost(post)}&gt;\n                &lt;h3&gt;{post.title}&lt;\/h3&gt;\n                &lt;p dangerouslySetInnerHTML={{ __html: post.excerpt }}&gt;&lt;\/p&gt;\n              &lt;\/li&gt;\n            ))}\n          &lt;\/ul&gt;\n        )}\n      &lt;\/div&gt;\n\n      {selectedPost &amp;&amp; (\n        &lt;div&gt;\n          &lt;h2&gt;Selected Post: {selectedPost.title}&lt;\/h2&gt;\n          &lt;p dangerouslySetInnerHTML={{ __html: selectedPost.content }}&gt;&lt;\/p&gt;\n          {\/* Add further actions here, like expanding the content with AI *\/}\n        &lt;\/div&gt;\n      )}\n    &lt;\/div&gt;\n  )\n}\n\nexport default PostSearch<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Component Breakdown<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>State Management<\/strong>: <code>query<\/code>, <code>posts<\/code>, and <code>selectedPost<\/code> states manage the search term, list of posts, and the currently selected post.<\/li>\n\n\n\n<li><strong>Search Function<\/strong>: The <code>handleSearch<\/code> function sends a search query to the Rails API, updating <code>posts<\/code> with the results.<\/li>\n\n\n\n<li><strong>Display and Select Posts<\/strong>: The component renders the posts in a list and allows the user to select a post for further actions.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Integrating the Component into the React App<\/h4>\n\n\n\n<p>Finally, import and render the <code>PostSearch<\/code> component in your main <code>App.js<\/code> file:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Set up the main App component to render the PostSearch component in a new React project.\"<\/code><\/pre>\n\n\n\n<p>With Cloving\u2019s help, you\u2019ll get the basic setup for your <code>App<\/code> component, which will look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ src\/App.js\nimport React from 'react'\nimport '.\/App.css'\nimport PostSearch from '.\/components\/PostSearch'\n\nfunction App() {\n  return (\n    &lt;div className=\"App\"&gt;\n      &lt;h1&gt;WordPress Post Search&lt;\/h1&gt;\n      &lt;PostSearch \/&gt;\n    &lt;\/div&gt;\n  )\n}\n\nexport default App<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Testing the Integration<\/h4>\n\n\n\n<p>Run both the Rails and React applications to test the flow from search to post selection. This setup provides a user-friendly interface to search for WordPress posts, which prepares us for the next step: integrating AI to enhance the content of a selected post.<\/p>\n\n\n\n<p>In Section 4, we\u2019ll connect the Rails backend to an AI API to allow users to expand on any selected WordPress post, creating a seamless content augmentation workflow.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Section 4: Enhancing Post Content with AI and Cloving CLI<\/h3>\n\n\n\n<p>With our Rails API successfully retrieving and formatting WordPress posts and the React frontend displaying them, we\u2019re ready to add AI-driven content enhancement. In this section, we\u2019ll use Cloving CLI to scaffold code that enables Rails to interact with an AI API (such as OpenAI\u2019s GPT-4) to expand the selected WordPress post\u2019s content based on user requests. This enhancement workflow will allow users to select a post, request expanded content, review the AI-generated additions, and submit the modified post back to WordPress.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Setting Up the AI Integration with Cloving CLI<\/h4>\n\n\n\n<p>To start, let\u2019s use Cloving CLI to generate the initial service code in Rails for connecting to the AI API. This service will take in a selected post\u2019s content, send it to the AI API, and return the expanded content.<\/p>\n\n\n\n<p>Use Cloving CLI to scaffold the service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Create a Rails service to connect to the OpenAI API and generate expanded content for a selected post.\"<\/code><\/pre>\n\n\n\n<p>Cloving will generate a service template similar to this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># app\/services\/ai_content_service.rb\nrequire 'net\/http'\nrequire 'uri'\nrequire 'json'\n\nclass AiContentService\n  OPENAI_API_URL = \"https:\/\/api.openai.com\/v1\/completions\"\n\n  def initialize(api_key)\n    @api_key = api_key\n  end\n\n  def expand_content(post_content)\n    prompt = \"Expand the following blog post content with additional insights and details:\\n\\n#{post_content}\"\n\n    response = Net::HTTP.post(\n      URI.parse(OPENAI_API_URL),\n      { model: \"text-davinci-003\", prompt:, max_tokens: 500 }.to_json,\n      \"Content-Type\" =&gt; \"application\/json\",\n      \"Authorization\" =&gt; \"Bearer #{@api_key}\"\n    )\n\n    JSON.parse(response.body)&#91;\"choices\"]&#91;0]&#91;\"text\"].strip\n  rescue =&gt; e\n    Rails.logger.error(\"Failed to generate expanded content: #{e.message}\")\n    nil\n  end\nend<\/code><\/pre>\n\n\n\n<p>Here\u2019s what this service does:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>API Key Setup<\/strong>: Initializes the service with the AI API key.<\/li>\n\n\n\n<li><strong>expand_content Method<\/strong>: Sends a prompt to the AI API to expand the post content and returns the AI-generated text.<\/li>\n\n\n\n<li><strong>Error Handling<\/strong>: Logs errors in case of issues with the API call.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Integrating the AI Service in the Controller<\/h4>\n\n\n\n<p>Now that we have the <code>AiContentService<\/code>, let\u2019s use Cloving CLI to help us integrate this service into our Rails controller. This integration will involve creating an endpoint that triggers the AI expansion process when a user selects a post.<\/p>\n\n\n\n<p>Generate the controller action with Cloving:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Add a controller action to call the AiContentService and return the expanded content for a selected post.\"<\/code><\/pre>\n\n\n\n<p>Cloving will create or update the controller with the following action:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># app\/controllers\/api\/v1\/posts_controller.rb\n\ndef expand_content\n  post_content = params&#91;:content]\n  ai_service = AiContentService.new(ENV&#91;'OPENAI_API_KEY'])\n  expanded_content = ai_service.expand_content(post_content)\n\n  if expanded_content\n    render json: { expanded_content: }, status: :ok\n  else\n    render json: { error: 'Failed to generate expanded content' }, status: :unprocessable_entity\n  end\nend<\/code><\/pre>\n\n\n\n<p>In this action:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Parameters<\/strong>: The <code>expand_content<\/code> action accepts <code>content<\/code> from the frontend, which contains the selected post\u2019s content.<\/li>\n\n\n\n<li><strong>AI Service Call<\/strong>: It initializes the <code>AiContentService<\/code> and calls the <code>expand_content<\/code> method.<\/li>\n\n\n\n<li><strong>Response<\/strong>: If successful, it returns the expanded content in JSON format; otherwise, it sends an error message.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Connecting the React Frontend to Request Expanded Content<\/h4>\n\n\n\n<p>Now that our Rails API is equipped to handle AI-generated content, use Cloving CLI to scaffold the next steps in the React frontend for making this request and displaying the expanded content.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Create a function in the React PostSearch component to request expanded content for a selected post.\"<\/code><\/pre>\n\n\n\n<p>Cloving will generate a new function in the <code>PostSearch<\/code> component for handling this request:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ In PostSearch.js\n\nconst requestExpandedContent = async () =&gt; {\n  try {\n    const response = await axios.post('http:\/\/localhost:3001\/api\/v1\/posts\/expand_content', {\n      content: selectedPost.content\n    })\n    setExpandedContent(response.data.expanded_content)\n  } catch (error) {\n    console.error('Error expanding content:', error)\n  }\n}<\/code><\/pre>\n\n\n\n<p>This function:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Sends a POST Request<\/strong>: Posts the content of the selected post to the Rails <code>expand_content<\/code> endpoint.<\/li>\n\n\n\n<li><strong>Updates State<\/strong>: Sets <code>expandedContent<\/code> with the AI-generated content returned by the Rails API.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Displaying the Expanded Content and Handling User Review<\/h4>\n\n\n\n<p>Finally, Cloving CLI can help scaffold code to render the AI-generated content for review and submission back to Rails.<\/p>\n\n\n\n<p>Add a section in the <code>PostSearch<\/code> component to display <code>expandedContent<\/code> and allow users to submit it back to the Rails API.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Add a form in the React component to display expanded content and submit it for saving in WordPress.\"<\/code><\/pre>\n\n\n\n<p>Cloving will generate a basic review component for the expanded content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ In PostSearch.js\n\nreturn (\n  &lt;div&gt;\n    {\/* Existing form and post list *\/}\n    {expandedContent &amp;&amp; (\n      &lt;div&gt;\n        &lt;h2&gt;Expanded Content:&lt;\/h2&gt;\n        &lt;p&gt;{expandedContent}&lt;\/p&gt;\n        &lt;button onClick={submitExpandedContent}&gt;Save to WordPress&lt;\/button&gt;\n      &lt;\/div&gt;\n    )}\n  &lt;\/div&gt;\n)<\/code><\/pre>\n\n\n\n<p>In this updated component:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Expanded Content Display<\/strong>: Shows the AI-generated expanded content.<\/li>\n\n\n\n<li><strong>Save Button<\/strong>: Triggers <code>submitExpandedContent<\/code>, which posts the modified content back to Rails for saving in WordPress.<\/li>\n<\/ul>\n\n\n\n<p>With Cloving CLI, this section was quickly scaffolded, allowing us to move efficiently through the process of integrating and displaying AI-generated content.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>In Section 5, we\u2019ll use Cloving CLI to finalize the workflow by implementing the save action in Rails, which will take the modified content from React and update it in WordPress. This will complete the content expansion workflow, allowing users to seamlessly expand, review, and save enhanced content directly in WordPress.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Section 5: Saving the Enhanced Content Back to WordPress Using Cloving CLI<\/h3>\n\n\n\n<p>With the AI-enhanced content ready for review in the React frontend, the final step is to allow users to submit the modified content back to the Rails backend, which will update the original WordPress post. In this section, we\u2019ll use Cloving CLI to generate the Rails functionality required to handle this update, ensuring the content is saved back to WordPress seamlessly.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Adding the Save Endpoint in Rails<\/h4>\n\n\n\n<p>First, let\u2019s add an endpoint in Rails that accepts the modified content from the React frontend and sends an update request to the WordPress API. Use Cloving CLI to scaffold the controller action and service code needed to perform this update.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Create a Rails controller action to update a WordPress post with new content.\"<\/code><\/pre>\n\n\n\n<p>Cloving will generate the following code in your <code>PostsController<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># app\/controllers\/api\/v1\/posts_controller.rb\n\ndef save_expanded_content\n  post_id = params&#91;:post_id]\n  updated_content = params&#91;:content]\n  wordpress_service = WordPressService.new\n  success = wordpress_service.update_post(post_id, updated_content)\n\n  if success\n    render json: { message: 'Post updated successfully' }, status: :ok\n  else\n    render json: { error: 'Failed to update the post on WordPress' }, status: :unprocessable_entity\n  end\nend<\/code><\/pre>\n\n\n\n<p>Here\u2019s a breakdown of this action:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Parameters<\/strong>: It accepts <code>post_id<\/code> and <code>content<\/code> as parameters, representing the WordPress post ID and the modified content.<\/li>\n\n\n\n<li><strong>Service Call<\/strong>: Initializes <code>WordPressService<\/code> to handle the update request to WordPress.<\/li>\n\n\n\n<li><strong>Response<\/strong>: Sends a success message if the update succeeds, otherwise returns an error message.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Creating the WordPressService to Handle Updates<\/h4>\n\n\n\n<p>Next, let\u2019s generate the <code>WordPressService<\/code> using Cloving CLI, which will manage the API request to update the post on WordPress.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Create a Rails service to update a WordPress post with new content.\"<\/code><\/pre>\n\n\n\n<p>Cloving will generate a service like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># app\/services\/wordpress_service.rb\nrequire 'httparty'\n\nclass WordPressService\n  include HTTParty\n  base_uri 'https:\/\/your-wordpress-site.com\/wp-json\/wp\/v2'\n\n  def initialize\n    @headers = {\n      \"Content-Type\" =&gt; \"application\/json\",\n      \"Authorization\" =&gt; \"Bearer #{ENV&#91;'WORDPRESS_API_TOKEN']}\"\n    }\n  end\n\n  def update_post(post_id, content)\n    response = self.class.put(\"\/posts\/#{post_id}\", {\n      headers: @headers,\n      body: { content: content }.to_json\n    })\n    response.success?\n  end\nend<\/code><\/pre>\n\n\n\n<p>This <code>WordPressService<\/code> class:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Base URI<\/strong>: Sets the base URI for the WordPress API.<\/li>\n\n\n\n<li><strong>Authorization<\/strong>: Uses an authorization header with an API token from the environment for secure access.<\/li>\n\n\n\n<li><strong>Update Post Method<\/strong>: Uses an HTTP <code>PUT<\/code> request to send the updated content back to the specified post on WordPress.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Submitting the Expanded Content from React<\/h4>\n\n\n\n<p>With the Rails API ready to handle updates, let\u2019s use Cloving CLI to scaffold a function in the React <code>PostSearch<\/code> component to submit the expanded content to Rails for saving in WordPress.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cloving generate code --prompt \"Add a function in the React PostSearch component to submit expanded content to the Rails API for saving in WordPress.\"<\/code><\/pre>\n\n\n\n<p>Cloving will add the <code>submitExpandedContent<\/code> function in your <code>PostSearch<\/code> component:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const submitExpandedContent = async () =&gt; {\n  try {\n    const response = await axios.post('http:\/\/localhost:3001\/api\/v1\/posts\/save_expanded_content', {\n      post_id: selectedPost.id,\n      content: expandedContent\n    })\n    if (response.data.message) {\n      alert('Post updated successfully!')\n    }\n  } catch (error) {\n    console.error('Error saving expanded content:', error)\n    alert('Failed to save the post on WordPress')\n  }\n}<\/code><\/pre>\n\n\n\n<p>This function:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Posts Data to Rails<\/strong>: Sends the <code>post_id<\/code> and modified <code>content<\/code> to the <code>save_expanded_content<\/code> endpoint in Rails.<\/li>\n\n\n\n<li><strong>Success Message<\/strong>: Displays a success message if the response is successful.<\/li>\n\n\n\n<li><strong>Error Handling<\/strong>: Logs errors and displays an alert if saving the content fails.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h4 class=\"wp-block-heading\">Finalizing and Testing the Workflow<\/h4>\n\n\n\n<p>With these elements in place, you can now test the full workflow:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Search and Select<\/strong>: The user searches for and selects a WordPress post.<\/li>\n\n\n\n<li><strong>Expand Content<\/strong>: The React frontend requests expanded content from the AI API via Rails.<\/li>\n\n\n\n<li><strong>Review and Save<\/strong>: The user reviews the expanded content and saves it back to WordPress.<\/li>\n<\/ol>\n\n\n\n<p>This end-to-end process, facilitated by Cloving CLI, makes it easy to set up and integrate AI-powered content workflows. The project showcases the potential of Cloving CLI in accelerating development, structuring code across multiple services, and seamlessly connecting a Rails API, React frontend, and external platforms like WordPress and AI APIs.<\/p>\n\n\n\n<p>This setup is now a robust foundation for future enhancements, such as adding more AI features, implementing version control for drafts, or extending the frontend to allow for rich text editing. By using Cloving CLI, this development process remains streamlined, efficient, and highly adaptable to changing requirements.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits of Using Cloving CLI<\/h3>\n\n\n\n<p><strong>Streamlined Development<\/strong>: Cloving CLI\u2019s <code>generate code<\/code> feature and chat mode provide real-time feedback, scaffolding, and refinement, helping you develop essential components quickly while ensuring generated code aligns with specific requirements. This rapid scaffolding frees up valuable time for testing, iteration, and fine-tuning, making the development process much faster and more efficient.<\/p>\n\n\n\n<p><strong>Seamless Integration Across Platforms<\/strong>: Cloving CLI\u2019s versatility shines as it supports multiple AI models (OpenAI, Claude, etc.), making it easy to integrate AI-driven workflows into your preferred tools. Whether using Rails for backend management, React for the frontend, or AI services for content expansion, Cloving allows these elements to connect seamlessly, making it ideal for multi-platform applications.<\/p>\n\n\n\n<p><strong>Context-Aware and Task-Specific Suggestions<\/strong>: Cloving\u2019s ability to retain and leverage project context means that generated code is aligned with your existing architecture and the specific needs of your app. This task-specific intelligence ensures that Cloving suggestions are not only functional but also optimized for your project\u2019s structure and goals.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\">Wrapping Up<\/h3>\n\n\n\n<p>Cloving CLI is a transformative tool for developers, enabling faster, more adaptable, and efficient project creation. By combining Cloving\u2019s context-aware code generation and interactive prompts with Rails, React, WordPress, and AI integrations, you can build robust micro apps that automate and simplify complex workflows, such as content management, in record time.<\/p>\n\n\n\n<p>Looking ahead, Cloving\u2019s additional features\u2014such as automated code reviews, debugging assistance, and test generation\u2014can further streamline your development process and improve code quality. This setup underscores the potential of AI-driven development tools like Cloving CLI to accelerate and refine the creation of sophisticated, multi-platform applications, paving the way for scalable and dynamic software solutions.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Modern development tools like Cloving CLI are revolutionizing how developers interact with AI in their workflows. Cloving CLI&#8217;s chat functionality offers a streamlined and interactive way to incorporate AI into development tasks, including creating micro apps. This blog post demonstrates how to use Cloving CLI&#8217;s chat feature to build a Rails-based micro app that integrates&hellip; <br \/> <a class=\"read-more\" href=\"https:\/\/rhwbaldwin.com\/blog\/2024\/11\/15\/leveraging-cloving-clis-chat-feature-to-build-a-rails-react-and-ai-powered-micro-app\/\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":102,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[7,8,9,10,11],"class_list":["post-96","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-ml-and-llms","tag-ai","tag-cloving","tag-rails","tag-react","tag-wordpress-api"],"_links":{"self":[{"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/posts\/96","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/comments?post=96"}],"version-history":[{"count":7,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/posts\/96\/revisions"}],"predecessor-version":[{"id":104,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/posts\/96\/revisions\/104"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/media\/102"}],"wp:attachment":[{"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/media?parent=96"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/categories?post=96"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rhwbaldwin.com\/blog\/wp-json\/wp\/v2\/tags?post=96"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}