CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-djangocms-blog

The blog application for django CMS providing multilingual blog functionality with advanced content management features

Pending
Overview
Eval results
Files

feeds-sitemaps.mddocs/

Feeds and Sitemaps

Automated RSS feed generation and sitemap integration for SEO optimization with multilingual support and customizable output formats.

Capabilities

RSS Feed Generation

Comprehensive RSS feed system for blog content distribution.

class LatestEntriesFeed(Feed):
    """
    RSS feed for latest blog entries.
    
    Features:
    - Configurable number of items
    - Multilingual content support
    - App configuration filtering
    - Custom feed metadata
    - Rich content support with images and media
    """
    
    feed_type: Type[Rss201rev2Feed] = Rss201rev2Feed
    feed_items_number: int = get_setting("FEED_LATEST_ITEMS")
    
    def __call__(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
        """Handle feed request with app configuration context."""
        
    def get_object(self, request: HttpRequest, *args, **kwargs) -> BlogConfig:
        """Get blog configuration for feed context."""
        
    def title(self, obj: BlogConfig) -> str:
        """Return feed title based on configuration."""
        
    def link(self, obj: BlogConfig) -> str:
        """Return feed link URL."""
        
    def description(self, obj: BlogConfig) -> str:
        """Return feed description."""
        
    def items(self, obj: BlogConfig) -> QuerySet:
        """
        Return published posts for feed.
        
        Returns:
        QuerySet of published posts filtered by:
        - Publication status
        - App configuration  
        - RSS inclusion setting
        - Language context
        - Site filtering (if multisite)
        """
        
    def item_title(self, item: Post) -> str:
        """Return post title for feed item."""
        
    def item_description(self, item: Post) -> str:
        """Return post description/content for feed item."""
        
    def item_link(self, item: Post) -> str:
        """Return post URL for feed item."""
        
    def item_author_name(self, item: Post) -> str:
        """Return post author name."""
        
    def item_author_email(self, item: Post) -> str:
        """Return post author email."""
        
    def item_pubdate(self, item: Post) -> datetime:
        """Return post publication date."""
        
    def item_updateddate(self, item: Post) -> datetime:
        """Return post last modified date."""
        
    def item_categories(self, item: Post) -> List[str]:
        """Return post categories as feed categories."""
        
    def item_enclosure_url(self, item: Post) -> Optional[str]:
        """Return main image URL as enclosure."""
        
    def item_enclosure_length(self, item: Post) -> Optional[int]:
        """Return main image file size."""
        
    def item_enclosure_mime_type(self, item: Post) -> Optional[str]:
        """Return main image MIME type."""

Sitemap Generation

SEO-optimized sitemap generation for blog content.

class BlogSitemap(Sitemap):
    """
    Sitemap generator for blog posts.
    
    Features:
    - Multilingual URL generation
    - Configurable priority and change frequency
    - App configuration filtering
    - Automatic URL validation
    - Cache-optimized URL generation
    """
    
    def __init__(self, *args, **kwargs) -> None:
        """Initialize sitemap with URL cache."""
        
    def priority(self, obj: Post) -> float:
        """
        Return sitemap priority for post.
        
        Uses app configuration priority or default setting.
        Range: 0.0 to 1.0
        """
        
    def changefreq(self, obj: Post) -> str:
        """
        Return change frequency for post.
        
        Options: 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'
        Uses app configuration setting or default.
        """
        
    def location(self, obj: Post) -> str:
        """Return absolute URL for post in current language."""
        
    def items(self) -> List[Post]:
        """
        Return all published posts across all languages.
        
        Features:
        - Multi-language support
        - URL validation to exclude posts without valid URLs
        - App configuration filtering
        - Publication status filtering
        """
        
    def lastmod(self, obj: Post) -> datetime:
        """Return last modification date for post."""

Additional Feed Types

Specialized feed types for tag-based and Facebook Instant Articles content.

class TagFeed(LatestEntriesFeed):
    """
    RSS feed for posts filtered by specific tag.
    
    Features:
    - Tag-specific post filtering
    - Dynamic title and description based on tag  
    - Same feed functionality as LatestEntriesFeed
    """
    
    def get_object(self, request: HttpRequest, tag: str) -> Dict[str, Any]:
        """Get tag and blog configuration for feed context."""
        
    def title(self, obj: Dict[str, Any]) -> str:
        """Return feed title with tag name."""
        
    def description(self, obj: Dict[str, Any]) -> str:
        """Return feed description for tag."""
        
    def items(self, obj: Dict[str, Any]) -> QuerySet:
        """Return posts filtered by tag."""

class FBInstantArticles(LatestEntriesFeed):
    """
    Facebook Instant Articles feed with custom XML format.
    
    Features:
    - Facebook Instant Articles XML format
    - Custom RSS elements for Facebook compatibility
    - Media content optimization
    - Enhanced article metadata
    """
    
    content_type: str = 'application/rss+xml; charset=utf-8'
    
    def items(self, obj: BlogConfig) -> QuerySet:
        """Return posts optimized for Facebook Instant Articles."""
        
    def item_extra_kwargs(self, item: Post) -> Dict[str, Any]:
        """Add Facebook-specific metadata to feed items."""

Feed Customization

Base classes and utilities for creating custom feeds.

# Custom feed class example structure
class CustomBlogFeed(LatestEntriesFeed):
    """
    Base structure for custom blog feeds.
    
    Override methods to customize:
    - title(): Feed title
    - description(): Feed description  
    - items(): Item selection and filtering
    - item_title(): Individual item titles
    - item_description(): Individual item content
    """
    
    def items(self, obj: BlogConfig) -> QuerySet:
        """Custom item filtering logic."""
        
    def item_extra_kwargs(self, item: Post) -> Dict[str, Any]:
        """Add custom attributes to feed items."""

Feed and Sitemap Usage Examples

# URL configuration for feeds and sitemaps
from django.urls import path, include
from djangocms_blog.feeds import LatestEntriesFeed
from djangocms_blog.sitemaps import BlogSitemap

urlpatterns = [
    # RSS feed URL
    path('blog/feed/', LatestEntriesFeed(), name='blog-feed'),
    
    # Include blog URLs (includes feed URLs)
    path('blog/', include('djangocms_blog.urls', namespace='djangocms_blog')),
]

# Sitemap configuration in main urls.py
from django.contrib.sitemaps.views import sitemap
from djangocms_blog.sitemaps import BlogSitemap

sitemaps = {
    'blog': BlogSitemap,
}

urlpatterns += [
    path('sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
]

# Custom feed creation
from djangocms_blog.feeds import LatestEntriesFeed
from djangocms_blog.models import Post

class FeaturedPostsFeed(LatestEntriesFeed):
    """RSS feed for featured posts only."""
    
    def title(self, obj):
        return f"{obj.app_title} - Featured Posts"
    
    def description(self, obj):
        return f"Featured posts from {obj.app_title}"
    
    def items(self, obj):
        """Return only featured posts."""
        return Post.objects.published().filter(
            app_config=obj,
            featured=True,
            include_in_rss=True
        ).order_by('-date_published')[:self.feed_items_number]

class CategoryFeed(LatestEntriesFeed):
    """RSS feed for specific category."""
    
    def get_object(self, request, category_slug):
        """Get category and config for feed."""
        from djangocms_blog.models import BlogCategory
        from aldryn_apphooks_config.utils import get_app_instance
        
        namespace, config = get_app_instance(request)
        category = BlogCategory.objects.translated().get(
            slug=category_slug,
            app_config=config
        )
        return {'config': config, 'category': category}
    
    def title(self, obj):
        return f"{obj['config'].app_title} - {obj['category'].name}"
    
    def items(self, obj):
        """Return posts in specific category."""
        return Post.objects.published().filter(
            app_config=obj['config'],
            categories=obj['category'],
            include_in_rss=True
        ).order_by('-date_published')[:self.feed_items_number]

# Custom feed with media enclosures
class MediaEnhancedFeed(LatestEntriesFeed):
    """Feed with enhanced media support."""
    
    def item_extra_kwargs(self, item):
        """Add custom media information."""
        kwargs = super().item_extra_kwargs(item)
        
        # Add main image as enclosure
        if item.main_image:
            kwargs.update({
                'enclosure': {
                    'url': item.main_image.url,
                    'length': str(item.main_image.size),
                    'type': 'image/jpeg'  # or detect from file
                }
            })
        
        return kwargs
    
    def item_description(self, item):
        """Enhanced description with media."""
        description = super().item_description(item)
        
        # Add main image to description
        if item.main_image:
            img_tag = f'<img src="{item.main_image.url}" alt="{item.title}" />'
            description = f"{img_tag}<br/>{description}"
        
        return description

# Custom sitemap with additional URLs
from django.contrib.sitemaps import Sitemap
from djangocms_blog.models import BlogCategory

class BlogCategorySitemap(Sitemap):
    """Sitemap for blog categories."""
    
    priority = 0.6
    changefreq = 'weekly'
    
    def items(self):
        """Return all published categories."""
        return BlogCategory.objects.translated().published()
    
    def location(self, obj):
        """Return category URL."""
        return obj.get_absolute_url()
    
    def lastmod(self, obj):
        """Return last modification based on latest post in category."""
        latest_post = Post.objects.published().filter(
            categories=obj
        ).order_by('-date_modified').first()
        
        return latest_post.date_modified if latest_post else None

# Multiple sitemaps registration
sitemaps = {
    'blog_posts': BlogSitemap,
    'blog_categories': BlogCategorySitemap,
}

# Feed autodiscovery in templates
# Add to base template <head> section:
# {% load cms_tags %}
# {% page_url 'posts-latest-feed' as feed_url %}
# <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="{{ feed_url }}">

# Settings customization
# In Django settings.py:
BLOG_FEED_LATEST_ITEMS = 20
BLOG_FEED_ENABLE = True
BLOG_SITEMAP_PRIORITY_DEFAULT = 0.7
BLOG_SITEMAP_CHANGEFREQ_DEFAULT = 'weekly'

# Per-configuration customization
# In BlogConfig app_data:
{
    'feed_latest_items': 15,
    'sitemap_priority': 0.8,
    'sitemap_changefreq': 'daily'
}

# Conditional feed inclusion
class ConditionalFeed(LatestEntriesFeed):
    """Feed that respects post RSS inclusion setting."""
    
    def items(self, obj):
        """Only include posts marked for RSS."""
        return super().items(obj).filter(include_in_rss=True)

# Feed with custom namespace support
from django.urls import path

# Per-apphook feed URLs
app_name = 'blog_feeds'
urlpatterns = [
    path('feed/', LatestEntriesFeed(), name='latest'),
    path('featured/', FeaturedPostsFeed(), name='featured'),
    path('category/<slug:category_slug>/', CategoryFeed(), name='category'),
]

# Access in templates:
# {% url 'blog_feeds:latest' %}
# {% url 'blog_feeds:featured' %}
# {% url 'blog_feeds:category' category.slug %}

Install with Tessl CLI

npx tessl i tessl/pypi-djangocms-blog

docs

admin-forms.md

cms-integration.md

configuration.md

feeds-sitemaps.md

index.md

models.md

templates-utilities.md

views.md

tile.json