diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html new file mode 100644 index 0000000..e4ba96f --- /dev/null +++ b/docs/_layouts/default.html @@ -0,0 +1,39 @@ + + + + + + + + {% include head-custom.html %} + +{% seo %} + + + + +
+
+ +

{{ site.title | default: site.github.repository_name }}

+
+

{{ site.description | default: site.github.project_tagline }}

+ +
+ {% if site.show_downloads %} + Download as .zip + Download as .tar.gz + {% endif %} + View on GitHub + Visit website +
+
+
+ +
+
+ {{ content }} +
+
+ + diff --git a/docs/contact.md b/docs/contact.md index 749ea40..1a8be78 100644 --- a/docs/contact.md +++ b/docs/contact.md @@ -1,3 +1,15 @@ # Contact -At this moment the only thing that this module does is rendering the contact page, which is just a static HTML page. -Perhaps at a later moment, this could contain a contact form. \ No newline at end of file +The website makes use of contact forms. With the help of these forms people can send directly a message to either the +entire Future Factory, or just individual teams. + +When a message gets send from the home page, it is sent to all the teams, whereas when a message is send through a team +page it will only end up at that specific team. + +In order to clean all the data and make it safe for processing we use the `ContactForm` object, using a Django +[Form](https://docs.djangoproject.com/en/4.1/topics/forms/). + +The `SendMessage` view, located in `main_site/views.py` takes care of actually sending the email to the correct +destination. At first the form is populated with the data and it is checked. If safe, an email is created and send. +A message indicating that the mail was successfully send will be shown to the user. + +In case the form contains any error, the user will be made aware of these errors. Asking them to fix it. \ No newline at end of file diff --git a/docs/events.md b/docs/events.md index eddcfdf..3cfec3a 100644 --- a/docs/events.md +++ b/docs/events.md @@ -1,21 +1,27 @@ # Events -An event is something that happened (or will happen) at the Future Factory. Events are small articles where we share -what happened and what was achieved during such event or activity. +An event is some form of activity that starts on a given time and date. -## Database model -Every event is saved in the database, lets take a look at the model that is used. +## Models +There is a single [model](https://docs.djangoproject.com/en/4.1/topics/db/models/) available in this app, which +represents a model. -| Attribute | Description | -|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `title` | The title of this event or article | -| `summary` | A short piece of text that is only shown on the home page and on the news list page | -| `description` | The article itself. Also this field is a `QuillField`, allowing for rich-text. | -| `image` | The image is used as a cover image and shown next to the article | -| `visible` | When you temporarily want to hide this article, but not permenantly remove it, you can set this to `False`. Note: Direct links to this article will keep working | -| `event_date` | The start date of this event | +| Attribute | Description | +|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `title` | The title of this event | +| `summary` | A short piece of text that is only shown on the home page and on the events list page | +| `description` | The main text description this event. Also this field is a `QuillField`, which provides the user a rich-text editor | +| `image` | The image is used as a cover image and shown with this event. | +| `visible` | When you temporarily want to hide this event, but not permanently remove it, you can set this to `False`. Note: Direct links to this article will keep working | +| `date` | The start date and time of this event | +| `location` | Where this event is supposed to take place | -Next to default functions this model has a property named `description_html`. This strips of the new paragraphs after -someone has pressed on enter in the rich-text editor, causing a lot of unnecessary white space. +## Views +For events, both the [`DetailView`](https://docs.djangoproject.com/en/4.1/ref/class-based-views/generic-display/#detailview) +and the [`ListView`](https://docs.djangoproject.com/en/4.1/ref/class-based-views/generic-display/#listview) have been +implemented. The list view sorts the events based on their start date / time. A +[paginator](https://docs.djangoproject.com/en/4.1/topics/pagination/) makes sure that every page has a maximum of eight +events on display at the same time. -## Page rendering -When events are displayed in a list, they are first filtered based on their visibility. Then sorted on the event date. \ No newline at end of file +## Templates +Next to your basic detail and list view templates an event also has a `event_thumbnail.html` template. This template +generates a single event item. This template is both used in the ListView as on the main page. \ No newline at end of file diff --git a/docs/facts.md b/docs/facts.md new file mode 100644 index 0000000..e7a8db6 --- /dev/null +++ b/docs/facts.md @@ -0,0 +1,15 @@ +# Facts +A fact is a HTML component that contains a big icon and two short pieces of text. They both appear on the main page and +each team page. + +## Models +There are two models that work with facts, the first one named `Fact` represents a single one. + +| Attribute | Description | +|:----------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `icon` | An icon is one of the many [Themify Icons](https://themify.me/themify-icons). Icons can be picked from a dropdown menu. Hence all the available choices are generated within the code | +| `value` | This is the big number indicating this fact (maximum of 10 characters) | +| `context` | Some text that is able to give some context to this number (maximum of 50 characters) | + +Another model that uses facts is a `TeamFact` which inherits the previously described `Fact` model, adding a team to it. +This model is located in the [teams](teams.md) app. \ No newline at end of file diff --git a/docs/images/classdiagram.jpg b/docs/images/classdiagram.jpg new file mode 100644 index 0000000..73310f7 Binary files /dev/null and b/docs/images/classdiagram.jpg differ diff --git a/docs/images/classdiagram.png b/docs/images/classdiagram.png deleted file mode 100644 index 89bf28d..0000000 Binary files a/docs/images/classdiagram.png and /dev/null differ diff --git a/docs/images/hexagons.jpg b/docs/images/hexagons.jpg new file mode 100644 index 0000000..2d7e9df Binary files /dev/null and b/docs/images/hexagons.jpg differ diff --git a/docs/index.md b/docs/index.md index 13ba3ff..a947d09 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,9 +1,9 @@ # Future Factory Website Documentation Over here you can find the documentation for the Future Factory website. -The website is written in Python using the [Django](https://www.djangoproject.com/) framework. At the moment RoboTeam -Twente is the lead maintainer on this website and is also responsible for hosting it. However, this should not discourage -other people from wanting to help and work on this site. +The website is written in Python using the [Django](https://www.djangoproject.com/) framework. At the moment +[Tom Meulenkamp](https://github.com/supertom01/) from RoboTeam Twente is the lead maintainer on this website and is also +responsible for hosting it. However, this should not discourage other people from wanting to help and work on this site. The code structure attempts to make it easy to search through and is written in a way that should not be too complex for someone with some experience with the Django framework. @@ -12,32 +12,53 @@ Although the code has some documentation incorporated into it, this documentatio allowing one to understand on how all of these components work together. ## Table of Contents -* [Teams](teams.md) * [Events](events.md) +* [Facts](facts.md) +* [News Articles](news_articles.md) * [Partners](partners.md) +* [Teams](teams.md) * [Contact](contact.md) * [Settings](settings.md) +* [Styling](styling.md) ## General Information -Most entities have their own module (also known as app) within this project. This allows for a clear distribution -between models, views and other stuff. +Most entities have their own module (also known as [app](https://docs.djangoproject.com/en/4.1/ref/applications/)) +within this project. This allows for a clear distribution between models, views and other stuff. ### Class Diagram -![Class Diagram](images/classdiagram.png) +![Class Diagram](images/classdiagram.jpg) -### Navigation bar highlighting -When you're somewhere on the website, your current location is highlighted in the navigation bar. This is done with the -help of the context variable, `current`, that is passed on by each view. The constant strings that are assigned to it -are hardcoded. An example from the TeamView looks like this: +### Templates +Each page that one sees is built with the Django [template](https://docs.djangoproject.com/en/4.1/ref/templates/) system. +Every page extends the `basis.html` template that can be found in `/templates`. This template handles the basis HTML +structure such as meta tags, favicons, the navigation bar and the footer. Each template then +[inherits](https://docs.djangoproject.com/en/4.1/ref/templates/language/#template-inheritance) this basic template and +is able to fill out the following blocks: -```python - def get_context_data(self, **kwargs): - context = super(self).get_context_data(**kwargs) - context['current'] = "teams" - return context -``` +* description + * Contains a short description about this specific page. This will be shown in the Google search results. +* title + * The title of the current page. +* head + * Additional HTML that should go into the head, for example additional stylesheets. + * Also, these blocks usually contain additional CSS, for example to override the default background picture in the + header. +* nav_bar + * By default the navigation bar only contains the logo and home button. Any additional buttons should be added with + the following HTML: + ```html + + ``` +* content + * The actual contents of this page. This will mainly contain `
` elements. +* scripts + * Any JavaScript that should be loaded into the page, this will be placed after the `` tag. -At this moment one can choose between the following constants: `home`, `teams`, `events`, `partners` & `contact` +#### Error pages +If a page cannot be found or the server raises an uncaught exception, the user will see an error message. The templates +for these pages can be found in `/templates` and are named according to their HTTP error codes. ### Automated image compression Images are automatically compressed, allowing for quick load times and an overall responsive website. This compression diff --git a/docs/news_articles.md b/docs/news_articles.md new file mode 100644 index 0000000..78b398a --- /dev/null +++ b/docs/news_articles.md @@ -0,0 +1,22 @@ +# News Articles +A news article is usually some form of article describing a past activity that is related with the Future Factory. + +## Models +A single model is used by news articles, the `NewsArticle` model. + +| Attribute | Description | +|---------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `title` | The title of this news article | +| `summary` | A short piece of text that is only shown on the home page and on the news article list page | +| `description` | The main text of this article. Also this field is a `QuillField`, allowing for the end user to add rich-text. | +| `image` | The image is used as a cover image and shown next to the article | +| `visible` | When you temporarily want to hide this article, but not permanently remove it, you can set this to `False`. Note: Direct links to this article will keep working | +| `date` | The start date of this event | + +## Views +Just like [events](events.md), news articles implement a Detail and a ListView. + +## Templates +The detail view relies on the `news_article.html` template, whereas the list view utilizes the `news.html` template. +Since news articles are used on multiple places a `news_article_thumbnail.html` is able to generate a single news +article. This component is used in both the main page and the list view. \ No newline at end of file diff --git a/docs/partners.md b/docs/partners.md index b45bee9..ab537e7 100644 --- a/docs/partners.md +++ b/docs/partners.md @@ -1,3 +1,47 @@ # Partners -At this moment partners are not actively being kept track of in the database. The only thing that this module does is -rendering the partner page, which is just a static HTML page. \ No newline at end of file +Partners are not actively being stored in the database. New partners can be added by modifying the `main.html` and +`partners.scss` files. Let's start out with the structure of the HTML. + +## HTML Structure +All the partners are located within the following `div` located in `/main_site/templates/main.html`: +```html +
+``` + +Each partner has their own hexagon, possibly varying in size. However, each hexagon element has the following structure: +```html + + _partner_ logo + +``` +The hexagons are available in three sizes: `small`, `medium`, `large`. The size is added as a class, in the example +above, it is called \_size\_. The medium size has an additional option, the values for this option are either `left` or +`right`. These values indicate whether the third hexagon sticks out either left or right. + +Ones filled out, the hexagon should still be positioned correctly within the div, this is done with (S)CSS. + +## SCSS Structure +The correct SCSS file can be found at `/static/public_html/assets/scss/partners.scss`. The positioning of the individual +hexagons are located at the bottom of the file. Since they are each positioned relative in the container we have to +define the `top` and `left` coordinates of our div, resulting in a rule looking like: +```scss +&#_partner_ { + top: ; + left: ; +} +``` + +The offsets have to be calculated by hand. In order to achieve this we can use the known width and height of all the +sizes of hexagons. These can all the accessed as css variables like: +```css +var(--hexagon_size_dimension) +``` +where size should be `small`, `medium`, or `big` and dimension should be `height` or `width`. + +To help with the positioning the relative dimensions of each hexagon type are shown in the picture below + +![Hexagon dimensions](images/hexagons.jpg) + +When adding hexagons at the outer edges, be aware of the fact that the width and/or height of the total container will +change. You have to compensate for this by updating the `--hexagon_small_width` and `--hexagon_margin` variables on the +top of the .scss file. Additionally, you will have to update the width and height of the `partner-hexagons` container. \ No newline at end of file diff --git a/docs/settings.md b/docs/settings.md index 3c3ab31..292f75c 100644 --- a/docs/settings.md +++ b/docs/settings.md @@ -5,10 +5,25 @@ has been deployed. This page will explain these settings. | Setting | Description | |------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `SECRET_KEY` | The secret key is taken from the environment variable `DJANGO_KEY` | -| `DEBUG` | Based on wether the DEBUG environment variable is set to `true`, we run in a debug mode. Otherwise we run in production mode | +| `DEBUG` | Based on whether the DEBUG environment variable is set to `true`, we run in a debug mode. Otherwise we run in production mode | +| `BETA` | Based on whether the BETA environment variable is set to `true`, the application runs in beta mode. | | `ALLOWED_HOSTS` | The deployment server runs behind NGINX, which already does host checks. Hence we skip this on the Django side | | `CSRF_TRUSTED_ORIGINS` | Only these hosts may receive POST requests | | `DATABASES` | The databases are dynamically chosen based on the `DEBUG` variable. The production database assumes that there are environment variables available for the database name, user and password. The server is expected to be found on `future_factory_db` | | `QUILL_CONFIGS` | The rich text editor configuration. For more information see its [documentation](https://django-quill-editor.readthedocs.io/en/latest/pages/change-toolbar-configs.html) | | `STATIC_ROOT` | The location on the deployment server where the static files are stored (part of the code base like .js, .css files) | -| `MEDIA_ROOT` | The location on the server where the media files are stored (uploaded by a user) | \ No newline at end of file +| `MEDIA_ROOT` | The location on the server where the media files are stored (uploaded by a user) | +| `EMAIL_*` | Email related settings, more details can be found in the [Django documentation](https://docs.djangoproject.com/en/4.1/topics/email/#send-mail) | + +# Environment variables +For safety reasons all secrets are loaded with the help of environment variables. The following are in use: + +| Value | Description | +|---------------------|----------------------------------------------------------| +| `DJANGO_KEY` | Used for the `SECRET_KEY` setting | +| `DEBUG` | Used to determine whether we are running in debug mode | +| `BETA` | Used to determine whether we are running in beta mode | +| `POSTGRES_NAME` | The name of the database used in production mode | +| `POSTGRES_USER` | The username to authenticate at the production database | +| `POSTGRES_PASSWORD` | The password for the production database | +| `EMAIL_PASSWORD` | The password to the email account used for sending email | \ No newline at end of file diff --git a/docs/styling.md b/docs/styling.md new file mode 100644 index 0000000..a6bc870 --- /dev/null +++ b/docs/styling.md @@ -0,0 +1,21 @@ +# Styling +The front-end of this website has been written with the help of [Bootstrap](https://getbootstrap.com/), +[jQuery](https://jquery.com/) and [Themify Icons](https://themify.me/themify-icons). Furthermore, the website +is based of a template provided by DevCRUD (https://devcrud.com). + +In order to update the generated `.css` and `.js` files [NodeJS](https://nodejs.org/en) in a combination with +[gulp.js](https://gulpjs.com/) is being used. + +When working on the front-end you can find all the images, stylesheets and other files inside the +`/static/public_htnl/assets` folder. When you're done with editing, and you want to see the result locally follow the +following steps: +1. Open a terminal inside of `/static`. +2. If `node_modules` is not yet in this directory, run `npm install` +3. Run `npm start clean`, removing all the old production files. +4. Run `npm start build`, this will start compiling the (s)css, js, compressing images etc. This will take some time, + if you only want to update for example the css, you can do so by running `npm start css` and then `npm start scss`. + +## Deployment +This is a note for the person that is responsible for deploying any updates. When asset files have been updated they +might not always be detected by the input-free `collectstatic` command from Django. So if you are missing any new assets +re-run the `python manage.py collectstatic` command by hand. \ No newline at end of file diff --git a/docs/teams.md b/docs/teams.md index 205a9fd..c880ce6 100644 --- a/docs/teams.md +++ b/docs/teams.md @@ -6,19 +6,21 @@ description of their activities. ## Database model Every team is saved in the database, hence there is a model available for it. Let's go over it: -| Attribute | Description | -|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| -| `name` | The name of this team | -| `contact_person` | The name of the main contact person for this team. Usually the communication or team manager | -| `contact_person_function` | The function of the contact person | -| `contact_person_phone` | The phone number of the contact person, make sure to actually fill out a valid number since people will be able to directily call this from the site | -| `contact_mail` | The mail-address to use when someone wants to contact the team. Often it looks like info@... | -| `website` | The teams website address | -| `banner_picture` | Each page on the website has a picture shown just below the navigation bar. This is the banner picture that will be shown at this team page | -| `logo` | The team's logo. Preferably a high quality PNG image with a transparent background | -| `slogan` | The slogan from the team | -| `team_picture` | This will be the first picture that is shown on the website, for consistency reasons this should be the team picture | -| `slug` | An auto generated field based on the team name. This field is used to generate the URL to the page of this team | +| Attribute | Description | +|---------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `name` | The name of this team | +| `contact_person` | The name of the main contact person for this team. Usually the communication or team manager | +| `contact_person_function` | The function of the contact person | +| `contact_person_phone` | The phone number of the contact person, make sure to actually fill out a valid number since people will be able to directily call this from the site | +| `contact_mail` | The mail-address to use when someone wants to contact the team. Often it looks like info@... | +| `website` | The teams website address | +| `front_page_picture` | The picture that is being shown on the front page inside of the hexagon. This picture should be square. | +| `banner_picture` | Each page on the website has a picture shown just below the navigation bar. This is the banner picture that will be shown at this team page, it will also show up as the picture behind the facts section of this team | +| `logo` | The team's logo. Preferably a high quality PNG image with a transparent background | +| `logo_svg` | The logo in SVG form of this team. This is used on the press page. | +| `main_color` | The accent color being used for headers on the team page, the hexagon overlays and icons on the contact form. | +| `slogan` | The slogan from the team | +| `slug` | An auto generated field based on the team name. This field is used to generate the URL to the page of this team | ### Text Sections As described above, each team has its own page. These pages contain sections where text and images can be uploaded. In @@ -35,13 +37,44 @@ has a title, body and possibly a picture. These text sections have a pre-determined ordering. Each page is rendered with sections ordered based on their order of creation. This should suffice, since the admin interface will correspond with final page render. +### TeamFact +Teams have small facts on their own pages. Each teams is enforced to have 3 or 4 of them on their page. Each fact comes +with an icon. These icons are [Themify Icons](https://themify.me/themify-icons) and can be chosen with a dropdown menu. +The database object itself looks like this: + +| Attribute | Description | +|-----------|---------------------------------------------------------------| +| `icon` | A string representing a Themify Icon | +| `value` | The big font sized text | +| `context` | A smaller piece of text adding context to the number and icon | +| `team` | To which team does this fact belong? | + +This object is inherited from the [Fact](facts.md) object. + +### TeamAccount +In order to limit teams from editing each other's data each user account has to be connected to a team. Only then that +specific user account can access the team's details in the [administration](https://futurefactorytwente.nl/admin) +environment. + +This model consists out of a one-to-one relation with a Django user and a foreign key with a team object. + +## Views +Teams implement two types of views: [`DetailView`](https://docs.djangoproject.com/en/4.1/ref/class-based-views/generic-display/#detailview) +and the [`SendMessage`](contact.md) view. + +The first one displays the team page. It therefore uses the team model and a contact form object for form validation. + +The second view handles the submission of a new email. + +## Templates +For the `DetailView` there is a `team.html` template, which shows all the information about a team. The +`team_thumbnail.html` template generates a single hexagon that can be found on the homepage. + ## Creating a new team -When you create a new team in the database, everything should be set up automatically, and you should be good to go. -However, in order to slightly optimize loading times, the navigation bar is hard-coded. Hence, you will have to the new -team to the navigation bar by hand. The easiest way to do this is by going to the new team in the admin environment, -click on "view on site" and copying the URL from this page. It can then be placed into the navigation section located -in `templates/basis.html`. The link should look like this: - -```html -
  • Team Name
  • -``` \ No newline at end of file +When one needs to add a new team, there are quite some steps to be taken. +1. Create a new user account +2. Create a new team in the database +3. Connect the specific account to the team (`TeamAccount`) +4. Figure out a new nice way to represent the teams on the home screen + * You will most likely have to update some CSS and perhaps some HTML +5. Furthermore, you'll want to have to update the FF logo throughout the entire website. \ No newline at end of file diff --git a/events/views.py b/events/views.py index d269242..2f0f50d 100644 --- a/events/views.py +++ b/events/views.py @@ -1,4 +1,3 @@ -from django.shortcuts import render from django.views.generic import DetailView, ListView from events.models import Event diff --git a/future_factory_website/settings.py b/future_factory_website/settings.py index da2dfbb..ba70a5c 100644 --- a/future_factory_website/settings.py +++ b/future_factory_website/settings.py @@ -42,7 +42,6 @@ 'colorfield', 'teams.apps.TeamsConfig', 'main_site.apps.MainSiteConfig', - 'partners.apps.PartnersConfig', 'news_articles.apps.NewsArticlesConfig', 'events.apps.EventsConfig', 'facts.apps.FactsConfig', diff --git a/partners/__init__.py b/partners/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/partners/admin.py b/partners/admin.py deleted file mode 100644 index 8c38f3f..0000000 --- a/partners/admin.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.contrib import admin - -# Register your models here. diff --git a/partners/apps.py b/partners/apps.py deleted file mode 100644 index 07969c7..0000000 --- a/partners/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class PartnersConfig(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' - name = 'partners' diff --git a/partners/migrations/__init__.py b/partners/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/partners/models.py b/partners/models.py deleted file mode 100644 index 71a8362..0000000 --- a/partners/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/partners/templates/partners.html b/partners/templates/partners.html deleted file mode 100644 index f463193..0000000 --- a/partners/templates/partners.html +++ /dev/null @@ -1,52 +0,0 @@ -{% extends "basis.html" %} -{% load static %} - -{% block title %}Partners{% endblock title %} - -{% block banner %} - -{% endblock banner %} - -{% block content %} -
    -
    -
    - -
    -
    -

    Wall Of Fame

    -

    We do not only share knowledge between the teams in the future factory. - We also have partnerships with several companies. With their support we hope - to be able to inspire even more people. By sharing knowledge with our partners we hope - to be able to innovate in new ways.

    - We are proud of our partners and therefore they get a special place on our site and on a wall in the Future Factory!
    - If you are interested in the possibilities of a partnership with Future Factory Twente - as well and want to know more about what we could offer you, you can send an email to - (info@futurefactorytwente.nl).

    -
    - -
    -
    - - - -
    -
    -
    -
    -
    -
    -{% endblock content %} \ No newline at end of file diff --git a/partners/tests.py b/partners/tests.py deleted file mode 100644 index 7ce503c..0000000 --- a/partners/tests.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/partners/urls.py b/partners/urls.py deleted file mode 100644 index e5fd406..0000000 --- a/partners/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.urls import path - -from partners import views - -urlpatterns = [ - path('', views.PartnerView.as_view(), name="Partners"), -] diff --git a/partners/views.py b/partners/views.py deleted file mode 100644 index 4e971d1..0000000 --- a/partners/views.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.views.generic import TemplateView - - -# Create your views here. -class PartnerView(TemplateView): - template_name = "partners.html" - - def get_context_data(self, **kwargs): - context = super(PartnerView, self).get_context_data(**kwargs) - context['current'] = "partners" - return context