Compare commits
72 Commits
with_posts
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
bf42e13626 | |
|
|
fd5d944cdf | |
|
|
8edffa16d5 | |
|
|
d7732c5f14 | |
|
|
2f0c2f4d7e | |
|
|
73e43f8f4b | |
|
|
936b3ec2f6 | |
|
|
ca72a91d20 | |
|
|
93e1ac1f1b | |
|
|
a6abab998e | |
|
|
12921e0e33 | |
|
|
e84eff41a1 | |
|
|
57bfe200fb | |
|
|
d06e3899cf | |
|
|
cd40dd57f9 | |
|
|
5273b06cf2 | |
|
|
32c5a88f1c | |
|
|
2cf5562d04 | |
|
|
74baf03ae7 | |
|
|
c0ac934c64 | |
|
|
e7a1572905 | |
|
|
c916a2f583 | |
|
|
2e1fd94c8f | |
|
|
2c286dacf4 | |
|
|
812099ee7f | |
|
|
80af0bb917 | |
|
|
588b151acd | |
|
|
28c5a0982d | |
|
|
29692b81ac | |
|
|
8e87a99ff2 | |
|
|
fca2a8e35f | |
|
|
e8ca2d76b0 | |
|
|
233381c9c2 | |
|
|
072df100ca | |
|
|
4d8011eec6 | |
|
|
b3be15b09e | |
|
|
dae1b0cb7f | |
|
|
5d402e7d67 | |
|
|
e4c441848e | |
|
|
212c7b033f | |
|
|
70ca6c2f48 | |
|
|
19cb537864 | |
|
|
c1b711fe6a | |
|
|
22a53d09ec | |
|
|
ee1a702618 | |
|
|
cb4e2d2236 | |
|
|
7bc99713c8 | |
|
|
0e27feddb4 | |
|
|
9de438c885 | |
|
|
9a6a88e695 | |
|
|
826d8aa56d | |
|
|
b15d095dc1 | |
|
|
1e5aecbd0b | |
|
|
72696e3302 | |
|
|
3eed3e280d | |
|
|
79acc8163a | |
|
|
d54da6f04d | |
|
|
02774e6094 | |
|
|
4ae7240d68 | |
|
|
21624d015b | |
|
|
4edf0577e6 | |
|
|
bc428552a5 | |
|
|
9873a7db28 | |
|
|
bdc8451f22 | |
|
|
bef63db9d1 | |
|
|
6a3eecddb9 | |
|
|
e232fec118 | |
|
|
9cae5bc994 | |
|
|
62e1a1dd3a | |
|
|
f39c272265 | |
|
|
2aba6b9853 | |
|
|
fbe72c0185 |
|
|
@ -1,11 +1,15 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*/__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
#added
|
||||
staticfiles/
|
||||
*/migrations/
|
||||
blog/migrations/
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
|
|
|
|||
|
|
@ -11,21 +11,27 @@ https://docs.djangoproject.com/en/3.0/ref/settings/
|
|||
"""
|
||||
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
TEMPLATES_DIR = os.path.join(BASE_DIR + '/templates')
|
||||
|
||||
DEFAULT_AUTO_FIELD='django.db.models.AutoField'
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
|
||||
|
||||
# Load the Env
|
||||
load_dotenv()
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = '!2g)+m+_h9fq9%il5+t5#qnj^9502or6$=2!$==v=i2*c#7q*m'
|
||||
SECRET_KEY = os.getenv('SECRET_KEY')
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'beyond-heroes.com', 'www.beyond-heroes.com']
|
||||
|
||||
|
||||
# Application definition
|
||||
|
|
@ -34,7 +40,6 @@ INSTALLED_APPS = [
|
|||
'crispy_forms',
|
||||
'crispy_bootstrap4',
|
||||
'blog.apps.BlogConfig',
|
||||
'users.apps.UsersConfig',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
|
|
@ -79,8 +84,12 @@ WSGI_APPLICATION = 'BH.wsgi.application'
|
|||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': os.getenv('DB_NAME'),
|
||||
'USER': os.getenv('DB_USER'),
|
||||
'PASSWORD': os.getenv('DB_PASSWORD'),
|
||||
'HOST': os.getenv('DB_HOST'),
|
||||
'PORT': os.getenv('DB_PORT'),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,10 +130,11 @@ USE_TZ = True
|
|||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/3.0/howto/static-files/
|
||||
|
||||
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
|
||||
STATIC_URL = '/static/'
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR + '/media')
|
||||
MEDIA_URL = '/media/'
|
||||
|
||||
CRISPY_TEMPLATE_PACK = 'bootstrap4'
|
||||
LOGIN_REDIRECT_URL = 'Home'
|
||||
LOGIN_REDIRECT_URL = 'News'
|
||||
LOGIN_URL = 'Login'
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ from django.urls import path, include
|
|||
|
||||
urlpatterns = [
|
||||
path('', include('blog.urls')),
|
||||
path('users/', include('users.urls')),
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
# Use an official Python runtime as a parent image
|
||||
FROM python:3.11-slim-bookworm
|
||||
|
||||
# Set environment variables
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
libpq-dev \
|
||||
default-libmysqlclient-dev \
|
||||
pkg-config \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Python dependencies
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
RUN pip install gunicorn
|
||||
|
||||
# Copy project files
|
||||
COPY . /app/
|
||||
|
||||
# Expose the port on which the application will run
|
||||
EXPOSE 3030
|
||||
|
||||
# Define environment variable for Gunicorn
|
||||
ENV GUNICORN_CMD_ARGS="--bind 0.0.0.0:3030"
|
||||
|
||||
# Run Gunicorn server with your Django application
|
||||
CMD ["gunicorn", "BH.wsgi:application"]
|
||||
32
README.md
|
|
@ -1,18 +1,30 @@
|
|||
## Requirements
|
||||
The website requires the following:
|
||||
- Docker
|
||||
- Docker Compose
|
||||
- A running MariaDB Instance
|
||||
|
||||
## Deployment
|
||||
To deploy the website:
|
||||
To deploy the website:
|
||||
- first clone the repository to any local folder
|
||||
- then open the folder with the `manage.py` file
|
||||
- then `Shift`+`Right Click` and click on `Open PowerShell window here`
|
||||
- then type in `py manage.py runserver 4000`
|
||||
- open browser at address `localhost:4000` or `127.0.0.1:4000`
|
||||
- then open the folder
|
||||
- create a new file called `.env` and add the following:
|
||||
```
|
||||
SECRET_KEY=your_secret_key
|
||||
DB_NAME=your_db_name
|
||||
DB_USER=your_db_user
|
||||
DB_PASSWORD=your_db_password
|
||||
DB_HOST=your_db_host
|
||||
DB_PORT=your_db_port
|
||||
```
|
||||
- run `docker-compose up --build` this starts the website at localhost:3030
|
||||
|
||||
## Structure
|
||||
The website has a Home page and a News page page currently. The News page shows all developer blogs.
|
||||
The website has a Home page and a News page currently. The News page shows all developer blogs.
|
||||
|
||||
## Problems and Development
|
||||
Currently there are the following problems:
|
||||
- `/dev/` route needs to be made
|
||||
- the Blog card needs to be updated
|
||||
- the `secret` needs to be secret
|
||||
Currently, there are the following problems:
|
||||
- the page needs a **Dark Mode**
|
||||
- Ability for staff to add blogs directly
|
||||
|
||||
If you find any problems and have a solution *in code* then please consider making a `pull request`, using the `Create a new branch for this commit and start a pull request` option with an appropriate branch name.
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
# Generated by Django 5.0.2 on 2024-07-06 16:24
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Blog',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('content', models.TextField()),
|
||||
('title', models.CharField(max_length=150)),
|
||||
('date_posted', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Post',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('content', models.TextField()),
|
||||
('date_posted', models.DateTimeField(default=django.utils.timezone.now)),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -7,15 +7,8 @@ from django.utils import timezone
|
|||
class Blog(models.Model):
|
||||
content = models.TextField()
|
||||
title = models.CharField(max_length=150)
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
author = models.TextField() #models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
date_posted = models.DateTimeField(default=timezone.now)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return '/'
|
||||
|
||||
|
||||
|
||||
class Post(models.Model):
|
||||
content = models.TextField()
|
||||
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
date_posted = models.DateTimeField(default=timezone.now)
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@ urlpatterns = [
|
|||
path('', views.home, name='Home'),
|
||||
path('news/', views.news, name='News'),
|
||||
path('blog/<int:pk>', views.BlogDetailView.as_view(), name='Blog'),
|
||||
path('blog/create/', views.BlogCreateView.as_view(), name='Blog Create'),
|
||||
path('post/<int:pk>', views.PostDetailView.as_view(), name='Post'),
|
||||
path('post/create/', views.PostCreateView.as_view(), name='Post Create'),
|
||||
path('dev/', views.dev, name='Dev'),
|
||||
path('dev/support/', views.support, name='Support'),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
from django.db.models import QuerySet
|
||||
from django.shortcuts import render
|
||||
from django.contrib.auth.mixins import *
|
||||
from django.views.generic import *
|
||||
|
|
@ -34,7 +35,7 @@ def news(request):
|
|||
ordering = (ordering,)
|
||||
queryset = queryset.order_by(*ordering)
|
||||
|
||||
return render(request, 'blog/home.html', { context_object_name: queryset, 'topics': ['No Updates...'] })
|
||||
return render(request, 'blog/home.html', {context_object_name: queryset, 'topics': ['No Updates...']})
|
||||
|
||||
|
||||
class BlogDetailView(DetailView):
|
||||
|
|
@ -42,37 +43,13 @@ class BlogDetailView(DetailView):
|
|||
template_name = 'blog/blogDetail.html'
|
||||
|
||||
|
||||
class BlogCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Blog
|
||||
template_name = 'blog/blogCreate.html'
|
||||
fields = ['title', 'content']
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.author = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
|
||||
class PostDetailView(DetailView):
|
||||
model = Post
|
||||
template_name = 'blog/postDetail.html'
|
||||
|
||||
|
||||
class PostCreateView(LoginRequiredMixin, CreateView):
|
||||
model = Post
|
||||
template_name = 'blog/postCreate.html'
|
||||
fields = ['content']
|
||||
|
||||
def form_valid(self, form):
|
||||
form.instance.author = self.request.user
|
||||
return super().form_valid(form)
|
||||
|
||||
|
||||
def dev(request):
|
||||
return render(request, 'dev.html', {'title': 'Development'})
|
||||
|
||||
|
||||
def support(request):
|
||||
return render(request, 'support.html', {'title': 'Support Us'})
|
||||
|
||||
|
||||
def home(request):
|
||||
return render(request, 'index.html', {'title': 'Home'})
|
||||
return render(request, 'index.html', {'title': 'Home'})
|
||||
|
|
|
|||
BIN
db.sqlite3
|
|
@ -0,0 +1,15 @@
|
|||
services:
|
||||
django:
|
||||
build: .
|
||||
env_file:
|
||||
- .env
|
||||
volumes:
|
||||
- .:/app
|
||||
ports:
|
||||
- "3030:3030"
|
||||
network_mode: "host"
|
||||
command: >
|
||||
sh -c "python manage.py makemigrations blog --noinput &&
|
||||
python manage.py migrate --noinput &&
|
||||
python manage.py collectstatic --noinput &&
|
||||
gunicorn BH.wsgi:application --bind 0.0.0.0:3030 --workers ${GUNICORN_WORKERS:-3}"
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 21 KiB |
BIN
requirements.txt
|
|
@ -1,5 +0,0 @@
|
|||
@ echo off
|
||||
echo The devlopment server will start in a few seconds...
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
python manage.py runserver 3000
|
||||
|
|
@ -5,49 +5,23 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Beyond Heroes</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<!-- Custom CSS -->
|
||||
<style>
|
||||
/* body {
|
||||
background-color: #f8f9fa;
|
||||
color: #eeeeee;
|
||||
}
|
||||
.card {
|
||||
border: 1px;
|
||||
border-radius: 15px;
|
||||
border-color: #eeeeee;
|
||||
box-shadow: 0 0 10px rgba(250, 250, 250, 0.1);
|
||||
}
|
||||
.list-group-item {
|
||||
background-color: #1e1f10;
|
||||
border-color: #eeeeee;
|
||||
}
|
||||
.card-header {
|
||||
background-color: #111111;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
.card-body {
|
||||
background-color: #1e1f10;
|
||||
}
|
||||
.profile-image {
|
||||
max-width: 125px;
|
||||
border-radius: 50%;
|
||||
padding: 20px;
|
||||
}*/
|
||||
.link {
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: 'Alte DIN 1451 Mittelschrift';
|
||||
src: url('/media/mittelschrift.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5, Opera 10+, Safari 3—5 */
|
||||
}
|
||||
body {
|
||||
font-family: 'Alte DIN 1451 Mittelschrift', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark" style="background-color: #000;">
|
||||
<a class="navbar-brand" href="/">
|
||||
<img src="/media/logo.jpg" alt="BH Logo" height="40"> Beyond Heroes
|
||||
<a class="navbar-brand" href="/" style="font-size: 24px;margin-left: 20px;">
|
||||
<img src="/media/Asset 3.png" alt="BH Logo" height="30" style="padding-right: 2px;"> Beyond Heroes
|
||||
</a>
|
||||
<!-- <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button> -->
|
||||
<div class="ml-auto"></div>
|
||||
<div class="justify-content-center" id="navbarNav">
|
||||
<div class="justify-content-center" style="margin-right: 20px;" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item" style="padding-right: 10px; padding-left: 10px;">
|
||||
<a class="nav-link" href="/news">News</a>
|
||||
|
|
@ -60,26 +34,6 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="ml-auto"></div>
|
||||
<div class="justify-content-center" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<form action="{% url 'Logout' %}" method="post">
|
||||
{% csrf_token %}
|
||||
<button class="nav-link btn btn-link" type="submit">Logout</button>
|
||||
</form>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'Login' %}">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'Register' %}">Register</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% block content %}
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
{% if title %}
|
||||
<title>WeBlog - {{ title }}</title>
|
||||
{% else %}
|
||||
<title>WeBlog - We connect your brains!</title>
|
||||
{% endif %}
|
||||
<link rel="icon" type="image/x-icon" href="WeBlog.ico">
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="></script>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary rounded-bottom" style="background: #a4e5ff; margin-bottom:10px">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/">TechBlog</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/">Home<span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'About' %}">About</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'People' %}">People</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'Explore' %}">Explore</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div style="margin-left: 60%;"></div>
|
||||
<ul class="navbar-nav nav-rev" style="margin-right: 0px;">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id='a' href="{% url 'Blog Create' %}">Post</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id='a' href="{% url 'Profile' %}">Profile</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id='a' href="{% url 'Logout' %}">Logout</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'Login' %}">Login</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id=a href="{% url 'Register' %}">Register</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="container"
|
||||
style="font-family: Rockwell; margin-bottom: 0; padding-bottom: 10px; padding-top: 20px; padding-right: 100px; padding-left: 100px;">
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }}">
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"
|
||||
integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
|
||||
integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
|
||||
integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
BIN
templates/bg.jpg
|
Before Width: | Height: | Size: 101 KiB |
|
|
@ -1,42 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
<h1 class="display-3" style="font-family: rockwell;"><strong>TechBlog</strong></h1>
|
||||
<h4 class="lead"><strong>We provide a platform for people who want to help others.</strong></h4>
|
||||
<hr>
|
||||
<br>
|
||||
<ul style="margin-bottom: 100px">
|
||||
{% for blog in blog %}
|
||||
<!-- <li>-->
|
||||
<!-- <h2>{{ blog.title }}</h2>-->
|
||||
<!-- <p>{{ blog.content }}</p>-->
|
||||
<!-- <hr>-->
|
||||
<!-- </li>-->
|
||||
<blockquote class="blockquote">
|
||||
<a href="{% url 'Blog' blog.id %}" class="h2" style="font-family: rockwell; color:rgb(0, 92, 167);">{{ blog.title }}</a>
|
||||
<p class="mb-0">{{ blog.content }}</p>
|
||||
<footer class="blockquote-footer">posted by <cite title="{{ blog.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ blog.author }}</a></cite> on <cite title="{{ blog.date_posted }}">{{ blog.date_posted|date:"M j, o" }}</cite></footer>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<!-- <li class="media">-->
|
||||
<!-- <img src="..." class="mr-3" alt="...">-->
|
||||
<!-- <div class="media-body">-->
|
||||
<!-- <h5 class="mt-0 mb-1">{{ blog.title }}</h5>-->
|
||||
<!-- {{ blog.content }}-->
|
||||
<!-- </div>-->
|
||||
<!-- </li>-->
|
||||
<!-- <hr>-->
|
||||
<!-- <br>-->
|
||||
<!-- <div class="card">-->
|
||||
<!-- <div class="card-header">-->
|
||||
<!-- {{ blog.author }}-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="card-body">-->
|
||||
<!-- <h5 class="card-title">{{ blog.title }}</h5>-->
|
||||
<!-- <p class="card-text">{{ blog.content }}</p>-->
|
||||
<!-- <a href="#" class="btn btn-primary">Read More</a>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <br>-->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<div class="container mt-5">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Create a Blog
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form | crispy }}
|
||||
<br>
|
||||
<button class="btn btn-light" type="submit"> Post </button>
|
||||
</div>
|
||||
<!-- <div class="card-footer">
|
||||
<small class="text-muted">
|
||||
Don't Have An Account? <a class="link" href="{% url 'Register' %}">Register</a>
|
||||
</small>
|
||||
</div> -->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,12 +1,19 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
|
||||
{% load markdown_extras %}
|
||||
<br>
|
||||
<blockquote class="blockquote">
|
||||
<h2 class="h2" style="font-family: rockwell;">{{ object.title | markdown | safe }}</h2>
|
||||
<p class="mb-0">{{ object.content | markdown | safe }}</p>
|
||||
<footer class="blockquote-footer">posted by <cite title="{{ object.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ object.author }}</a></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite></footer>
|
||||
</blockquote>
|
||||
<hr style="margin-bottom: 20px">
|
||||
{% load markdown_extras %}
|
||||
<div class="container mt-5">
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title">{{ object.title | markdown | safe }}</h3>
|
||||
<p class="card-text">{{ object.content | markdown | safe }}</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
By <cite title="{{ object.author }}"></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
|
||||
{% load markdown_extras %}
|
||||
|
||||
<div style="">
|
||||
<h1 class="h1">We Blog</h1>
|
||||
<p class="lead">We connect your brains!</p>
|
||||
<hr class="my-4" />
|
||||
</div>
|
||||
<ul class="list-unstyled">
|
||||
{% for post in blogs %}
|
||||
<div class="jumbotron" id="jumbotron" style="background-color: #ffffff60;">
|
||||
<li class="media">
|
||||
<article class="media content-section">
|
||||
<div class="media-body">
|
||||
<div class="article-metadata">
|
||||
<a class="mr-2" href="{% url 'NamedProfile' post.author.id %}">{{ post.author }}</a>
|
||||
<small class="text-muted">{{ post.data_posted|date:"M j, Y" }}</small>
|
||||
<br>
|
||||
</div>
|
||||
<a class="article-title" style="font-size: 40px;" href="{% url 'Blog' post.id %}">{{ post.title | markdown | safe }}</a>
|
||||
<hr class="my-4" />
|
||||
<p class="article-content">{{ post.content | markdown | safe }}</p>
|
||||
</div>
|
||||
</article>
|
||||
</li>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
<!-- Posts will be dynamically added here -->
|
||||
<div class="card mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ post.title }} <a href="#" class="link text-secondary lead">@{{ post.author }}</a></h5>
|
||||
<h4 class="card-title"><a href="{% url 'Blog' post.id %}" class="text-dark">{{ post.title }}</a></h4>
|
||||
<p class="card-text">{{ post.content | markdown | safe }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<div class="container mt-5">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Create a Post
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form | crispy }}
|
||||
<br>
|
||||
<button class="btn btn-light" type="submit"> Post </button>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<small class="text-muted">
|
||||
Don't Have An Account? <a class="link" href="{% url 'Register' %}">Register</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{% extends 'base2.html' %}
|
||||
{% block content %}
|
||||
|
||||
{% load markdown_extras %}
|
||||
<br>
|
||||
<blockquote class="blockquote">
|
||||
<p class="mb-0">{{ object.content | markdown | safe }}</p>
|
||||
<footer class="blockquote-footer">posted by <cite title="{{ object.author }}"><a href="{% url 'NamedProfile' blog.author.id %}">{{ object.author }}</a></cite> on <cite title="{{ object.date_posted }}">{{ object.date_posted|date:"M j, o" }}</cite></footer>
|
||||
</blockquote>
|
||||
<hr style="margin-bottom: 20px">
|
||||
{% for comment in object.comments %}
|
||||
<blockquote class="blockquote" style="margin-left: 10px;">
|
||||
<p class="mb-1">{{ comment.content | markdown | safe }}</p>
|
||||
<footer class="blockquote-footer">posted by <cite title="{{ comment.author }}"><a href="{% url 'NamedProfile' comment.author.id %}">{{ comment.author }}</a></cite> on <cite title="{{ comment.date_posted }}">{{ comment.date_posted|date:"M j, o" }}</cite></footer>
|
||||
</blockquote>
|
||||
<hr style="margin-bottom: 10px; margin-left: 10px;">
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
{% block content %}
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;background-color: #000;
|
||||
}
|
||||
</style>
|
||||
<div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px;" class="container">
|
||||
<div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px; font-size: 18px;" class="container">
|
||||
<div style="padding: 20px;">
|
||||
<h2 style="text-align: justify;">Beyond Heroes</h2>
|
||||
<p style="text-align: justify;">
|
||||
|
|
@ -16,19 +16,13 @@
|
|||
<div class="container">
|
||||
<h3 style="text-align: justify;">Our Developers</h3>
|
||||
<p style="text-align: justify;">
|
||||
Similique earum unde unde exercitationem totam voluptatibus. Cupiditate reiciendis aut ducimus sunt. Sunt laboriosam rerum qui maxime quod aut aspernatur. Ipsa reprehenderit quas nihil vel dignissimos at. Repellendus minima dolorem ipsa sit est ipsum accusamus.<br>
|
||||
Made up of enthusiastic helpers from all over the globe, with a strong core in Germany, Poland, France, India, Argentina, and more. Sharing ideas across so many cultures gives us fresh perspectives and helps us keep eyes on different parts that might be more relevant locally and their experience with other mmos. That way, we can reach farther and keep a foot in major countries around the globe. If you'd like to join, just <a href="https://forms.gle/wf4LTUHNW7hjPXcz6">fill out the form</a> and don't be scared to hit us up on Discord! Our work environment is super hostile and we do require you to have a sense of humor and the latest version of sarcasm which you can get here <a href="https://en.wikipedia.org/wiki/Sarcasm">Sarcasm-StopMakingNewBranches-win-x64.7z</a><br>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h3 style="text-align: justify;">Our Vision</h3>
|
||||
<p style="text-align: justify;">
|
||||
Laborum nobis incidunt voluptate magnam voluptatibus. Itaque sequi eveniet vitae voluptas voluptatem ullam alias omnis. Officiis quia dolores architecto.Voluptate quia aspernatur excepturi voluptas molestias. Maxime magnam maiores sunt dolorum. Id possimus ullam rerum dignissimos.<br>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h3 style="text-align: justify;">Roadmap</h3>
|
||||
<p style="text-align: justify;">
|
||||
A adipisci ad quia accusantium voluptates. Rem culpa et repellendus qui et tenetur quia. Nam rem provident non. Eum quod nostrum molestiae ut expedita vel. In voluptas ea quod. Modi incidunt qui tempora soluta minus odio sed et.Est aliquid id est quia praesentium rerum blanditiis. Voluptas a est omnis. Aut non quo non. Numquam quibusdam esse cum nostrum ab vel et. Fugit porro libero commodi dicta omnis libero.<br>
|
||||
So blurry the background image seems fine. Beyond Heroes, aims to create an exciting World War gaming experience inspired by 'Heroes & Generals' but without the issues it had. Our goal is to provide the same immersive and challenging game while renewing some changes and upgrading the technical systems that preceded. Through strategic gameplay that made HnG so interesting, War, and balanced mechanics, our game aims to deliver a fun and rewarding experience that appeals to old and new players. We value our community and strive to provide a respectful and enjoyable environment that fosters teamwork, camaraderie, and sportsmanship. Also this text sounds corporate af, and thus this anti-climatic sentence is here to break with the same old corporate speech that makes us pay 5$ to open the game. The team is mostly comprised of people who share the same core values those being: Being against the new trend of p2w mechanics, combating <a href="https://colinmagazine.com/blogs/news/live-service-fatigue-are-we-tired-of-battle-passes-microtransactions">microtransaction fatigue</a>, being in favour of <a href="https://www.stopkillinggames.com/">stop killing games</a>, being in favour of <a href="https://www.youtube.com/watch?v=2_Dtmpe9qaQ">clippy</a> and against anti-consumer practices <a href="https://www.forbes.com/sites/paultassi/2024/05/01/nba-2k-players-furious-about-kobe-bryant-collector-level-reward-removal/">(1)</a> <a href="https://www.gamesindustry.biz/epic-ea-roblox-and-more-face-eu-complaint-over-tricking-players-into-spending">(2)</a>, <a href="https://en.wikipedia.org/wiki/Enshittification">being absolutely against enshittification</a>, and in favor of remakes.<br>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -3,22 +3,22 @@
|
|||
{% block content %}
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;background-color: #000;
|
||||
}
|
||||
</style>
|
||||
<div style="position: absolute; bottom: 1; right: 0;margin: 25px; width: 30%; background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px;">
|
||||
<div style="position: absolute; bottom: 1; right: 0;margin: 25px; width: 35%; background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px;">
|
||||
<div style="padding: 20px;">
|
||||
<h2 style="text-align: justify;">Beyond Heroes</h2>
|
||||
<p style="text-align: justify;">
|
||||
<p style="text-align: justify; font-size: 22px;">
|
||||
The project that rose from the ashes of a game that was once. We aim to recreate the experience that we enjoyed throughout the years, while also adding new features that make it truly <i>Beyond</i> Heroes and Generals.<br>
|
||||
Join Us on this journey to relive the old days and experience something new by clicking on the button below!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position: absolute; bottom: 0; right: 0; margin-right: 25px; margin-bottom: 30px;">
|
||||
<button class="btn" style="padding: 5px 75px; font-family:'Trebuchet MS', sans-serif; font-size: 30px; font-weight: bold; background-color: #139358; color: white; border-radius: 2px;" onmouseover="this.style.backgroundColor='#0f7a4c'" onmouseout="this.style.backgroundColor='#139358'">
|
||||
<a class="btn" href="https://discord.gg/gnnfKKuumg" style="padding: 10px 100px; font-family:'Trebuchet MS', sans-serif; font-size: 36px; font-weight: bold; background-color: #139358; color: white; border-radius: 2px;" onmouseover="this.style.backgroundColor='#0f7a4c'" onmouseout="this.style.backgroundColor='#139358'">
|
||||
To Battle!
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -3,30 +3,40 @@
|
|||
{% block content %}
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;
|
||||
background-image: url('/media/bg.jpg'); background-size: cover; background-repeat: no-repeat;background-color: #000;
|
||||
}
|
||||
|
||||
/* Link-Farben definieren */
|
||||
a.text-light {
|
||||
color: #E2C490 !important;
|
||||
}
|
||||
|
||||
a.text-light:visited {
|
||||
color: #6c562d !important;
|
||||
}
|
||||
|
||||
/* Optionale Hover-Effekte */
|
||||
a.text-light:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
<div style="background-color: rgba(0, 0, 0, 0.6); color: #eeeeee; border-radius: 2px; margin-top: 10px;" class="container">
|
||||
<div style="padding: 20px;">
|
||||
<h2 style="text-align: justify;">Beyond Heroes</h2>
|
||||
<p style="text-align: justify;">
|
||||
The project that rose from the ashes of a game that was once. We aim to recreate the experience that we enjoyed throughout the years, while also adding new features that make it truly <i>Beyond</i> Heroes and Generals.<br>
|
||||
</p>
|
||||
<div style="padding: 20px; font-size: 18px;">
|
||||
<h2 style="text-align: justify;">Support Us</h2>
|
||||
<hr style="background-color: #999999;">
|
||||
<div class="container">
|
||||
<h3 style="text-align: justify;">Why Help Us</h3>
|
||||
<h3 style="text-align: justify;">Hi! So, you want to support the project, I hear?</h3>
|
||||
<p style="text-align: justify;">
|
||||
Similique earum unde unde exercitationem totam voluptatibus. Cupiditate reiciendis aut ducimus sunt. Sunt laboriosam rerum qui maxime quod aut aspernatur. Ipsa reprehenderit quas nihil vel dignissimos at. Repellendus minima dolorem ipsa sit est ipsum accusamus.<br>
|
||||
Well, the main way you can do that is by joining the team or telling people to join the team! You can fill out this form <a class="text-light" href="#"><strong>here</strong></a> if you're interested in any dev position or <a class="text-light" href="#"><strong>here</strong></a> if you're interested in translation.<br>
|
||||
</p>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h3 style="text-align: justify;">How to Help Us</h3>
|
||||
<h3 style="text-align: justify;">If you want to help economically... let's talk first...</h3>
|
||||
<p style="text-align: justify;">
|
||||
Laborum nobis incidunt voluptate magnam voluptatibus. Itaque sequi eveniet vitae voluptas voluptatem ullam alias omnis. Officiis quia dolores architecto.Voluptate quia aspernatur excepturi voluptas molestias. Maxime magnam maiores sunt dolorum. Id possimus ullam rerum dignissimos.<br>
|
||||
Here's the thing, I really appreciate that you want to help us out, and we LOVE your energy. We really don't want to accept economic help, and there are a few reasons as to why. Mostly, we can't (or don't want to) promise anything, we don't want to get your hopes up, and we don't want to lead you to believe in something that might not happen. Giving us money has a worse ROI than playing it all on red in roulette, and as such, to me personally, it feels like asking for money from you just because you like us. If that's the case, okay, alright, no problem; we still have to solve the distribution issue, but whatever, we'll get to it eventually. Otherwise, understand that the reason the links are so hidden is exactly because we don't want you to feel like you wasted money - at least not before you knowingly and willingly understand that this is just like giving it to us because you like us and want to, or you have money to spare and don't care. If you want to specifically help out a team member, assign it on the message or something so I know who not to give it to :P
|
||||
<br>
|
||||
If you understand the above-mentioned stuff, then <a class="text-light" href="https://ko-fi.com/beyondheroes" target="blank"><strong>here's</strong></a> a link to our Ko-fi, and <a class="text-light" href="https://www.buymeacoffee.com/beyondheroes" target="blank"><strong>here's</strong></a> a link to our Buy Me a Coffee.
|
||||
</p>
|
||||
<button class="btn" style="padding: 5px 30px; font-family:'Trebuchet MS', sans-serif; font-size: 20px; font-weight: bold; background-color: #139358; color: white; border-radius: 2px;" onmouseover="this.style.backgroundColor='#0f7a4c'" onmouseout="this.style.backgroundColor='#139358'">
|
||||
Donate
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,24 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<div class="container mt-5">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Login
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form | crispy }}
|
||||
<br>
|
||||
<button class="btn btn-light" type="submit"> Login </button>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<small class="text-muted">
|
||||
Don't Have An Account? <a class="link" href="{% url 'Register' %}">Register</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{message.tags}}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="container mt-5">
|
||||
<div class="card mb-4">
|
||||
<div class="card-header h5">
|
||||
You have been Logged Out
|
||||
</div>
|
||||
<div class="card-body">
|
||||
Hope you enjoyed Today!
|
||||
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<small class="text-muted">
|
||||
Go to <a href="{% url 'Home' %}" class="link">Home</a> or <a href="{% url 'Login' %}" class="link" type="submit"> Log in </a> Again?
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
|
||||
|
||||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
|
||||
{% load markdown_extras %}
|
||||
<!-- Main Content -->
|
||||
<div class="container mt-5">
|
||||
<div class="row">
|
||||
<!-- Mainbar -->
|
||||
<div class="col-lg-8">
|
||||
<div class="card-body">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
Latest Posts
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% for post in posts %}
|
||||
{% if post.author == profileUser %}
|
||||
<!-- Posts will be dynamically added here -->
|
||||
<div class="card mb-3 userPost">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ post.author.username }} <a href="#" class="link text-secondary lead" style="text-decoration: none;">@{{ post.author.id }}</a></h5>
|
||||
<p class="card-text">{{ post.content | markdown | safe }}</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- End of Posts -->
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card mb-4">
|
||||
<div class="row" style="padding-bottom: 20px;">
|
||||
<div class="col-md-4 text-center">
|
||||
<img src="https://cdn.pixabay.com/photo/2017/06/13/12/54/profile-2398783_1280.png" alt="Profile Image" class="profile-image">
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h2 class="mt-3" style="margin-bottom: 0px;">{{ profileUser.username }}</h2>
|
||||
<p class="text-secondary lead" style="margin-bottom: 0px;">@{{ profileUser.id }}</p>
|
||||
<p>Date Joined: Jan 1, 2022</p>
|
||||
{% if profileUser == user %}
|
||||
<a href="#" class="link">Edit Profile</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
{% load crispy_forms_tags %}
|
||||
<div class="container mt-5">
|
||||
<form method="POST">
|
||||
{% csrf_token %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
Create an Account
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ form | crispy }}
|
||||
<br>
|
||||
<button class="btn btn-light sm" type="submit"> Register </button>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<small class="text-muted">
|
||||
Already Have An Account? <a class="link" href="{% url 'Login' %}">Sign In</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
from django.contrib import admin
|
||||
from .models import Profile
|
||||
|
||||
|
||||
# Register your models here.
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class UsersConfig(AppConfig):
|
||||
name = 'users'
|
||||
|
||||
def ready(self):
|
||||
import users.signals
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
from django import forms
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from .models import Profile
|
||||
|
||||
|
||||
class UserRegisterForm(UserCreationForm):
|
||||
email = forms.EmailField()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username', 'email', 'password1', 'password2']
|
||||
|
||||
|
||||
class UserUpdateForm(forms.ModelForm):
|
||||
email = forms.EmailField()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username', 'email']
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# Generated by Django 5.0.2 on 2024-07-06 16:24
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=100)),
|
||||
('about', models.TextField(default='Hi, I am new to TechBlog')),
|
||||
('gender', models.TextField(default='None')),
|
||||
('dob', models.DateField(default='1999-01-01')),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
|
||||
# Create your models here.
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=100)
|
||||
about = models.TextField(default='Hi, I am new to TechBlog')
|
||||
gender = models.TextField(default='None')
|
||||
dob = models.DateField(default='1999-01-01')
|
||||
# image = models.ImageField(default='default.png', name='profile_pic', upload_to='profile_pics')
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.user.username}'s Profile"
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
from django.db.models.signals import post_save
|
||||
from django.contrib.auth.models import User
|
||||
from django.dispatch import receiver
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
from django.urls import path
|
||||
from django.contrib.auth import views as login_view
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('profile/', views.profile, name='Profile'),
|
||||
path('profile/<int:pk>', views.profile, name='NamedProfile'),
|
||||
path('login/', login_view.LoginView.as_view(template_name='users/login.html'), name='Login'),
|
||||
path('logout/', login_view.LogoutView.as_view(template_name='users/logout.html'), name='Logout'),
|
||||
path('register/', views.register, name='Register')
|
||||
]
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
from django.shortcuts import render, redirect
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from .forms import UserRegisterForm
|
||||
from blog.models import *
|
||||
from .models import *
|
||||
from django.views.generic import *
|
||||
|
||||
|
||||
# Create your views here.
|
||||
# def users(request):
|
||||
# return render(request, 'users/users.html', {'title': 'Users'})
|
||||
|
||||
def getFromArr(arr, indices, *args, **kwargs):
|
||||
x = []
|
||||
for i in indices:
|
||||
x.append(arr[i])
|
||||
return x
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request, *args, **kwargs):
|
||||
try:
|
||||
user = User._default_manager.all()[kwargs['pk'] - 1]
|
||||
except:
|
||||
user = request.user
|
||||
print(user.id)
|
||||
|
||||
allow_empty = True
|
||||
queryset = None
|
||||
model = Post
|
||||
paginate_by = None
|
||||
paginate_orphans = 0
|
||||
context_object_name = 'posts'
|
||||
ordering = ['-date_posted']
|
||||
|
||||
if queryset is not None:
|
||||
queryset = queryset
|
||||
if isinstance(queryset, QuerySet):
|
||||
queryset = queryset.all()
|
||||
elif model is not None:
|
||||
queryset = model._default_manager.all()
|
||||
else:
|
||||
raise ImproperlyConfigured(
|
||||
"%(cls)s is missing a QuerySet. Define "
|
||||
"%(cls)s.model, %(cls)s.queryset, or override "
|
||||
"%(cls)s.get_queryset()." % {"cls": self.__class__.__name__}
|
||||
)
|
||||
|
||||
if ordering:
|
||||
if isinstance(ordering, str):
|
||||
ordering = (ordering,)
|
||||
queryset = queryset.order_by(*ordering)
|
||||
|
||||
return render(request, 'users/profile.html', {'title': 'Profile', 'profileUser': user, context_object_name: queryset})
|
||||
|
||||
|
||||
def people(request):
|
||||
return render(request, 'users/people.html', {'title': 'People', 'users': User._default_manager.all()})
|
||||
|
||||
|
||||
users = {
|
||||
'user': User.objects.all()
|
||||
}
|
||||
|
||||
|
||||
class UserListView(ListView):
|
||||
model = User
|
||||
template_name = 'users/people.html'
|
||||
context_object_name = 'users'
|
||||
|
||||
|
||||
def explore(request):
|
||||
return render(request, 'users/explore.html', {'title': 'Explore'})
|
||||
|
||||
|
||||
def login(request):
|
||||
return render(request, 'users/login.html', {'title': 'Login'})
|
||||
|
||||
|
||||
def register(request):
|
||||
if request.method == 'POST':
|
||||
form = UserRegisterForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
username = form.cleaned_data.get('username')
|
||||
messages.success(request, f'{username}! Your account has been created.')
|
||||
return redirect('Login')
|
||||
else:
|
||||
form = UserRegisterForm()
|
||||
return render(request, 'users/register.html', {'title': 'Register', 'form': form})
|
||||