chore: bulk commit of local changes across blog writer, SEO dashboard, scheduler, docs-site, and frontend
This commit is contained in:
@@ -54,58 +54,58 @@ class TitleGenerator:
|
||||
Returns:
|
||||
Formatted title string
|
||||
"""
|
||||
if not angle or len(angle.strip()) < 10: # Too short to be a good title
|
||||
if not angle or len(angle.strip()) < 10:
|
||||
return ""
|
||||
|
||||
# Clean up the angle
|
||||
cleaned_angle = angle.strip()
|
||||
|
||||
# Capitalize first letter of each sentence and proper nouns
|
||||
sentences = cleaned_angle.split('. ')
|
||||
formatted_sentences = []
|
||||
for sentence in sentences:
|
||||
if sentence.strip():
|
||||
# Use title case for better formatting
|
||||
formatted_sentence = sentence.strip().title()
|
||||
formatted_sentences.append(formatted_sentence)
|
||||
|
||||
formatted_title = '. '.join(formatted_sentences)
|
||||
|
||||
# Ensure it ends with proper punctuation
|
||||
if not formatted_title.endswith(('.', '!', '?')):
|
||||
formatted_title += '.'
|
||||
# Use sentence case: capitalize first letter, rest as-is
|
||||
if cleaned_angle:
|
||||
cleaned_angle = cleaned_angle[0].upper() + cleaned_angle[1:]
|
||||
|
||||
# Limit length to reasonable blog title size
|
||||
if len(formatted_title) > 200:
|
||||
formatted_title = formatted_title[:197] + "..."
|
||||
if len(cleaned_angle) > 120:
|
||||
cleaned_angle = cleaned_angle[:117] + "..."
|
||||
|
||||
return formatted_title
|
||||
return cleaned_angle
|
||||
|
||||
def combine_title_options(self, ai_titles: List[str], content_angle_titles: List[str], primary_keywords: List[str]) -> List[str]:
|
||||
def combine_title_options(self, ai_titles: List[str], content_angle_titles: List[str], primary_keywords: List[str], research_topic: str = "") -> List[str]:
|
||||
"""
|
||||
Combine AI-generated titles with content angle titles, ensuring variety and quality.
|
||||
|
||||
AI titles (proper SEO titles generated by LLM) take priority.
|
||||
Content angle titles (long-format descriptions) are used as fallback.
|
||||
The research topic is the last resort when nothing else exists.
|
||||
|
||||
Args:
|
||||
ai_titles: AI-generated title options
|
||||
content_angle_titles: Titles derived from content angles
|
||||
ai_titles: AI-generated title options (proper blog titles, 50-65 chars)
|
||||
content_angle_titles: Titles derived from content angles (longer, descriptive)
|
||||
primary_keywords: Primary keywords for fallback generation
|
||||
research_topic: Original user research topic as ultimate fallback
|
||||
|
||||
Returns:
|
||||
Combined list of title options (max 6 total)
|
||||
"""
|
||||
all_titles = []
|
||||
|
||||
# Add content angle titles first (these are research-based and valuable)
|
||||
for title in content_angle_titles[:3]: # Limit to top 3 content angles
|
||||
if title and title not in all_titles:
|
||||
all_titles.append(title)
|
||||
|
||||
# Add AI-generated titles
|
||||
# 1. AI-generated titles first (proper SEO titles from LLM)
|
||||
for title in ai_titles:
|
||||
if title and title not in all_titles:
|
||||
all_titles.append(title)
|
||||
|
||||
# Note: Removed fallback titles as requested - only use research and AI-generated titles
|
||||
# 2. Content angle titles as fallback (research-based, but verbose)
|
||||
for title in content_angle_titles[:3]:
|
||||
if title and title not in all_titles:
|
||||
all_titles.append(title)
|
||||
|
||||
# 3. Research topic as last resort when nothing was generated
|
||||
if not all_titles and research_topic:
|
||||
all_titles.append(research_topic)
|
||||
|
||||
# 4. Primary keyword fallback as absolute last resort
|
||||
if not all_titles and primary_keywords:
|
||||
kw = primary_keywords[0]
|
||||
all_titles.append(kw)
|
||||
|
||||
# Limit to 6 titles maximum for UI usability
|
||||
final_titles = all_titles[:6]
|
||||
@@ -115,9 +115,10 @@ class TitleGenerator:
|
||||
|
||||
def generate_fallback_titles(self, primary_keywords: List[str]) -> List[str]:
|
||||
"""Generate fallback titles when AI generation fails."""
|
||||
from datetime import datetime
|
||||
primary_keyword = primary_keywords[0] if primary_keywords else "Topic"
|
||||
return [
|
||||
f"The Complete Guide to {primary_keyword}",
|
||||
f"{primary_keyword}: Everything You Need to Know",
|
||||
f"How to Master {primary_keyword} in 2024"
|
||||
f"How to Master {primary_keyword} in {datetime.now().year}"
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user