2026-05-10 07:08:12 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
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' }}" >
< 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-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-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-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-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 >
< body >
< nav class = "topnav" >
< div class = "topnav-inner" >
< a href = "/feed" class = "topnav-logo" > Dev< span > Place</ span ></ a >
< div class = "topnav-links" >
2026-05-12 13:07:34 +00:00
< a href = "/" class = "topnav-link {% if request.url.path == '/' %}active{% endif %}" >< span class = "icon" > 🏠</ span > Home</ a >
< a href = "/feed" class = "topnav-link {% if request.url.path == '/feed' %}active{% endif %}" >< span class = "icon" > 📝</ span > Posts</ a >
< a href = "/news" class = "topnav-link {% if 'news' in request.url.path %}active{% endif %}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/gists" class = "topnav-link {% if 'gists' in request.url.path %}active{% endif %}" >< span class = "icon" > 📄</ span > Gists</ a >
2026-06-14 00:16:22 +00:00
< a href = "/projects" class = "topnav-link topnav-link-feature {% if 'projects' in request.url.path %}active{% endif %}" >< span class = "icon" > 🚀</ span > Projects</ a >
2026-05-30 18:16:39 +00:00
< a href = "/leaderboard" class = "topnav-link {% if 'leaderboard' in request.url.path %}active{% endif %}" >< span class = "icon" > 🏆</ span > Leaderboard</ a >
2026-06-14 00:16:22 +00:00
< div class = "topnav-tools-dropdown {% if request.url.path.startswith('/tools') %}active{% endif %}" >
< button type = "button" class = "topnav-link topnav-tools-toggle" aria-haspopup = "true" aria-expanded = "false" >< span class = "icon" > 🧰</ span > Tools < span class = "topnav-caret" > ▾</ span ></ button >
< div class = "dropdown-menu" >
< a href = "/tools/seo" class = "dropdown-item" >< span class = "icon" > 🔍</ span > SEO Diagnostics</ a >
</ div >
</ div >
2026-05-12 10:45:52 +00:00
{% if user %}
2026-06-06 14:31:42 +00:00
< a href = "/messages" class = "topnav-link {% if 'messages' in request.url.path %}active{% endif %}" data-counter = "messages" >< span class = "icon" > ✉️</ span > Messages{% set msg_unread = get_unread_messages(user["uid"]) %}< span class = "nav-badge nav-badge-inline" data-counter-badge {% if msg_unread = = 0 %} hidden {% endif %} > {{ msg_unread }}</ span ></ a >
2026-06-08 15:38:33 +00:00
{% if is_admin(user) %}
2026-05-12 13:07:34 +00:00
< a href = "/admin" class = "topnav-link {% if 'admin' in request.url.path %}active{% endif %}" >< span class = "icon" > ⚙️</ span > Admin</ a >
2026-05-11 03:30:51 +00:00
{% endif %}
2026-05-12 10:45:52 +00:00
{% endif %}
2026-05-10 07:08:12 +00:00
</ div >
< div class = "topnav-right" >
2026-05-12 10:45:52 +00:00
{% if user %}
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-06 14:31:42 +00:00
< a href = "/notifications" class = "topnav-icon" data-counter = "notifications" title = "Notifications" aria-label = "Notifications" >
< span class = "nav-bell" > 🔔</ span >
2026-05-10 07:08:12 +00:00
{% set unread_count = get_unread_count(user["uid"]) %}
2026-06-06 14:31:42 +00:00
< span class = "nav-badge" data-counter-badge {% if unread_count = = 0 %} hidden {% endif %} > {{ unread_count }}</ span >
2026-05-10 07:08:12 +00:00
</ a >
2026-05-12 10:45:52 +00:00
< div class = "topnav-user-dropdown" >
2026-06-09 17:38:44 +00:00
< button type = "button" class = "topnav-user" aria-label = "User menu" >
2026-05-12 10:45:52 +00:00
< img src = "{{ avatar_url('multiavatar', user['username'], 32) }}" class = "avatar-img avatar-sm" alt = "{{ user['username'] }}" loading = "lazy" >
< div class = "topnav-user-info" >
< span class = "topnav-user-name" > {{ user['username'] }}</ span >
2026-06-08 15:38:33 +00:00
{% if is_admin(user) %}< span class = "topnav-user-role" > {{ user['role'] }}</ span > {% endif %}
2026-05-12 10:45:52 +00:00
</ div >
2026-06-09 17:38:44 +00:00
</ button >
2026-05-12 10:45:52 +00:00
< div class = "dropdown-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-06 14:31:42 +00:00
< button type = "button" class = "topnav-hamburger" id = "hamburger-btn" aria-label = "Toggle menu" > ☰</ button >
2026-05-10 07:08:12 +00:00
</ div >
</ div >
</ nav >
2026-05-15 23:34:45 +00:00
< div class = "topnav-mobile-overlay" id = "mobile-overlay" ></ div >
< div class = "topnav-mobile-panel" id = "mobile-panel" >
< nav class = "topnav-mobile-links" >
< a href = "/" class = "topnav-mobile-link {% if request.url.path == '/' %}active{% endif %}" >< span class = "icon" > 🏠</ span > Home</ a >
< a href = "/feed" class = "topnav-mobile-link {% if request.url.path == '/feed' %}active{% endif %}" >< span class = "icon" > 📝</ span > Posts</ a >
< a href = "/news" class = "topnav-mobile-link {% if 'news' in request.url.path %}active{% endif %}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/gists" class = "topnav-mobile-link {% if 'gists' in request.url.path %}active{% endif %}" >< span class = "icon" > 📄</ span > Gists</ a >
< a href = "/projects" class = "topnav-mobile-link {% if 'projects' in request.url.path %}active{% endif %}" >< span class = "icon" > 🚀</ span > Projects</ a >
2026-05-30 18:16:39 +00:00
< a href = "/leaderboard" class = "topnav-mobile-link {% if 'leaderboard' in request.url.path %}active{% endif %}" >< span class = "icon" > 🏆</ span > Leaderboard</ a >
2026-06-14 00:16:22 +00:00
< div class = "topnav-mobile-divider" ></ div >
< div class = "topnav-mobile-section-label" > Tools</ div >
< a href = "/tools/seo" class = "topnav-mobile-link {% if 'tools/seo' in request.url.path %}active{% endif %}" >< span class = "icon" > 🔍</ span > SEO Diagnostics</ a >
2026-05-15 23:34:45 +00:00
{% if user %}
2026-06-06 14:31:42 +00:00
< a href = "/messages" class = "topnav-mobile-link {% if 'messages' in request.url.path %}active{% endif %}" data-counter = "messages" >< span class = "icon" > ✉️</ span > Messages< span class = "nav-badge nav-badge-inline" data-counter-badge {% if get_unread_messages ( user [" uid "]) == 0 %} hidden {% endif %} > {{ get_unread_messages(user["uid"]) }}</ span ></ a >
< a href = "/notifications" class = "topnav-mobile-link {% if 'notifications' in request.url.path %}active{% endif %}" data-counter = "notifications" >< span class = "icon" > 🔔</ span > Notifications< span class = "nav-badge nav-badge-inline" data-counter-badge {% if get_unread_count ( user [" uid "]) == 0 %} hidden {% endif %} > {{ 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-06 14:31:42 +00:00
< a href = "/admin/users" class = "topnav-mobile-link {% if 'admin/users' in request.url.path %}active{% endif %}" >< span class = "icon" > 👥</ span > Users</ a >
< a href = "/admin/news" class = "topnav-mobile-link {% if 'admin/news' in request.url.path %}active{% endif %}" >< span class = "icon" > 📰</ span > News</ a >
< a href = "/admin/services" class = "topnav-mobile-link {% if 'admin/services' in request.url.path %}active{% endif %}" >< span class = "icon" > ⚙️</ span > Services</ a >
< a href = "/admin/settings" class = "topnav-mobile-link {% if 'admin/settings' in request.url.path %}active{% endif %}" >< 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" >
< img src = "{{ avatar_url('multiavatar', user['username'], 32) }}" class = "avatar-img avatar-sm" alt = "{{ user['username'] }}" loading = "lazy" >
< div class = "topnav-mobile-user-info" >
< span > {{ user['username'] }}</ span >
2026-06-08 15:38:33 +00:00
{% if is_admin(user) %}< span class = "topnav-mobile-user-role" > {{ user['role'] }}</ span > {% endif %}
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-06 14:31:42 +00:00
< a href = "/bookmarks/saved" class = "topnav-mobile-link {% if 'bookmarks' in request.url.path %}active{% endif %}" >< span class = "icon" > 🔖</ span > Saved</ a >
< 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-09 14:06:02 +00:00
< main class = "page" 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-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/vendor/emoji-picker-element/index.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 >