Compare commits

...

9 Commits
master ... 2025

  1. 4
      .gitignore
  2. 104
      ContentfulService.py
  3. BIN
      __pycache__/ContentfulService.cpython-310.pyc
  4. 64
      app.py
  5. 78
      public/css/styles.css
  6. 48
      public/js/locations.js
  7. 6
      templates/_nav.html
  8. 4
      templates/article.html
  9. 12
      templates/base.html
  10. 21
      templates/index.html
  11. 22
      templates/list-exhibitions.html
  12. 30
      templates/list.html
  13. 53
      templates/locations.html

4
.gitignore

@ -1,4 +1,6 @@
.env .env
/node_modules/ /node_modules/
package-lock.json package-lock.json
beta-favicon.psd beta-favicon.psd
public/images/locations.zip
public/images/support.zip

104
ContentfulService.py

@ -0,0 +1,104 @@
import contentful
import markdown
import os
import re
class ContentfulService:
def __init__(self, space_id, access_token):
self.client = contentful.Client(space_id, access_token)
def get_general_info(self):
entries = self.client.entries({'content_type': 'general'})
if not entries:
return None
entry = entries[0]
general_date = entry.fields().get('general_date')
general_end_date = entry.fields().get('general_end_date')
general_text = entry.fields().get('general_text')
general_text_event = entry.fields().get('general_event_text')
general_text_conference = entry.fields().get('general_conference_text')
formatted_date = general_date.strftime('%#d %b %Y') if general_date else None
formatted_end_date = general_end_date.strftime('%#d %b %Y') if general_end_date else None
info = {
'startDate': formatted_date,
'endDate': formatted_end_date,
'text': markdown.markdown(general_text) if general_text else '',
'textConference': markdown.markdown(general_text_conference) if general_text_conference else '',
'textEvent':markdown.markdown(general_text_event) if general_text_event else ''
}
return info
def get_location_info(self):
entries = self.client.entries({'content_type': 'locations'})
location_list = []
for e in entries:
name = getattr(e, 'name')
directions = getattr(e, 'directions')
url = getattr(e, 'url')
image_asset = getattr(e, 'image')
image_url = image_asset.url() if image_asset else ''
content = {
'name': name,
'directions' : directions,
'url' : url,
'image' : image_url
}
location_list.append(content)
return location_list
def get_exhibition_list_info(self):
entries = self.client.entries({'content_type': 'exhibitionList'})
exhibition_list = []
for e in entries:
title = getattr(e, 'title')
description = getattr(e, 'description')
description = markdown.markdown(description)
start_date = getattr(e, 'start_date')
start_date = start_date.strftime('%#d %b %Y') if start_date else None
end_date = getattr(e, 'end_date')
end_date = end_date.strftime('%#d %b %Y') if end_date else None
location = getattr(e, 'location')
slug = title.lower() # Convert to lowercase
slug = re.sub(r'[^a-z0-9\s-]', '', slug) # Remove non-alphanumeric characters
slug = re.sub(r'[\s-]+', '-', slug).strip('-') # Replace spaces and repeated hyphens
url = slug
content = {
'title': title,
'location': location,
'description': description,
'start_date': start_date,
'end_date': end_date,
'url': url
}
exhibition_list.append(content)
return exhibition_list
def get_sponser_logos(self):
entries = self.client.entries({'content_type': 'sponser'})
supp_img = []
prio_img = []
top_img = []
for e in entries:
src = getattr(e, 'logo')
idx = getattr(e, 'type')
content = 'https:{0}'.format(src.url())
if idx == '1':
top_img.append(content)
elif idx == '2':
prio_img.append(content)
else:
supp_img.append(content)
return supp_img, prio_img, top_img

BIN
__pycache__/ContentfulService.cpython-310.pyc

Binary file not shown.

64
app.py

@ -3,6 +3,7 @@ import contentful
from dotenv import load_dotenv from dotenv import load_dotenv
import os import os
import markdown import markdown
from ContentfulService import ContentfulService
load_dotenv() load_dotenv()
@ -13,10 +14,18 @@ SPACE_ID = os.getenv('SPACE_ID')
ACCESS_TOKEN = os.getenv('ACCESS_TOKEN') ACCESS_TOKEN = os.getenv('ACCESS_TOKEN')
client = contentful.Client(SPACE_ID, ACCESS_TOKEN) client = contentful.Client(SPACE_ID, ACCESS_TOKEN)
contentful_service = ContentfulService(SPACE_ID, ACCESS_TOKEN)
@app.context_processor
def inject_general_info():
# Fetch the data here, inside the function that runs for every request.
# This guarantees the data is always fresh from Contentful.
festival_info = contentful_service.get_general_info()
return dict(festival_general_info=festival_info)
@app.route('/') @app.route('/')
def index(): def index():
sup_img, prio_img, prio_img_top = get_support_images() sup_img, prio_img, prio_img_top = contentful_service.get_sponser_logos()
return render_template('index.html', title='', sup_img_list=sup_img, prio_img=prio_img, prio_img_top=prio_img_top) return render_template('index.html', title='', sup_img_list=sup_img, prio_img=prio_img, prio_img_top=prio_img_top)
@app.route('/grph') @app.route('/grph')
@ -30,17 +39,26 @@ def events():
@app.route('/exhibitions') @app.route('/exhibitions')
def exhibitions(): def exhibitions():
return render_template('list.html', title='Exhibitions') exhibition_info = contentful_service.get_exhibition_list_info()[::-1]
print(exhibition_info)
return render_template('list.html', title='Exhibitions', exhibition_info=exhibition_info)
@app.route('/exhibitions/<ex_type>') @app.route('/exhibitions/<ex_type>')
def exhibition_type(ex_type): def exhibition_type(ex_type):
if ex_type == "local-artists-network": if ex_type == "local-artists-network":
ex_type = "LAN" ex_type = "LAN"
elif ex_type == "unsettling-the-algorithm": elif ex_type == "unsettling-the-algorithm":
ex_type = "UTA" ex_type = "UTA"
elif ex_type == "ethics-studio": elif ex_type == "ethics-studio":
ex_type = "ES" ex_type = "ES"
elif ex_type == "undercurrent-as-below-so-above":
ex_type = "S4W2"
elif ex_type == "beta-x-living-canvas-at-irish-museum-of-modern-art-imma":
ex_type = "IMMA"
exhibitions = get_all_content('exhibition') exhibitions = get_all_content('exhibition')
print(ex_type)
return render_template('list-exhibitions.html', title="Exhibitions", content=exhibitions, ex_type=ex_type) return render_template('list-exhibitions.html', title="Exhibitions", content=exhibitions, ex_type=ex_type)
@app.route('/conferences') @app.route('/conferences')
@ -60,18 +78,24 @@ def event_articles(type, title, ex_type):
@app.route('/locations') @app.route('/locations')
def locations(): def locations():
return render_template('locations.html', title='Locations') location_info = contentful_service.get_location_info()
print(location_info)
return render_template('locations.html', title='Locations', locInfo=location_info)
def get_all_content(type): def get_all_content(type):
entries = client.entries({'content_type': type}) entries = client.entries({'content_type': type, 'fields.beta25': 'true'})
content_list = process_content(entries, type) content_list = process_content(entries, type)
return content_list return content_list
def get_content_by_title(title, pre_type): def get_content_by_title(title, pre_type):
type = pre_type[:-1] type = pre_type[:-1]
print(title) print(title)
entries = client.entries({'query': title, 'limit': 5}) entries = client.entries({
exact_matches = [] 'content_type': type,
'query': title,
'limit': 5,
'fields.beta25': 'true'
})
for entry in entries: for entry in entries:
try: try:
if getattr(entry, f'title_of_{type}') == title: if getattr(entry, f'title_of_{type}') == title:
@ -133,33 +157,7 @@ def process_content(entries, type):
# Sort the content list by the 'title' key alphabetically # Sort the content list by the 'title' key alphabetically
content_list.sort(key=lambda x: x['title'].lower()) content_list.sort(key=lambda x: x['title'].lower())
return content_list return content_list
def get_support_images():
# Specify the folder where images are stored
image_folder = os.path.join(app.static_folder, 'images/support')
# Define a list of supported image file extensions
valid_extensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp']
# List to hold the image file names
image_files = []
prio_image_files = []
prio_image_top_files = []
# Loop through files in the directory
for filename in os.listdir(image_folder):
# Check if the file is an image (by extension)
if os.path.splitext(filename)[1].lower() in valid_extensions:
if os.path.splitext(filename)[0].lower() == "dg" or os.path.splitext(filename)[0].lower() == "sw":
prio_image_top_files.append(filename)
elif os.path.splitext(filename)[0].lower() == "french-emb" or os.path.splitext(filename)[0].lower() == "nn" or os.path.splitext(filename)[0].lower() == "if":
prio_image_files.append(filename)
else:
image_files.append(filename)
return image_files, prio_image_files, prio_image_top_files
def format_datetime(dt): def format_datetime(dt):
date_str = dt.strftime('%d.%m.%y') date_str = dt.strftime('%d.%m.%y')

78
public/css/styles.css

@ -1,3 +1,8 @@
:root {
--prim-red: #0075FF;
--prim-blue: #0075FF;
}
html { html {
padding: 0; padding: 0;
margin: 0; margin: 0;
@ -37,8 +42,11 @@ p {
} }
a { a {
text-decoration: none; color: var(--prim-red);
color: #0075FF; font-weight: 200;
padding: 5px;
filter: drop-shadow(0 0 0.0rem var(--prim-red));
text-decoration: underline;
} }
hr { hr {
@ -48,7 +56,7 @@ hr {
margin: 0; margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
border-top: thin solid #0075FF; border-top: thin solid var(--prim-red);
} }
#socials { #socials {
@ -139,7 +147,7 @@ hr {
border: 1px solid; border: 1px solid;
text-align: center; text-align: center;
/* font-family: 'Syne Mono', monospace; */ /* font-family: 'Syne Mono', monospace; */
color: #0075FF; color: var(--prim-red);
cursor: pointer; cursor: pointer;
} }
@ -157,7 +165,7 @@ hr {
font-size: 30px; font-size: 30px;
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
font-weight: 300; font-weight: 300;
color: #0075FF; color: var(--prim-red);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 20px; gap: 20px;
@ -297,7 +305,7 @@ hr {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 20px; gap: 20px;
color:#0075FF; color:var(--prim-red);
} }
#main-container-article { #main-container-article {
@ -313,7 +321,7 @@ hr {
font-size: 26px; font-size: 26px;
width: 60%; width: 60%;
line-height: 40px; line-height: 40px;
color:#0075FF; color:var(--prim-red);
} }
#hyperlink-container { #hyperlink-container {
@ -335,18 +343,18 @@ hr {
flex-direction: row; flex-direction: row;
gap: 20px; gap: 20px;
width: fit-content; width: fit-content;
border-color: #0075FF; border-color: var(--prim-red);
background-size: cover; /* or contain, depending on your preference */ background-size: cover; /* or contain, depending on your preference */
background-repeat:repeat; background-repeat:repeat;
border-radius: 30px; border-radius: 30px;
padding: 10px; /* padding: 10px; */
padding-left: 25px; /* padding-left: 25px;
padding-right: 25px; padding-right: 25px; */
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
border: 1px solid; /*border: 1px solid;
/* font-family: 'Syne Mono', monospace; */ /* font-family: 'Syne Mono', monospace; */
color: #0075FF; color: var(--prim-red);
background-color: #ffffff95; /* background-color: var(--prim-red); */
} }
.hyperlink-home { .hyperlink-home {
@ -354,18 +362,17 @@ hr {
flex-direction: row; flex-direction: row;
gap: 20px; gap: 20px;
width: fit-content; width: fit-content;
border-color: #0075FF; border-color: var(--prim-red);
background-size: cover; /* or contain, depending on your preference */ background-size: cover; /* or contain, depending on your preference */
background-repeat:repeat; background-repeat:repeat;
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
text-decoration: underline; text-decoration: underline;
color: #ffffff; color: var(--prim-red);
background-color: #0075FF; /* background-color:var(--prim-red); */
font-size: 40px; font-size: 40px;
font-weight: 300; font-weight: 300;
padding: 5px; padding: 5px;
filter: drop-shadow(0 0 0.25rem black);
} }
.hyperlink-header { .hyperlink-header {
@ -373,14 +380,14 @@ hr {
flex-direction: row; flex-direction: row;
gap: 20px; gap: 20px;
width: fit-content; width: fit-content;
background-color: #0075FF; background-color: var(--prim-red);
background-size: cover; /* or contain, depending on your preference */ background-size: cover; /* or contain, depending on your preference */
background-repeat:repeat; background-repeat:repeat;
padding: 10px; padding: 10px;
padding-left: 25px; padding-left: 25px;
padding-right: 25px; padding-right: 25px;
color: white; color: white;
border-color: #0075FF; border-color:var(--prim-red);
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
text-transform: uppercase; text-transform: uppercase;
} }
@ -390,7 +397,7 @@ hr {
} }
.active-page { .active-page {
color: #0075FF; color: var(--prim-red);
background-color: white; background-color: white;
border: 1px solid; border: 1px solid;
} }
@ -462,7 +469,7 @@ hr {
.list-title { .list-title {
font-size: 20px; font-size: 20px;
color: #0075FF; color: var(--prim-red);
font-weight: 500; font-weight: 500;
font-family: 'JetBrains', monospace font-family: 'JetBrains', monospace
} }
@ -496,7 +503,7 @@ hr {
font-weight: 300; font-weight: 300;
} }
.list-info-text { #list-info-container p{
padding-bottom: 10px; padding-bottom: 10px;
} }
@ -504,7 +511,7 @@ hr {
font-size: 36px; font-size: 36px;
text-transform: uppercase; text-transform: uppercase;
font-weight: 700; font-weight: 700;
color: #0075FF; color: var(--prim-red);
text-decoration: underline; text-decoration: underline;
} }
@ -517,7 +524,7 @@ hr {
font-size: 20px; font-size: 20px;
gap: 20px; gap: 20px;
height: fit-content; height: fit-content;
color: #0075FF; color: var(--prim-red);
align-items: start; align-items: start;
overflow-x: scroll; overflow-x: scroll;
overflow-y: hidden; overflow-y: hidden;
@ -558,7 +565,7 @@ hr {
} }
#article-sep { #article-sep {
color: #0075FF; color: var(--prim-red);
} }
#article-container { #article-container {
@ -620,15 +627,15 @@ hr {
#article-information em { #article-information em {
font-size: 14px; /* font-size: 14px;
font-weight: 400; font-weight: 400; */
font-family: 'JetBrains', monospace; /* font-family: 'JetBrains', monospace; */
} }
#article-title { #article-title {
font-size: 25px; font-size: 25px;
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
color: #0075FF; color: var(--prim-red);
text-transform: uppercase; text-transform: uppercase;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -638,7 +645,7 @@ hr {
font-size: 25px; font-size: 25px;
padding-top: 20px; padding-top: 20px;
font-family: 'Inter', sans-serif; font-family: 'Inter', sans-serif;
color: #0075FF; color: var(--prim-red);
margin-bottom: 50px; margin-bottom: 50px;
width: fit-content; width: fit-content;
text-transform: uppercase; text-transform: uppercase;
@ -647,7 +654,7 @@ hr {
#article-artists { #article-artists {
font-family: 'JetBrains', monospace; font-family: 'JetBrains', monospace;
color: #0075FF; color: var(--prim-red);
text-transform: uppercase; text-transform: uppercase;
} }
@ -737,7 +744,7 @@ hr {
color: white; color: white;
width: fit-content; width: fit-content;
cursor: pointer; cursor: pointer;
background-color: #0075FF; background-color: var(--prim-red);
padding: 5px; padding: 5px;
} }
@ -770,6 +777,7 @@ hr {
.exh-container h1 { .exh-container h1 {
text-decoration: underline; text-decoration: underline;
cursor: pointer; cursor: pointer;
line-height: 50px;
} }
.exh-info { .exh-info {
@ -823,7 +831,7 @@ animation: 2s fadeInUp;
} }
.hyperlink { .hyperlink {
padding-left: 5vw; /* padding-left: 5vw; */
width: 80%; width: 80%;
} }
@ -1044,7 +1052,7 @@ animation: 2s fadeInUp;
.hyperlink { .hyperlink {
gap: 10px; gap: 10px;
width: auto; width: auto;
justify-content: center; /* justify-content: center; */
margin-left: 0px; margin-left: 0px;
margin-right: 0px; margin-right: 0px;
text-align: center; text-align: center;

48
public/js/locations.js

@ -1,38 +1,3 @@
// Example location data
const locationData = {
'digital-hub': {
text: 'The Digital Hub, 10-13 Thomas St, The Liberties, Dublin 8, D08 PX8H',
imageUrl: '/public/images/locations/digital-hub.webp',
direction: 'https://www.google.com/maps/dir//115-117,+The+Coombe,+The+Liberties,+Dublin,+D08+A970/@53.3391179,-6.3569591,12z/data=!4m8!4m7!1m0!1m5!1m1!1s0x48670e89423ed249:0x8aa3669566840ff9!2m2!1d-6.274559!2d53.3391463?entry=ttu'
},
'pallas-projects': {
text: '115-117, The Coombe, The Liberties, Dublin, D08 A970',
imageUrl: 'public/images/locations/pallas.webp',
direction: 'https://www.google.com/maps?gs_lcrp=EgZjaHJvbWUqBggAEEUYOzIGCAAQRRg7MgYIARBFGDkyBggCEEUYOzIGCAMQRRg8MgYIBBAuGEDSAQgxNDA3ajBqOagCALACAQ&um=1&ie=UTF-8&fb=1&gl=ie&sa=X&geocode=KUnSPkKJDmdIMfkPhGaVZqOK&daddr=115-117,+The+Coombe,+The+Liberties,+Dublin,+D08+A970'
},
'fire-station': {
text: '9 - 12 Buckingham Street Lower, Mountjoy, Dublin 1',
imageUrl: 'public/images/locations/fire.webp',
direction: 'https://www.google.com/maps/place//data=!4m2!3m1!1s0x48670e897d6ec3f7:0x2eee044a4b511022?sa=X&ved=1t:8290&ictx=111'
},
'imma': {
text: 'Royal Hospital Kilmainham, Military Rd, Kilmainham, Dublin 8, D08 FW31',
imageUrl: 'public/images/locations/imma.webp',
direction: 'https://www.google.com/maps/place//data=!4m2!3m1!1s0x48670c462efd7fcd:0x3dc9b365e0e6ace?sa=X&ved=1t:8290&ictx=111'
},
'digital-bank': {
text: '85 James St, The Liberties, Dublin 8, D08 C2PR',
imageUrl: '/public/images/locations/bank.webp',
direction: 'https://www.google.com/maps/place//data=!4m2!3m1!1s0x48670d2fc081f95f:0xa5173048f627d0?sa=X&ved=1t:8290&ictx=111'
},
'beckett': {
text: 'Samuel Beckett Theatre, Trinity College, Dublin',
imageUrl: '/public/images/locations/beckett.png',
direction: 'https://maps.app.goo.gl/a1T7HktmKdxNcFWB7'
},
// Add more locations as needed
};
// Function to update the content // Function to update the content
function updateLocationContent(locationKey) { function updateLocationContent(locationKey) {
const location = locationData[locationKey]; const location = locationData[locationKey];
@ -43,10 +8,15 @@ function updateLocationContent(locationKey) {
} }
} }
// Add event listeners to buttons
document.querySelectorAll('.location-button').forEach(button => { document.querySelectorAll('.location-button').forEach(button => {
button.addEventListener('click', (event) => { button.addEventListener('click', (event) => {
const locationKey = event.currentTarget.getAttribute('data-location'); const index = event.currentTarget.getAttribute('data-location');
updateLocationContent(locationKey); const locInfo = window.locInfo; // We'll inject this below
const location = locInfo[index];
if (location) {
document.getElementById('location-text').innerText = location.directions;
document.getElementById('location-img').src = location.image;
document.getElementById('location-direction').href = location.url;
}
}); });
}); });

6
templates/_nav.html

@ -1,7 +1,9 @@
<div id="nav-bar"> <div id="nav-bar">
<a href="/"><div class="nav-element">BETA FESTIVAL (2024)</div></a> <a href="/"><div class="nav-element">BETA FESTIVAL (2025)</div></a>
<div class="nav-element nav-element-align"> <div class="nav-element nav-element-align">
<div>NOV 1 - 17 | DUBLIN</div> {% if festival_general_info %}
<div>{{ festival_general_info.startDate }} - {{ festival_general_info.endDate }} | DUBLIN</div>
{% endif %}
</div> </div>
</div> </div>
<hr> <hr>

4
templates/article.html

@ -10,8 +10,8 @@
<div id="article-container"> <div id="article-container">
<div id="article-text"> <div id="article-text">
<div id="article-title"> <div id="article-title">
{% if article.title == 'This Is How I Roll' %} {% if article.title == 'Not Breaking This Wave Drowns Hate' %}
<div>This Is How 👁️ Roll</div> <div>~~ Not Breaking ~~ ~~ This Wave Drowns Hate ~~</div>
{% else %} {% else %}
<div>{{ article.title }}</div> <div>{{ article.title }}</div>
{% endif %} {% endif %}

12
templates/base.html

@ -3,15 +3,15 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="og:description" content="The Beta Festival 2024 catalogue showcasing and archiving all exhibitions, events, and conferences which will be on as part of this years festival." /> <meta name="og:description" content="The Beta Festival 2025 catalogue showcasing and archiving all exhibitions, events, and conferences which will be on as part of this years festival." />
<meta name="description" content="The Beta Festival 2024 catalogue showcasing and archiving all exhibitions, events, and conferences which will be on as part of this years festival." /> <meta name="description" content="The Beta Festival 2025 catalogue showcasing and archiving all exhibitions, events, and conferences which will be on as part of this years festival." />
<meta content="Beta Festival 2024" property="og:title"/> <meta content="Beta Festival 2025" property="og:title"/>
<meta content="Beta Festival 2024" property="og:site_name"/> <meta content="Beta Festival 2025" property="og:site_name"/>
<meta content="website" property="og:type"/> <meta content="website" property="og:type"/>
<meta name="keywords" content="beta festival, 2024, dublin, art and technology, digital art" /> <meta name="keywords" content="beta festival, 2025, dublin, art and technology, digital art" />
<meta name="robots" content="all" /> <meta name="robots" content="all" />
<meta name="language" content="en-ie" /> <meta name="language" content="en-ie" />
<title>Beta Festival 2024 {% block title %}{% endblock %}</title> <title>Beta Festival 2025 {% block title %}{% endblock %}</title>
<link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" rel="stylesheet">

21
templates/index.html

@ -26,26 +26,21 @@
<div>\Locations</div> <div>\Locations</div>
</div></a> </div></a>
</div> </div>
<p>
Beta is a new festival of art and technology critically engaging with the impact of emerging technologies on society. Taking Ireland’s role as a central node in today's wired world as a starting point, Beta showcases and celebrates Ireland’s research and artistic communities through a combination of creativity, debate and experimentation. Beta allows members of the public to engage playfully and critically with new technologies essentially beta testing ethical issues facing society {% if festival_general_info %}
</p> {{ festival_general_info.text | safe}}
<p> {% endif %}
The 2024 edition of Beta will explore a range of themes relating to AI, Automated Systems, and the politics of resistance in an algorithmic age. Through a programme of exhibitions, workshops and talks, the festival will interrogate what kinds of powers reside in technology.
</p>
<p>
The festival is co-founded by The Digital Hub and supported by Science Week with additional support for the 2024 programme from Screen Ireland, the French Embassy, Institut français, British Council, Smart Dublin, Cultural and Creative Industries Skillsnet, Arts Council Festival Investment Scheme and Creative Europe Desk Ireland.
</p>
<div id="index-socials"> <div id="index-socials">
<a href="https://betafestival.ie/" target="_blank"><span>↑ beta-festival</span></a> <a href="https://betafestival.ie/" target="_blank"><span>↑ beta-festival</span></a>
<a href="https://x.com/BetaFest_IRL" target="_blank"><span>twitter</span></a> <a href="https://www.eventbrite.ie/o/beta-an-art-technology-festival-in-ireland-71330964833" target="_blank"><span>↑ eventbrite</span></a>
<a href="https://www.instagram.com/betafest_irl/" target="_blank"><span>↑ instagram</span></a> <a href="https://www.instagram.com/betafest_irl/" target="_blank"><span>↑ instagram</span></a>
</div> </div>
<div id="index-support-prio-top"> <div id="index-support-prio-top">
{% for img in prio_img_top %} {% for img in prio_img_top %}
<div class="index-prio-img"> <div class="index-prio-img">
<img src="{{ url_for('static', filename='images/support/' + img) }}"> <img src="{{ img }}">
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -53,7 +48,7 @@
<div id="index-support-prio"> <div id="index-support-prio">
{% for img in prio_img %} {% for img in prio_img %}
<div class="index-prio-img"> <div class="index-prio-img">
<img src="{{ url_for('static', filename='images/support/' + img) }}"> <img src="{{ img }}">
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
@ -61,7 +56,7 @@
<div id="index-support"> <div id="index-support">
{% for img in sup_img_list %} {% for img in sup_img_list %}
<div class="index-support-img"> <div class="index-support-img">
<img src="{{ url_for('static', filename='images/support/' + img) }}"> <img src="{{ img }}">
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

22
templates/list-exhibitions.html

@ -7,9 +7,9 @@
{% include '_nav.html' %} {% include '_nav.html' %}
{% include '_list-header.html'%} {% include '_list-header.html'%}
<div id="main-container"> <div id="main-container">
{% if ex_type == "UTA" %} {% if ex_type == "S4W2" %}
<div class="list-header"> <div class="list-header">
Unsettling the Algorithm Undercurrent: As Below, So Above
</div> </div>
{% endif %} {% endif %}
{% if ex_type == "LAN" %} {% if ex_type == "LAN" %}
@ -22,13 +22,18 @@
Ethics Studio ↑ Ethics Studio ↑
</div> </div>
{% endif %} {% endif %}
{% if ex_type == "IMMA" %}
<div class="list-header">
Beta x Living Canvas at Irish Museum of Modern Art (IMMA) ↑
</div>
{% endif %}
<div id="list-container" class="fadeInUp-animation"> <div id="list-container" class="fadeInUp-animation">
{% for event in content %} {% for event in content %}
{% if event.exh_type == ex_type %} {% if event.exh_type == ex_type %}
{% if ex_type == "UTA"%} {% if ex_type == "S4W2"%}
<a href='/{{ title.lower() }}/unsettling-the-algorithm/{{ event.title }}'> <a href='/{{ title.lower() }}/undercurrent-as-below-so-above/{{ event.title }}'>
{% endif %} {% endif %}
{% if ex_type == "LAN"%} {% if ex_type == "LAN"%}
<a href='/{{ title.lower() }}/local-artists-network/{{event.title}}'> <a href='/{{ title.lower() }}/local-artists-network/{{event.title}}'>
@ -36,13 +41,16 @@
{% if ex_type == "ES"%} {% if ex_type == "ES"%}
<a href='/{{ title.lower() }}/ethics-studio/{{event.title}}'> <a href='/{{ title.lower() }}/ethics-studio/{{event.title}}'>
{% endif %} {% endif %}
{% if ex_type == "IMMA"%}
<a href='/{{ title.lower() }}/beta-x-living-canvas-at-irish-museum-of-modern-art-imma/{{event.title}}'>
{% endif %}
<div class="list"> <div class="list">
<div class="list-image"> <div class="list-image">
<img src="{{ event.image }}" alt="{{event.title}}" loading="lazy"> <img src="{{ event.image }}" alt="{{event.title}}" loading="lazy">
<div class="list-image-overlay"></div> <div class="list-image-overlay"></div>
</div> </div>
{% if event.title == 'This Is How I Roll' %} {% if event.title == 'Not Breaking This Wave Drowns Hate' %}
<div class="list-title">This Is How 👁️ Roll</div> <div class="list-title">~~ Not Breaking ~~ ~~ This Wave Drowns Hate ~~</div>
{% else %} {% else %}
<div class="list-title">{{ event.title }}</div> <div class="list-title">{{ event.title }}</div>
{% endif %} {% endif %}
@ -57,6 +65,8 @@
<div class="list-date">● {{ event.times | join(', ')}}</div> <div class="list-date">● {{ event.times | join(', ')}}</div>
{% endif %} {% endif %}
<div class="list-date">● {{ event.location[0] }}</div> <div class="list-date">● {{ event.location[0] }}</div>
</div> </div>
</div> </div>
</a> </a>

30
templates/list.html

@ -8,19 +8,27 @@
{% include '_list-header.html'%} {% include '_list-header.html'%}
<div id="main-container"> <div id="main-container">
<div id="list-info-container"> <div id="list-info-container">
{% if title == 'Conferences'%} {% if festival_general_info %}
<p class="list-info-text">Exploring the relationship between technology and power, Beta Festival’s 2024 conference explores how digital infrastructures and software have reshaped society, culture, and politics. Spanning two days, the event delves into the ways technology influences institutions, political interests, and economic and cultural practices. Bringing together artists, technologists, and researchers, the conference participants will question the forms of power and control embedded in digital infrastructures and explore strategies for redesigning these systems to meet societal demands for both individual and collective autonomy.</p> {% if title == 'Conferences'%}
<p class="list-info-text">On the first day, discussions will focus on the ethics of AI development, its impact on democracy, and the manipulation of political systems, as well as how artists are leveraging digital tools to resist surveillance and platform capitalism. The second day will explore the transformation of creative practices by these technologies, with sessions addressing copyright and intellectual property in the age of AI, the preservation of digital cultural memory, counter-archives, and new possibilities for immersive and interactive storytelling.</p> {{ festival_general_info.textConference | safe }}
<p class="list-info-text">Throughout the conference, keynote speakers Abeba Birhane, an accountability expert, and Kay Watson, a specialist in art and technology, will offer insights into how AI is reshaping society and culture, while exploring the limits and possibilities of individual and collective agency in this rapidly evolving digital landscape.</p> {% endif %}
{% endif %}
{% if title == 'Events'%} {% if title == 'Events'%}
<p class="list-info-text">Beta Festival will feature a variety of performances, workshops and discussions as part of this year's programme including a number of events with our festival research partner ADAPT Research Centre and collaborations with D.A.T.A., Base, Fire Station Artists Studios, Creative Futures Academy and Creative Sparks Fab Lab.</p> {{ festival_general_info.textEvent | safe }}
<p class="list-info-text">We will also present Noire (France) in association with the French Embassy and Institut français, the Cannes award-winning immersive experience directed by Stéphane Foenkinos and Pierre-Alain Giraud, based on the work by Tania de Montaigne, produced by Novaya in partnership with the Centre Pompidou, co-produced with Flash Forward Entertainment.</p> {% endif %}
{% endif %}
{% if title == 'Exhibitions' %} {% if title == 'Exhibitions' %}
{% include '_ex.html' %} {% for ex in exhibition_info %}
<div class="exh-container">
<a href="exhibitions/{{ ex.url }}"><h1>{{ ex.title }}</h1></a>
{{ ex.description | safe }}
<div class="exh-info">
<p>Date: {{ ex.start_date }} -> {{ ex.end_date }}</p>
<p>Location: {{ ex.location }}</p>
</div>
</div>
{% endfor %}
{% endif %}
{% endif %} {% endif %}
</div> </div>

53
templates/locations.html

@ -4,33 +4,32 @@
{% block content %} {% block content %}
<div id="main-wrapper"> <div id="main-wrapper">
{% include '_nav.html' %} {% include '_nav.html' %}
<div id="main-container-locations"> <div id="main-container-locations">
<div id="location-list"> <div id="location-list">
<div id="location-button-list"> <div id="location-button-list">
<div class="location-button" data-location="digital-hub">Digital Depot at The Digital Hub</div> {% for loc in locInfo %}
<div class="location-button" data-location="digital-bank">The Bank at The Digital Hub</div> <div class="location-button" data-location="{{ loop.index0 }}">{{ loc.name }}</div>
<div class="location-button" data-location="pallas-projects">Pallas Projects/Studios</div> {% endfor %}
<div class="location-button" data-location="fire-station">Fire Station Artists Studios</div> </div>
<div class="location-button" data-location="beckett">Samuel Beckett Theatre</div> <div id="location-information">
</div> <div id="location-text">
<div id="location-information"> {{ locInfo[0].directions }}
<div id="location-text"> </div>
The Digital Hub, 10-13 Thomas St, The Liberties, Dublin 8, D08 PX8H <a id="location-direction" target="_blank" href="{{ locInfo[0].url }}">
</div> <div class="location-button">↳ Directions</div>
<a id="location-direction" target="_blank" href="https://www.google.com/maps/dir//115-117,+The+Coombe,+The+Liberties,+Dublin,+D08+A970/@53.3391179,-6.3569591,12z/data=!4m8!4m7!1m0!1m5!1m1!1s0x48670e89423ed249:0x8aa3669566840ff9!2m2!1d-6.274559!2d53.3391463?entry=ttu"> </a>
<div class="location-button">↳ Directions</div> </div>
</a> </div>
</div> <div id="location-images">
</div> <div id="location-image">
<div id="location-images"> <img id="location-img" src="{{ locInfo[0].image }}">
<div id="location-image"> </div>
<img id="location-img" src="{{ url_for('static', filename='images/locations/digital-hub.webp') }}"> </div>
</div> </div>
</div>
</div>
</div> </div>
<script>
<script type="module" src="{{ url_for('static', filename='js/skybox.js') }}"></script> window.locInfo = {{ locInfo|tojson }};
</script>
<script type="module" src="{{ url_for('static', filename='js/locations.js') }}"></script> <script type="module" src="{{ url_for('static', filename='js/locations.js') }}"></script>
{% endblock content %} {% endblock content %}
Loading…
Cancel
Save