diff --git a/docs/en/user-guide/templates.md b/docs/en/user-guide/templates.md index 5a37747..7314929 100644 --- a/docs/en/user-guide/templates.md +++ b/docs/en/user-guide/templates.md @@ -22,7 +22,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Blurred background card style, suitable for graphic content display @@ -30,7 +30,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Cartoon style, suitable for light and lively content @@ -38,7 +38,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Default template, simple and versatile @@ -46,7 +46,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Elegant style, suitable for artistic and intellectual content @@ -54,7 +54,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Retro fashion style, suitable for nostalgic themes @@ -62,7 +62,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Life insight style, suitable for inspirational content @@ -70,7 +70,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Modern minimalist style, suitable for business and tech content @@ -78,7 +78,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Neon style, suitable for fashion and trendy content @@ -86,7 +86,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Psychology card style, suitable for knowledge popularization @@ -94,7 +94,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Purple theme, suitable for dreamy and mysterious styles @@ -102,7 +102,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Minimalist style, highlighting the content itself @@ -110,7 +110,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  80s satirical cartoon style for spiritual tales @@ -118,7 +118,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Simple black background, suitable for inspirational content @@ -126,7 +126,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Simple line drawing style for cognitive growth content @@ -134,7 +134,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Book style, suitable for book lists @@ -142,7 +142,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Long text style, suitable for inspirational content @@ -150,7 +150,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Excerpt style, suitable for quotes and book excerpts @@ -158,7 +158,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Health preserving tips, suitable for wellness explainers. @@ -166,7 +166,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Life insights, conveying warmth and strength @@ -174,7 +174,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Full screen display, suitable for book lists @@ -182,7 +182,7 @@ Suitable for TikTok, Kuaishou, Xiaohongshu, and other short video platforms. --- -  +  Healing style, suitable for therapeutic content @@ -199,7 +199,7 @@ Suitable for YouTube, Bilibili, and other video platforms. --- -  +  Ultrawide minimalist style, suitable for desktop viewing @@ -207,7 +207,7 @@ Suitable for YouTube, Bilibili, and other video platforms. --- -  +  Dark tech style, suitable for technology and gaming content @@ -215,7 +215,7 @@ Suitable for YouTube, Bilibili, and other video platforms. --- -  +  Film style, immersive experience @@ -223,7 +223,7 @@ Suitable for YouTube, Bilibili, and other video platforms. --- -  +  Full screen display, suitable for book lists @@ -231,7 +231,7 @@ Suitable for YouTube, Bilibili, and other video platforms. --- -  +  Book style, suitable for book lists @@ -249,7 +249,7 @@ Suitable for Instagram, WeChat Moments, and other platforms. --- -  +  Minimalist framed style, suitable for social media sharing diff --git a/docs/images/1080x1080/minimal_framed.jpg b/docs/images/1080x1080/image_minimal_framed.jpg similarity index 100% rename from docs/images/1080x1080/minimal_framed.jpg rename to docs/images/1080x1080/image_minimal_framed.jpg diff --git a/docs/images/1080x1080/minimal_framed_en.jpg b/docs/images/1080x1080/image_minimal_framed_en.jpg similarity index 100% rename from docs/images/1080x1080/minimal_framed_en.jpg rename to docs/images/1080x1080/image_minimal_framed_en.jpg diff --git a/docs/images/1080x1920/blur_card.png b/docs/images/1080x1920/image_blur_card.png similarity index 100% rename from docs/images/1080x1920/blur_card.png rename to docs/images/1080x1920/image_blur_card.png diff --git a/docs/images/1080x1920/blur_card_en.jpg b/docs/images/1080x1920/image_blur_card_en.jpg similarity index 100% rename from docs/images/1080x1920/blur_card_en.jpg rename to docs/images/1080x1920/image_blur_card_en.jpg diff --git a/docs/images/1080x1920/book.jpg b/docs/images/1080x1920/image_book.jpg similarity index 100% rename from docs/images/1080x1920/book.jpg rename to docs/images/1080x1920/image_book.jpg diff --git a/docs/images/1080x1920/book_en.jpg b/docs/images/1080x1920/image_book_en.jpg similarity index 100% rename from docs/images/1080x1920/book_en.jpg rename to docs/images/1080x1920/image_book_en.jpg diff --git a/docs/images/1080x1920/cartoon.png b/docs/images/1080x1920/image_cartoon.png similarity index 100% rename from docs/images/1080x1920/cartoon.png rename to docs/images/1080x1920/image_cartoon.png diff --git a/docs/images/1080x1920/cartoon_en.jpg b/docs/images/1080x1920/image_cartoon_en.jpg similarity index 100% rename from docs/images/1080x1920/cartoon_en.jpg rename to docs/images/1080x1920/image_cartoon_en.jpg diff --git a/docs/images/1080x1920/default.jpg b/docs/images/1080x1920/image_default.jpg similarity index 100% rename from docs/images/1080x1920/default.jpg rename to docs/images/1080x1920/image_default.jpg diff --git a/docs/images/1080x1920/default_en.jpg b/docs/images/1080x1920/image_default_en.jpg similarity index 100% rename from docs/images/1080x1920/default_en.jpg rename to docs/images/1080x1920/image_default_en.jpg diff --git a/docs/images/1080x1920/elegant.jpg b/docs/images/1080x1920/image_elegant.jpg similarity index 100% rename from docs/images/1080x1920/elegant.jpg rename to docs/images/1080x1920/image_elegant.jpg diff --git a/docs/images/1080x1920/elegant_en.jpg b/docs/images/1080x1920/image_elegant_en.jpg similarity index 100% rename from docs/images/1080x1920/elegant_en.jpg rename to docs/images/1080x1920/image_elegant_en.jpg diff --git a/docs/images/1080x1920/excerpt.jpg b/docs/images/1080x1920/image_excerpt.jpg similarity index 100% rename from docs/images/1080x1920/excerpt.jpg rename to docs/images/1080x1920/image_excerpt.jpg diff --git a/docs/images/1080x1920/excerpt_en.jpg b/docs/images/1080x1920/image_excerpt_en.jpg similarity index 100% rename from docs/images/1080x1920/excerpt_en.jpg rename to docs/images/1080x1920/image_excerpt_en.jpg diff --git a/docs/images/1080x1920/fashion_vintage.jpg b/docs/images/1080x1920/image_fashion_vintage.jpg similarity index 100% rename from docs/images/1080x1920/fashion_vintage.jpg rename to docs/images/1080x1920/image_fashion_vintage.jpg diff --git a/docs/images/1080x1920/fashion_vintage_en.jpg b/docs/images/1080x1920/image_fashion_vintage_en.jpg similarity index 100% rename from docs/images/1080x1920/fashion_vintage_en.jpg rename to docs/images/1080x1920/image_fashion_vintage_en.jpg diff --git a/docs/images/1080x1920/full.jpg b/docs/images/1080x1920/image_full.jpg similarity index 100% rename from docs/images/1080x1920/full.jpg rename to docs/images/1080x1920/image_full.jpg diff --git a/docs/images/1080x1920/full_en.jpg b/docs/images/1080x1920/image_full_en.jpg similarity index 100% rename from docs/images/1080x1920/full_en.jpg rename to docs/images/1080x1920/image_full_en.jpg diff --git a/docs/images/1080x1920/healing.jpg b/docs/images/1080x1920/image_healing.jpg similarity index 100% rename from docs/images/1080x1920/healing.jpg rename to docs/images/1080x1920/image_healing.jpg diff --git a/docs/images/1080x1920/healing_en.jpg b/docs/images/1080x1920/image_healing_en.jpg similarity index 100% rename from docs/images/1080x1920/healing_en.jpg rename to docs/images/1080x1920/image_healing_en.jpg diff --git a/docs/images/1080x1920/health_preservation.jpg b/docs/images/1080x1920/image_health_preservation.jpg similarity index 100% rename from docs/images/1080x1920/health_preservation.jpg rename to docs/images/1080x1920/image_health_preservation.jpg diff --git a/docs/images/1080x1920/health_preservation_en.jpg b/docs/images/1080x1920/image_health_preservation_en.jpg similarity index 100% rename from docs/images/1080x1920/health_preservation_en.jpg rename to docs/images/1080x1920/image_health_preservation_en.jpg diff --git a/docs/images/1080x1920/life_insights.jpg b/docs/images/1080x1920/image_life_insights.jpg similarity index 100% rename from docs/images/1080x1920/life_insights.jpg rename to docs/images/1080x1920/image_life_insights.jpg diff --git a/docs/images/1080x1920/life_insights_en.jpg b/docs/images/1080x1920/image_life_insights_en.jpg similarity index 100% rename from docs/images/1080x1920/life_insights_en.jpg rename to docs/images/1080x1920/image_life_insights_en.jpg diff --git a/docs/images/1080x1920/life_insights_light.jpg b/docs/images/1080x1920/image_life_insights_light.jpg similarity index 100% rename from docs/images/1080x1920/life_insights_light.jpg rename to docs/images/1080x1920/image_life_insights_light.jpg diff --git a/docs/images/1080x1920/life_insights_light_en.jpg b/docs/images/1080x1920/image_life_insights_light_en.jpg similarity index 100% rename from docs/images/1080x1920/life_insights_light_en.jpg rename to docs/images/1080x1920/image_life_insights_light_en.jpg diff --git a/docs/images/1080x1920/long_text.jpg b/docs/images/1080x1920/image_long_text.jpg similarity index 100% rename from docs/images/1080x1920/long_text.jpg rename to docs/images/1080x1920/image_long_text.jpg diff --git a/docs/images/1080x1920/long_text_en.jpg b/docs/images/1080x1920/image_long_text_en.jpg similarity index 100% rename from docs/images/1080x1920/long_text_en.jpg rename to docs/images/1080x1920/image_long_text_en.jpg diff --git a/docs/images/1080x1920/modern.jpg b/docs/images/1080x1920/image_modern.jpg similarity index 100% rename from docs/images/1080x1920/modern.jpg rename to docs/images/1080x1920/image_modern.jpg diff --git a/docs/images/1080x1920/modern_en.jpg b/docs/images/1080x1920/image_modern_en.jpg similarity index 100% rename from docs/images/1080x1920/modern_en.jpg rename to docs/images/1080x1920/image_modern_en.jpg diff --git a/docs/images/1080x1920/neon.jpg b/docs/images/1080x1920/image_neon.jpg similarity index 100% rename from docs/images/1080x1920/neon.jpg rename to docs/images/1080x1920/image_neon.jpg diff --git a/docs/images/1080x1920/neon_en.jpg b/docs/images/1080x1920/image_neon_en.jpg similarity index 100% rename from docs/images/1080x1920/neon_en.jpg rename to docs/images/1080x1920/image_neon_en.jpg diff --git a/docs/images/1080x1920/psychology_card.jpg b/docs/images/1080x1920/image_psychology_card.jpg similarity index 100% rename from docs/images/1080x1920/psychology_card.jpg rename to docs/images/1080x1920/image_psychology_card.jpg diff --git a/docs/images/1080x1920/psychology_card_en.jpg b/docs/images/1080x1920/image_psychology_card_en.jpg similarity index 100% rename from docs/images/1080x1920/psychology_card_en.jpg rename to docs/images/1080x1920/image_psychology_card_en.jpg diff --git a/docs/images/1080x1920/purple.jpg b/docs/images/1080x1920/image_purple.jpg similarity index 100% rename from docs/images/1080x1920/purple.jpg rename to docs/images/1080x1920/image_purple.jpg diff --git a/docs/images/1080x1920/purple_en.jpg b/docs/images/1080x1920/image_purple_en.jpg similarity index 100% rename from docs/images/1080x1920/purple_en.jpg rename to docs/images/1080x1920/image_purple_en.jpg diff --git a/docs/images/1080x1920/satirical_cartoon.jpg b/docs/images/1080x1920/image_satirical_cartoon.jpg similarity index 100% rename from docs/images/1080x1920/satirical_cartoon.jpg rename to docs/images/1080x1920/image_satirical_cartoon.jpg diff --git a/docs/images/1080x1920/satirical_cartoon_en.jpg b/docs/images/1080x1920/image_satirical_cartoon_en.jpg similarity index 100% rename from docs/images/1080x1920/satirical_cartoon_en.jpg rename to docs/images/1080x1920/image_satirical_cartoon_en.jpg diff --git a/docs/images/1080x1920/simple.jpg b/docs/images/1080x1920/image_simple.jpg similarity index 100% rename from docs/images/1080x1920/simple.jpg rename to docs/images/1080x1920/image_simple.jpg diff --git a/docs/images/1080x1920/simple_black.jpg b/docs/images/1080x1920/image_simple_black.jpg similarity index 100% rename from docs/images/1080x1920/simple_black.jpg rename to docs/images/1080x1920/image_simple_black.jpg diff --git a/docs/images/1080x1920/simple_black_en.jpg b/docs/images/1080x1920/image_simple_black_en.jpg similarity index 100% rename from docs/images/1080x1920/simple_black_en.jpg rename to docs/images/1080x1920/image_simple_black_en.jpg diff --git a/docs/images/1080x1920/simple_en.jpg b/docs/images/1080x1920/image_simple_en.jpg similarity index 100% rename from docs/images/1080x1920/simple_en.jpg rename to docs/images/1080x1920/image_simple_en.jpg diff --git a/docs/images/1080x1920/simple_line_drawing.jpg b/docs/images/1080x1920/image_simple_line_drawing.jpg similarity index 100% rename from docs/images/1080x1920/simple_line_drawing.jpg rename to docs/images/1080x1920/image_simple_line_drawing.jpg diff --git a/docs/images/1080x1920/simple_line_drawing_en.jpg b/docs/images/1080x1920/image_simple_line_drawing_en.jpg similarity index 100% rename from docs/images/1080x1920/simple_line_drawing_en.jpg rename to docs/images/1080x1920/image_simple_line_drawing_en.jpg diff --git a/docs/images/1920x1080/book.jpg b/docs/images/1920x1080/image_book.jpg similarity index 100% rename from docs/images/1920x1080/book.jpg rename to docs/images/1920x1080/image_book.jpg diff --git a/docs/images/1920x1080/book_en.jpg b/docs/images/1920x1080/image_book_en.jpg similarity index 100% rename from docs/images/1920x1080/book_en.jpg rename to docs/images/1920x1080/image_book_en.jpg diff --git a/docs/images/1920x1080/film.jpg b/docs/images/1920x1080/image_film.jpg similarity index 100% rename from docs/images/1920x1080/film.jpg rename to docs/images/1920x1080/image_film.jpg diff --git a/docs/images/1920x1080/film_en.jpg b/docs/images/1920x1080/image_film_en.jpg similarity index 100% rename from docs/images/1920x1080/film_en.jpg rename to docs/images/1920x1080/image_film_en.jpg diff --git a/docs/images/1920x1080/full.jpg b/docs/images/1920x1080/image_full.jpg similarity index 100% rename from docs/images/1920x1080/full.jpg rename to docs/images/1920x1080/image_full.jpg diff --git a/docs/images/1920x1080/full_en.jpg b/docs/images/1920x1080/image_full_en.jpg similarity index 100% rename from docs/images/1920x1080/full_en.jpg rename to docs/images/1920x1080/image_full_en.jpg diff --git a/docs/images/1920x1080/ultrawide_minimal.jpg b/docs/images/1920x1080/image_ultrawide_minimal.jpg similarity index 100% rename from docs/images/1920x1080/ultrawide_minimal.jpg rename to docs/images/1920x1080/image_ultrawide_minimal.jpg diff --git a/docs/images/1920x1080/ultrawide_minimal_en.jpg b/docs/images/1920x1080/image_ultrawide_minimal_en.jpg similarity index 100% rename from docs/images/1920x1080/ultrawide_minimal_en.jpg rename to docs/images/1920x1080/image_ultrawide_minimal_en.jpg diff --git a/docs/images/1920x1080/wide_darktech.jpg b/docs/images/1920x1080/image_wide_darktech.jpg similarity index 100% rename from docs/images/1920x1080/wide_darktech.jpg rename to docs/images/1920x1080/image_wide_darktech.jpg diff --git a/docs/images/1920x1080/wide_darktech_en.jpg b/docs/images/1920x1080/image_wide_darktech_en.jpg similarity index 100% rename from docs/images/1920x1080/wide_darktech_en.jpg rename to docs/images/1920x1080/image_wide_darktech_en.jpg diff --git a/docs/zh/user-guide/templates.md b/docs/zh/user-guide/templates.md index 595d8ce..cf7b7d6 100644 --- a/docs/zh/user-guide/templates.md +++ b/docs/zh/user-guide/templates.md @@ -22,7 +22,7 @@ --- -  +  模糊背景卡片风格,适合图文内容展示 @@ -30,7 +30,7 @@ --- -  +  卡通风格,适合轻松活泼的内容 @@ -38,7 +38,7 @@ --- -  +  默认模板,简洁通用 @@ -46,7 +46,7 @@ --- -  +  优雅风格,适合文艺、知性内容 @@ -54,7 +54,7 @@ --- -  +  复古时尚风格,适合怀旧主题 @@ -62,7 +62,7 @@ --- -  +  生活感悟风格,适合心灵鸡汤类内容 @@ -70,7 +70,7 @@ --- -  +  现代简约风格,适合商务、科技内容 @@ -78,7 +78,7 @@ --- -  +  霓虹灯风格,适合时尚、潮流内容 @@ -86,7 +86,7 @@ --- -  +  心理学卡片风格,适合知识科普 @@ -94,7 +94,7 @@ --- -  +  紫色主题,适合梦幻、神秘风格 @@ -102,7 +102,7 @@ --- -  +  极简风格,突出内容本身 @@ -110,7 +110,7 @@ --- -  +  80年代讽刺漫画风格,适合精神类小故事 @@ -118,7 +118,7 @@ --- -  +  极简黑色背景,适合心灵鸡汤类内容 @@ -126,7 +126,7 @@ --- -  +  简笔画,适合认知成长类内容 @@ -134,7 +134,7 @@ --- -  +  图书解读,适合科普类内容 @@ -142,7 +142,7 @@ --- -  +  长文本,适合励志鸡汤类内容 @@ -150,7 +150,7 @@ --- -  +  图文摘抄,适合图文摘抄,名人名言 @@ -158,7 +158,7 @@ --- -  +  养生窍门,适合养生科普内容 @@ -166,7 +166,7 @@ --- -  +  人生感悟,传递温暖与力量 @@ -174,7 +174,7 @@ --- -  +  全屏模版,适合书单号 @@ -182,7 +182,7 @@ --- -  +  治愈模版,适合疗愈类内容 @@ -199,7 +199,7 @@ --- -  +  超宽屏极简风格,适合桌面端观看 @@ -207,7 +207,7 @@ --- -  +  暗黑科技风格,适合技术、游戏内容 @@ -215,7 +215,7 @@ --- -  +  电影风格,沉浸式体验 @@ -223,7 +223,7 @@ --- -  +  全屏显示,适合书单号 @@ -231,7 +231,7 @@ --- -  +  图书解读,适合科普类内容 @@ -248,7 +248,7 @@ --- -  +  极简边框风格,适合社交媒体分享 diff --git a/web/components/style_config.py b/web/components/style_config.py index e92037d..4df81a9 100644 --- a/web/components/style_config.py +++ b/web/components/style_config.py @@ -228,6 +228,46 @@ def render_style_config(pixelle_video): # ==================================================================== # Storyboard Template Section # ==================================================================== + + def get_template_preview_path(template_path: str, language: str = "zh_CN") -> str: + """ + Get the preview image path for a template based on language. + + Args: + template_path: Template path like "1080x1920/image_default.html" + language: Language code, either "zh_CN" or "en" + + Returns: + Path to preview image in docs/images/ + """ + # Extract size and template name from path + # e.g., "1080x1920/image_default.html" -> size="1080x1920", name="image_default" + path_parts = template_path.split('/') + if len(path_parts) >= 2: + size = path_parts[0] # e.g., "1080x1920" + template_file = path_parts[1] # e.g., "image_default.html" + template_name = template_file.replace('.html', '') # e.g., "image_default" + + # Build preview image path + # Format: docs/images/{size}/{template_name}.jpg or {template_name}_en.jpg + # Chinese uses Chinese preview, all other languages use English preview for better i18n + suffix = "" if language == "zh_CN" else "_en" + + # Try different image extensions + for ext in ['.jpg', '.png']: + preview_path = f"docs/images/{size}/{template_name}{suffix}{ext}" + if os.path.exists(preview_path): + return preview_path + + # Fallback: try without language suffix (for templates with only one version) + for ext in ['.jpg', '.png']: + preview_path = f"docs/images/{size}/{template_name}{ext}" + if os.path.exists(preview_path): + return preview_path + + # If no preview found, return empty string + return "" + with st.container(border=True): st.markdown(f"**{tr('section.template')}**") @@ -284,18 +324,13 @@ def render_style_config(pixelle_video): st.warning(f"No {template_type_options[selected_template_type]} templates found. Please select a different type or add templates.") st.stop() - # Build display options with group separators + # Build orientation i18n mapping ORIENTATION_I18N = { 'portrait': tr('orientation.portrait'), 'landscape': tr('orientation.landscape'), 'square': tr('orientation.square') } - display_options = [] - template_paths_ordered = [] # Use ordered list instead of dict to avoid key conflicts - default_index = 0 - current_index = 0 - # Get default template from config template_config = pixelle_video.config.get("template", {}) config_default_template = template_config.get("default_template", "1080x1920/image_default.html") @@ -312,68 +347,145 @@ def render_style_config(pixelle_video): } type_specific_default = type_default_templates.get(selected_template_type, config_default_template) + # Initialize selected template in session state if not exists + if 'selected_template' not in st.session_state: + st.session_state['selected_template'] = type_specific_default + + # Collect size groups and prepare tabs + size_groups = [] + size_labels = [] + for size, templates in grouped_templates.items(): if not templates: continue + # Filter templates to only include those with proper naming convention + # Only show templates starting with static_, image_, or video_ + valid_templates = [] + for template in templates: + template_name = template.display_info.name + if template_name.startswith(('static_', 'image_', 'video_')): + valid_templates.append(template) + + # Skip if no valid templates after filtering + if not valid_templates: + continue + + # Separate templates into two groups: with preview and without preview + templates_with_preview = [] + templates_without_preview = [] + + for template in valid_templates: + preview_path = get_template_preview_path(template.template_path, current_lang) + if preview_path and os.path.exists(preview_path): + templates_with_preview.append(template) + else: + templates_without_preview.append(template) + + # Skip this group if no templates at all + if not templates_with_preview and not templates_without_preview: + continue + + # Combine: templates with preview first, then without preview + all_templates = templates_with_preview + templates_without_preview + # Get orientation from first template in group orientation = ORIENTATION_I18N.get( - templates[0].display_info.orientation, - templates[0].display_info.orientation + all_templates[0].display_info.orientation, + all_templates[0].display_info.orientation ) - width = templates[0].display_info.width - height = templates[0].display_info.height + width = all_templates[0].display_info.width + height = all_templates[0].display_info.height - # Add group separator - separator = f"─── {orientation} {width}×{height} ───" - display_options.append(separator) - template_paths_ordered.append(None) # Separator has no template path - current_index += 1 + # Create tab label + tab_label = f"{orientation} {width}×{height}" + size_labels.append(tab_label) + size_groups.append(all_templates) + + # Create tabs for each size group (wrapped in expander) + with st.expander(tr("template.gallery_view"), expanded=True): + if size_groups: + tabs = st.tabs(size_labels) + + for tab, all_templates in zip(tabs, size_groups): + with tab: + # Create grid layout (5 columns) + num_cols = 5 + cols = st.columns(num_cols) + + for idx, template in enumerate(all_templates): + col_idx = idx % num_cols + with cols[col_idx]: + # Get preview image path + preview_path = get_template_preview_path(template.template_path, current_lang) + + # Display preview image or placeholder + if preview_path and os.path.exists(preview_path): + st.image(preview_path, use_container_width=True) + else: + # Placeholder for templates without preview (fixed height, compact layout) + st.markdown( + f""" +