2026-05-10 07:08:12 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
2026-06-15 12:10:14 +00:00
< meta name = "viewport" content = "width=device-width, initial-scale=1.0, viewport-fit=cover" >
2026-05-23 01:21:55 +00:00
< meta name = "theme-color" content = "#0f0a1a" >
2026-06-14 00:16:22 +00:00
< meta name = "asset-version" content = "{{ static_version }}" >
2026-05-22 23:50:31 +00:00
< title > {% if page_title %}{{ page_title }}{% else %}DevPlace - The Developer Social Network{% endif %}</ title >
2026-05-11 03:30:51 +00:00
< meta name = "description" content = "{% if meta_description %}{{ meta_description }}{% else %}Track industry shifts. Discover bold releases. Share what you're building in an open, uncensored environment.{% endif %}" >
< link rel = "canonical" href = "{{ canonical_url or request.url }}" >
2026-06-05 18:05:07 +00:00
{% if prev_url %}< link rel = "prev" href = "{{ prev_url }}" > {% endif %}
{% if next_url %}< link rel = "next" href = "{{ next_url }}" > {% endif %}
2026-05-11 03:30:51 +00:00
< meta name = "robots" content = "{{ meta_robots or 'index,follow' }}" >
2026-06-19 20:15:22 +00:00
{% if meta_keywords %}< meta name = "keywords" content = "{{ meta_keywords }}" > {% endif %}
2026-05-11 03:30:51 +00:00
< meta property = "og:title" content = "{{ og_title or page_title or 'DevPlace' }}" >
< meta property = "og:description" content = "{{ og_description or meta_description or 'The Developer Social Network' }}" >
< meta property = "og:type" content = "{{ og_type or 'website' }}" >
< meta property = "og:url" content = "{{ canonical_url or request.url }}" >
2026-06-14 00:16:22 +00:00
< meta property = "og:image" content = "{{ static_url(og_image or '/static/og-default.png') }}" >
2026-06-19 20:15:22 +00:00
{% if not og_image or og_image == '/static/og-default.png' %}
< meta property = "og:image:width" content = "1200" >
< meta property = "og:image:height" content = "630" >
{% endif %}
< meta property = "og:image:alt" content = "{{ og_title or page_title or 'DevPlace' }}" >
2026-05-11 03:30:51 +00:00
< meta property = "og:site_name" content = "DevPlace" >
< meta property = "og:locale" content = "en_US" >
< meta name = "twitter:card" content = "summary_large_image" >
< meta name = "twitter:title" content = "{{ og_title or page_title or 'DevPlace' }}" >
< meta name = "twitter:description" content = "{{ og_description or meta_description or 'The Developer Social Network' }}" >
2026-06-14 00:16:22 +00:00
< meta name = "twitter:image" content = "{{ static_url(og_image or '/static/og-default.png') }}" >
2026-06-19 20:15:22 +00:00
< meta name = "twitter:image:alt" content = "{{ og_title or page_title or 'DevPlace' }}" >
2026-05-11 03:30:51 +00:00
< link rel = "icon" href = "data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>💻</text></svg>" >
2026-06-14 00:16:22 +00:00
< link rel = "apple-touch-icon" href = "{{ static_url('/static/apple-touch-icon.png') }}" >
2026-05-23 08:03:27 +00:00
< link rel = "manifest" href = "/manifest.json" >
2026-05-23 08:35:40 +00:00
< meta name = "mobile-web-app-capable" content = "yes" >
2026-05-23 08:03:27 +00:00
< meta name = "apple-mobile-web-app-capable" content = "yes" >
< meta name = "apple-mobile-web-app-status-bar-style" content = "black-translucent" >
< meta name = "apple-mobile-web-app-title" content = "DevPlace" >
2026-05-11 03:30:51 +00:00
2026-07-06 03:57:47 +00:00
< link rel = "modulepreload" href = "{{ static_url('/static/js/Application.js') }}" >
< link rel = "modulepreload" href = "{{ static_url('/static/js/components/index.js') }}" >
2026-06-14 00:16:22 +00:00
< link rel = "stylesheet" href = "{{ static_url('/static/css/variables.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/base.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/components.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/vendor/atom-one-dark.min.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/markdown.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/mention.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/attachments.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/lightbox.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/media.css') }}" >
< link rel = "stylesheet" href = "{{ static_url('/static/css/engagement.css') }}" >
2026-05-10 07:08:12 +00:00
{% block extra_head %}{% endblock %}
2026-06-09 14:06:02 +00:00
{{ custom_css_tag(request) }}
2026-06-19 20:15:22 +00:00
{{ extra_head_tag() }}
2026-05-11 03:30:51 +00:00
{% if page_schema %}
< script type = "application/ld+json" >
{{ page_schema | safe }}
</ script >
{% endif %}
2026-05-10 07:08:12 +00:00
</ head >
2026-07-04 22:08:20 +00:00
< body data-user-uid = "{{ user['uid'] if user else '' }}" data-presence-timeout = "{{ presence_timeout }}" >
2026-06-19 08:06:09 +00:00
< a class = "skip-link" href = "#main-content" > Skip to main content</ a >
< nav class = "topnav" aria-label = "Primary" >
2026-05-10 07:08:12 +00:00
< div class = "topnav-inner" >
< a href = "/feed" class = "topnav-logo" > Dev< span > Place</ span ></ a >
< div class = "topnav-links" >
2026-06-19 08:06:09 +00:00
< a href = "/" class = "topnav-link {{ nav_active(request, '/') }}" >< span class = "icon" > 🏠</ span > Home</ a >
< a href = "/feed" class = "topnav-link {{ nav_active(request, '/feed') }}" >< span class = "icon" > 📝</ span > Posts</ a >
< a href = "/news" class = "topnav-link {{ nav_active(request, '/news') }}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/gists" class = "topnav-link {{ nav_active(request, '/gists') }}" >< span class = "icon" > 📄</ span > Gists</ a >
< a href = "/projects" class = "topnav-link {{ nav_active(request, '/projects') }}" >< span class = "icon" > 🚀</ span > Projects</ a >
2026-06-22 16:41:53 +00:00
{% if user %}< a href = "/game" class = "topnav-link {{ nav_active(request, '/game') }}" >< span class = "icon" > 🌱</ span > Farm</ a > {% endif %}
2026-06-22 17:53:20 +00:00
</ div >
< div class = "topnav-right" >
< a href = "/leaderboard" class = "topnav-icon {{ nav_active(request, '/leaderboard') }}" title = "Leaderboard" aria-label = "Leaderboard" >
< span class = "nav-bell" aria-hidden = "true" > 🏆</ span >
</ a >
2026-06-19 08:06:09 +00:00
< div class = "topnav-tools-dropdown {{ nav_active(request, '/tools') }}" >
2026-06-22 17:53:20 +00:00
< button type = "button" class = "topnav-icon topnav-tools-toggle" aria-expanded = "false" aria-controls = "tools-menu" title = "Tools" aria-label = "Tools" >< span class = "nav-bell" aria-hidden = "true" > 🧰</ span ></ button >
2026-06-19 08:06:09 +00:00
< div class = "dropdown-menu" id = "tools-menu" >
2026-06-14 00:16:22 +00:00
< a href = "/tools/seo" class = "dropdown-item" >< span class = "icon" > 🔍</ span > SEO Diagnostics</ a >
2026-06-14 01:34:21 +00:00
< a href = "/tools/deepsearch" class = "dropdown-item" >< span class = "icon" > 🧠</ span > DeepSearch</ a >
2026-07-06 03:57:47 +00:00
< a href = "/tools/isslop" class = "dropdown-item" >< span class = "icon" > 🧪</ span > AI Usage Analyzer</ a >
2026-06-14 00:16:22 +00:00
</ div >
</ div >
2026-05-12 10:45:52 +00:00
{% if user %}
2026-06-14 07:48:10 +00:00
{% set msg_unread = get_unread_messages(user["uid"]) %}
2026-06-19 08:06:09 +00:00
< a href = "/messages" class = "topnav-icon {{ nav_active(request, '/messages') }}" data-counter = "messages" data-counter-noun = "messages" title = "Messages" aria-label = "{% if msg_unread %}{{ msg_unread }} unread messages{% else %}Messages, no unread{% endif %}" >
< span class = "nav-bell" aria-hidden = "true" > ✉️< span class = "nav-badge" data-counter-badge {% if msg_unread = = 0 %} hidden {% endif %} > {{ msg_unread }}</ span ></ span >
2026-06-14 01:06:18 +00:00
</ a >
2026-05-23 08:03:27 +00:00
< button type = "button" class = "topnav-icon" data-push-enable hidden title = "Enable push notifications" aria-label = "Enable push notifications" >
2026-06-06 14:31:42 +00:00
< span class = "nav-bell" > 🔕</ span >
2026-05-23 08:03:27 +00:00
</ button >
2026-06-14 07:48:10 +00:00
{% set unread_count = get_unread_count(user["uid"]) %}
2026-06-19 08:06:09 +00:00
< a href = "/notifications" class = "topnav-icon" data-counter = "notifications" data-counter-noun = "notifications" title = "Notifications" aria-label = "{% if unread_count %}{{ unread_count }} unread notifications{% else %}Notifications, no unread{% endif %}" >
< span class = "nav-bell" aria-hidden = "true" > 🔔< span class = "nav-badge" data-counter-badge {% if unread_count = = 0 %} hidden {% endif %} > {{ unread_count }}</ span ></ span >
2026-05-10 07:08:12 +00:00
</ a >
2026-06-14 01:06:18 +00:00
{% if is_admin(user) %}
2026-06-19 08:06:09 +00:00
< a href = "/admin" class = "topnav-icon {{ nav_active(request, '/admin') }}" title = "Admin" aria-label = "Admin" >
2026-06-14 01:06:18 +00:00
< span class = "nav-bell" > ⚙️</ span >
</ a >
{% endif %}
2026-05-12 10:45:52 +00:00
< div class = "topnav-user-dropdown" >
2026-06-19 08:06:09 +00:00
< button type = "button" class = "topnav-user" aria-label = "User menu" aria-expanded = "false" aria-controls = "user-menu" >
2026-07-09 02:52:54 +02:00
< span class = "avatar-badge" >< img src = "{{ avatar_url('multiavatar', avatar_seed(user), 32) }}" class = "avatar-img avatar-sm" alt = "{{ user['username'] }}" loading = "lazy" > {% set _user = user %}{% include "_presence_dot.html" %}{% include "_award_badge.html" %}</ span >
2026-05-12 10:45:52 +00:00
< div class = "topnav-user-info" >
< span class = "topnav-user-name" > {{ user['username'] }}</ span >
2026-06-17 14:08:28 +00:00
< span class = "topnav-user-level" > Level {{ user.get('level', 1) }}</ span >
2026-05-12 10:45:52 +00:00
</ div >
2026-06-09 17:38:44 +00:00
</ button >
2026-06-19 08:06:09 +00:00
< div class = "dropdown-menu" id = "user-menu" >
2026-06-09 17:38:44 +00:00
< a href = "/profile/{{ user['username'] }}" class = "dropdown-item" >< span class = "icon" > 👤</ span > Profile</ a >
2026-06-08 15:38:33 +00:00
< a href = "/devii/" class = "dropdown-item" data-devii-open >< span class = "icon" > 🤖</ span > Devii</ a >
2026-06-06 14:31:42 +00:00
< a href = "/bookmarks/saved" class = "dropdown-item" >< span class = "icon" > 🔖</ span > Saved</ a >
2026-05-27 20:03:12 +00:00
< a href = "/auth/logout" class = "dropdown-item" >< span class = "icon" > 🚪</ span > Logout</ a >
2026-05-10 07:08:12 +00:00
</ div >
2026-05-12 10:45:52 +00:00
</ div >
{% else %}
2026-05-27 20:03:12 +00:00
< a href = "/auth/login" class = "topnav-link" >< span class = "icon" > 🔑</ span > Login</ a >
2026-05-12 13:07:34 +00:00
< a href = "/auth/signup" class = "btn btn-primary btn-sm" >< span class = "icon" > ✨</ span > Sign Up</ a >
2026-05-12 10:45:52 +00:00
{% endif %}
2026-06-19 08:06:09 +00:00
< button type = "button" class = "topnav-hamburger" id = "hamburger-btn" aria-label = "Toggle menu" aria-controls = "mobile-panel" aria-expanded = "false" > ☰</ button >
2026-05-10 07:08:12 +00:00
</ div >
</ div >
</ nav >
2026-06-19 08:06:09 +00:00
< div class = "topnav-mobile-overlay" id = "mobile-overlay" aria-hidden = "true" ></ div >
< div class = "topnav-mobile-panel" id = "mobile-panel" inert >
< nav class = "topnav-mobile-links" aria-label = "Mobile" >
< a href = "/" class = "topnav-mobile-link {{ nav_active(request, '/') }}" >< span class = "icon" > 🏠</ span > Home</ a >
< a href = "/feed" class = "topnav-mobile-link {{ nav_active(request, '/feed') }}" >< span class = "icon" > 📝</ span > Posts</ a >
< a href = "/news" class = "topnav-mobile-link {{ nav_active(request, '/news') }}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/gists" class = "topnav-mobile-link {{ nav_active(request, '/gists') }}" >< span class = "icon" > 📄</ span > Gists</ a >
< a href = "/projects" class = "topnav-mobile-link {{ nav_active(request, '/projects') }}" >< span class = "icon" > 🚀</ span > Projects</ a >
< a href = "/leaderboard" class = "topnav-mobile-link {{ nav_active(request, '/leaderboard') }}" >< span class = "icon" > 🏆</ span > Leaderboard</ a >
2026-06-22 16:41:53 +00:00
{% if user %}< a href = "/game" class = "topnav-mobile-link {{ nav_active(request, '/game') }}" >< span class = "icon" > 🌱</ span > Farm</ a > {% endif %}
2026-06-14 00:16:22 +00:00
< div class = "topnav-mobile-divider" ></ div >
< div class = "topnav-mobile-section-label" > Tools</ div >
2026-06-19 08:06:09 +00:00
< a href = "/tools/seo" class = "topnav-mobile-link {{ nav_active(request, '/tools/seo') }}" >< span class = "icon" > 🔍</ span > SEO Diagnostics</ a >
< a href = "/tools/deepsearch" class = "topnav-mobile-link {{ nav_active(request, '/tools/deepsearch') }}" >< span class = "icon" > 🧠</ span > DeepSearch</ a >
2026-07-06 03:57:47 +00:00
< a href = "/tools/isslop" class = "topnav-mobile-link {{ nav_active(request, '/tools/isslop') }}" >< span class = "icon" > 🧪</ span > AI Usage Analyzer</ a >
2026-05-15 23:34:45 +00:00
{% if user %}
2026-06-19 08:06:09 +00:00
< a href = "/messages" class = "topnav-mobile-link {{ nav_active(request, '/messages') }}" data-counter = "messages" data-counter-noun = "messages" aria-label = "{% if get_unread_messages(user['uid']) %}Messages, {{ get_unread_messages(user['uid']) }} unread{% else %}Messages, no unread{% endif %}" >< span class = "icon" > ✉️</ span > Messages< span class = "nav-badge nav-badge-inline" data-counter-badge {% if get_unread_messages ( user [" uid "]) == 0 %} hidden {% endif %} aria-hidden = "true" > {{ get_unread_messages(user["uid"]) }}</ span ></ a >
< a href = "/notifications" class = "topnav-mobile-link {{ nav_active(request, '/notifications') }}" data-counter = "notifications" data-counter-noun = "notifications" aria-label = "{% if get_unread_count(user['uid']) %}Notifications, {{ get_unread_count(user['uid']) }} unread{% else %}Notifications, no unread{% endif %}" >< span class = "icon" > 🔔</ span > Notifications< span class = "nav-badge nav-badge-inline" data-counter-badge {% if get_unread_count ( user [" uid "]) == 0 %} hidden {% endif %} aria-hidden = "true" > {{ get_unread_count(user["uid"]) }}</ span ></ a >
2026-06-08 15:38:33 +00:00
{% if is_admin(user) %}
2026-05-15 23:34:45 +00:00
< div class = "topnav-mobile-divider" ></ div >
< div class = "topnav-mobile-section-label" > Admin</ div >
2026-06-19 08:06:09 +00:00
< a href = "/admin" class = "topnav-mobile-link {{ nav_active(request, '/admin', exact=True) }}" >< span class = "icon" > 🛡️</ span > Dashboard</ a >
< a href = "/admin/users" class = "topnav-mobile-link {{ nav_active(request, '/admin/users') }}" >< span class = "icon" > 👥</ span > Users</ a >
< a href = "/admin/news" class = "topnav-mobile-link {{ nav_active(request, '/admin/news') }}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/admin/media" class = "topnav-mobile-link {{ nav_active(request, '/admin/media') }}" >< span class = "icon" > 🖼️</ span > Media</ a >
< a href = "/admin/trash" class = "topnav-mobile-link {{ nav_active(request, '/admin/trash') }}" >< span class = "icon" > 🗑️</ span > Trash</ a >
< a href = "/admin/services" class = "topnav-mobile-link {{ nav_active(request, '/admin/services') }}" >< span class = "icon" > ⚙️</ span > Services</ a >
< a href = "/admin/containers" class = "topnav-mobile-link {{ nav_active(request, '/admin/containers') }}" >< span class = "icon" > 📦</ span > Containers</ a >
< a href = "/admin/bots" class = "topnav-mobile-link {{ nav_active(request, '/admin/bots') }}" >< span class = "icon" > 🤖</ span > Bot Monitor</ a >
< a href = "/admin/ai-usage" class = "topnav-mobile-link {{ nav_active(request, '/admin/ai-usage') }}" >< span class = "icon" > 📊</ span > AI usage</ a >
< a href = "/admin/audit-log" class = "topnav-mobile-link {{ nav_active(request, '/admin/audit-log') }}" >< span class = "icon" > 📋</ span > Audit Log</ a >
< a href = "/admin/notifications" class = "topnav-mobile-link {{ nav_active(request, '/admin/notifications') }}" >< span class = "icon" > 🔔</ span > Notifications</ a >
< a href = "/admin/settings" class = "topnav-mobile-link {{ nav_active(request, '/admin/settings') }}" >< span class = "icon" > 🔧</ span > Settings</ a >
2026-05-15 23:34:45 +00:00
{% endif %}
< div class = "topnav-mobile-divider" ></ div >
< div class = "topnav-mobile-user" >
2026-07-09 02:52:54 +02:00
< span class = "avatar-badge" >< img src = "{{ avatar_url('multiavatar', avatar_seed(user), 32) }}" class = "avatar-img avatar-sm" alt = "{{ user['username'] }}" loading = "lazy" > {% set _user = user %}{% include "_presence_dot.html" %}{% include "_award_badge.html" %}</ span >
2026-05-15 23:34:45 +00:00
< div class = "topnav-mobile-user-info" >
< span > {{ user['username'] }}</ span >
2026-06-17 14:08:28 +00:00
< span class = "topnav-mobile-user-level" > Level {{ user.get('level', 1) }}</ span >
2026-05-15 23:34:45 +00:00
</ div >
</ div >
2026-06-06 14:31:42 +00:00
< a href = "/profile/{{ user['username'] }}" class = "topnav-mobile-link" >< span class = "icon" > 👤</ span > Profile</ a >
2026-06-08 15:38:33 +00:00
< a href = "/devii/" class = "topnav-mobile-link" data-devii-open >< span class = "icon" > 🤖</ span > Devii</ a >
2026-06-19 08:06:09 +00:00
< a href = "/bookmarks/saved" class = "topnav-mobile-link {{ nav_active(request, '/bookmarks') }}" >< span class = "icon" > 🔖</ span > Saved</ a >
2026-06-06 14:31:42 +00:00
< a href = "/auth/logout" class = "topnav-mobile-link" >< span class = "icon" > 🚪</ span > Logout</ a >
2026-05-15 23:34:45 +00:00
{% else %}
< div class = "topnav-mobile-divider" ></ div >
2026-06-06 14:31:42 +00:00
< a href = "/auth/login" class = "topnav-mobile-link" >< span class = "icon" > 🔑</ span > Login</ a >
< a href = "/auth/signup" class = "topnav-mobile-link" >< span class = "icon" > ✨</ span > Sign Up</ a >
2026-05-15 23:34:45 +00:00
{% endif %}
</ nav >
</ div >
2026-05-11 03:30:51 +00:00
{% if breadcrumbs and breadcrumbs|length > 1 %}
< nav aria-label = "Breadcrumb" class = "breadcrumb" >
< ol >
{% for crumb in breadcrumbs %}
< li >
{% if not loop.last %}
< a href = "{{ crumb.url }}" > {{ crumb.name }}</ a >
{% else %}
< span aria-current = "page" > {{ crumb.name }}</ span >
{% endif %}
</ li >
{% endfor %}
</ ol >
</ nav >
{% endif %}
2026-06-19 08:06:09 +00:00
< main id = "main-content" class = "page" tabindex = "-1" data-page-type = "{{ page_type_for(request) }}" >
2026-05-10 07:08:12 +00:00
{% block content %}{% endblock %}
</ main >
2026-05-12 10:45:52 +00:00
{% block footer %}
2026-05-11 05:02:06 +00:00
< footer class = "site-footer" >
< div class = "footer-inner" >
2026-06-08 15:38:33 +00:00
{% include "_footer_links.html" %}
2026-05-11 05:02:06 +00:00
</ div >
</ footer >
2026-05-12 10:45:52 +00:00
{% endblock %}
2026-05-11 05:02:06 +00:00
2026-06-18 22:09:34 +00:00
{%- set _response_time = response_time_ms(request) -%}
2026-06-19 08:06:09 +00:00
{%- if _response_time %}< div class = "response-time-indicator" title = "Server response time" aria-hidden = "true" > {{ _response_time }} ms</ div > {% endif -%}
2026-06-18 22:09:34 +00:00
2026-06-05 16:42:43 +00:00
{% if user %}
< template id = "comment-reply-template" >
{% set _comment_target_uid = "" %}{% set _comment_target_type = "" %}{% include "_comment_form.html" %}
</ template >
{% endif %}
2026-06-14 00:16:22 +00:00
< script defer src = "{{ static_url('/static/vendor/marked.umd.js') }}" ></ script >
< script defer src = "{{ static_url('/static/vendor/highlight.min.js') }}" ></ script >
< script defer src = "{{ static_url('/static/vendor/purify.min.js') }}" ></ script >
< script type = "module" src = "{{ static_url('/static/js/Application.js') }}" ></ script >
2026-05-10 07:08:12 +00:00
{% block extra_js %}{% endblock %}
2026-06-09 14:06:02 +00:00
{{ custom_js_tag(request) }}
2026-05-10 07:08:12 +00:00
</ body >
</ html >