-
Notifications
You must be signed in to change notification settings - Fork 0
One-Click 'Create Draft from This Idea' Buttons #5
Description
Problem Statement
Currently, users receive AI-generated content recommendations but cannot act on them directly. The interface is a dead-end: users must manually copy ideas, navigate to content creation forms, and recreate context. This creates friction between strategy and execution.
Proposed Solution
Add a "📝 Create Draft" button next to each content idea in all recommendation cards (Content Gaps, Authority Topics, Expertise Demonstrations, Trust Signals) that:
- Opens Drupal's node creation form with pre-filled content
- Auto-selects the appropriate content type
- Pre-populates title and body fields with AI recommendation context
- Reduces time-to-draft from ~5 minutes to ~10 seconds
Content Type Selection Logic
Option 1: Configuration-Based Mapping (Recommended for MVP)
Create admin configuration form at /admin/config/ai/content-strategy/settings:
content_type_mapping:
content_gaps:
default: 'article'
keywords:
'guide': 'page'
'tutorial': 'tutorial'
'faq': 'faq'
authority_topics:
default: 'article'
expertise_demonstrations:
default: 'article'
keywords:
'webinar': 'event'
'case study': 'case_study'
'video': 'video'
trust_signals:
default: 'page'
keywords:
'testimonial': 'testimonial'
'certification': 'certification'Logic:
- Check recommendation section (content_gaps, authority_topics, etc.)
- Scan content idea text for keyword matches
- Use mapped content type if keyword found
- Fall back to section default
- Fall back to site default content type (from config)
Benefits:
- Simple to implement
- No AI calls needed
- Users can customize mappings
- Predictable behavior
Option 2: AI-Powered Content Type Detection (Future Enhancement)
Send lightweight prompt to AI:
Given this content idea: "{idea_text}"
And these available content types: {json_list_of_content_types}
Return only the machine name of the most appropriate content type.
Benefits:
- More intelligent matching
- Adapts to any content type
Drawbacks:
- Adds latency (200-500ms)
- Costs per API call
- Less predictable
Recommendation: Start with Option 1, add Option 2 as checkbox "Use AI to suggest content type"
Option 3: User Choice Dropdown (Hybrid Approach)
Show mini-form before creating draft:
┌─────────────────────────────────────┐
│ Create draft from this idea? │
├─────────────────────────────────────┤
│ Content Type: [Article ▼] │
│ - Article (suggested) │
│ - Page │
│ - Tutorial │
│ - Case Study │
│ │
│ [Cancel] [Create Draft →] │
└─────────────────────────────────────┘
Benefits:
- User maintains control
- Can override AI suggestion
- Clear and transparent
Recommendation: Combine with Option 1 - show suggested type as default, allow override
Technical Implementation
1. Add Button to Template
File: templates/ai-content-strategy-recommendations-items.html.twig
{% for idea in item.content_ideas %}
<tr>
<td>{{ idea }}</td>
<td class="actions">
<button class="create-draft-button button button--small"
data-section="{{ section }}"
data-recommendation="{{ item[section_config.item_key] }}"
data-idea="{{ idea }}">
📝 Create Draft
</button>
</td>
</tr>
{% endfor %}2. JavaScript Handler
File: js/content-ideas.js (or new js/create-draft.js)
Drupal.behaviors.aiContentStrategyCreateDraft = {
attach: function (context, settings) {
$('.create-draft-button', context).once('create-draft').on('click', function(e) {
e.preventDefault();
const $button = $(this);
const section = $button.data('section');
const recommendation = $button.data('recommendation');
const idea = $button.data('idea');
// Get content type via AJAX
$.ajax({
url: '/admin/reports/ai/content-strategy/suggest-content-type',
method: 'POST',
data: {
section: section,
idea: idea
},
success: function(response) {
// Build node/add URL with query parameters
const params = new URLSearchParams({
ai_title: idea,
ai_context: recommendation,
ai_section: section
});
window.location.href = `/node/add/${response.content_type}?${params.toString()}`;
}
});
});
}
};3. New Route for Content Type Suggestion
File: ai_content_strategy.routing.yml
ai_content_strategy.suggest_content_type:
path: '/admin/reports/ai/content-strategy/suggest-content-type'
defaults:
_controller: '\Drupal\ai_content_strategy\Controller\ContentStrategyController::suggestContentType'
_title: 'Suggest Content Type'
requirements:
_permission: 'access ai content strategy'
methods: [POST]4. Controller Method
File: src/Controller/ContentStrategyController.php
/**
* Suggests a content type based on recommendation section and idea text.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request object.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* JSON response with suggested content_type.
*/
public function suggestContentType(Request $request) {
$section = $request->request->get('section');
$idea = $request->request->get('idea');
// Get configuration
$config = $this->config('ai_content_strategy.content_types');
$mapping = $config->get('mapping') ?? [];
// Default content type
$content_type = 'article';
// Check section-specific mapping
if (isset($mapping[$section])) {
$section_config = $mapping[$section];
// Check for keyword matches
if (isset($section_config['keywords'])) {
foreach ($section_config['keywords'] as $keyword => $type) {
if (stripos($idea, $keyword) !== FALSE) {
$content_type = $type;
break;
}
}
}
// Use section default if no keyword match
if ($content_type === 'article' && isset($section_config['default'])) {
$content_type = $section_config['default'];
}
}
return new JsonResponse(['content_type' => $content_type]);
}5. Hook into Node Form
File: ai_content_strategy.module
/**
* Implements hook_form_BASE_FORM_ID_alter() for node_form.
*/
function ai_content_strategy_form_node_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Check if we have AI-generated content in query parameters
$request = \Drupal::request();
$ai_title = $request->query->get('ai_title');
$ai_context = $request->query->get('ai_context');
$ai_section = $request->query->get('ai_section');
if ($ai_title) {
// Pre-fill title
$form['title']['widget'][0]['value']['#default_value'] = $ai_title;
// Pre-fill body with context
if (isset($form['body']) && $ai_context) {
$body_text = "## Content Strategy Recommendation\n\n";
$body_text .= "**Section:** " . ucwords(str_replace('_', ' ', $ai_section)) . "\n\n";
$body_text .= "**Recommendation:** {$ai_context}\n\n";
$body_text .= "**Idea:** {$ai_title}\n\n";
$body_text .= "---\n\n";
$body_text .= "[Start writing your content here...]";
$form['body']['widget'][0]['#default_value'] = $body_text;
$form['body']['widget'][0]['#format'] = 'basic_html';
}
// Add informational message
\Drupal::messenger()->addStatus(t('This draft was created from an AI content strategy recommendation. Feel free to edit and customize.'));
}
}6. Configuration Schema
File: config/schema/ai_content_strategy.schema.yml
Add:
ai_content_strategy.content_types:
type: config_object
label: 'Content Type Mapping'
mapping:
mapping:
type: sequence
label: 'Section to Content Type Mapping'
sequence:
type: mapping
mapping:
default:
type: string
label: 'Default content type'
keywords:
type: sequence
label: 'Keyword mappings'
sequence:
type: mapping
mapping:
keyword:
type: string
content_type:
type: string7. Default Configuration
File: config/install/ai_content_strategy.content_types.yml
mapping:
content_gaps:
default: 'article'
keywords:
guide: 'page'
tutorial: 'tutorial'
faq: 'faq'
authority_topics:
default: 'article'
expertise_demonstrations:
default: 'article'
keywords:
webinar: 'event'
'case study': 'case_study'
video: 'video'
trust_signals:
default: 'page'
keywords:
testimonial: 'testimonial'
certification: 'page'Acceptance Criteria
- Each content idea row has a "Create Draft" button
- Clicking button suggests appropriate content type based on configuration
- Node creation form opens with pre-filled title from content idea
- Body field contains context about the recommendation
- User sees message indicating draft was created from AI recommendation
- Configuration form allows admins to customize content type mappings
- Works with any installed content types on the site
- Gracefully handles missing content types (falls back to 'article')
- Button shows loading state during AJAX request
- Appropriate permissions checked before allowing draft creation
Future Enhancements
- Add "Create Multiple Drafts" checkbox to create nodes from all ideas at once
- AI-powered content type detection option
- Save as unpublished by default with option to configure
- Add to editorial calendar/workflow if modules installed
- Assign to specific users/teams
Value Proposition
Time Saved: 5 minutes per idea → 10 seconds per idea
User Impact: Transforms passive recommendations into active content pipeline
Development Time: 8-12 hours
ROI: ⭐⭐⭐⭐⭐
🤖 Generated with Claude Code