Popravki za timeline
Deploy to Production on Develop Push / deploy (push) Successful in 1m17s Details

This commit is contained in:
Mark Poljanšek 2025-09-09 14:21:55 +02:00
parent eb3b804dbc
commit d9ed2a449f
5 changed files with 97 additions and 169 deletions

View File

@ -38,17 +38,7 @@
padding: 0 32px;
}
/* The vertical line */
.timeline-container::before {
content: '';
position: absolute;
left: 40px;
top: 10px;
bottom: 10px;
width: 2px;
background-color: #EAECF0; /* Gray/200 */
z-index: 1; /* Ensure the line is behind the markers */
}
/* Navpična črta je bila odstranjena z izbrisom pravila .timeline-container::before */
/* 2. Timeline items and markers */
@ -168,10 +158,6 @@
padding: 0 24px;
}
.timeline-container::before {
left: 24px;
}
.timeline-item {
padding-left: 56px;
margin-bottom: 48px;

View File

@ -193,10 +193,10 @@
<section class="partners-section">
<div class="partners-container">
<img src="../images/2.%20Slo%20embassy%20in%20Skopje_mcd-1.png" alt="Slovenian Embassy in Skopje logo">
<img src="../images/5.%20UL_EF-logoENG-HOR-CMYK_color-1.png" alt="University of Ljubljana School of Economics and Business logo">
<img src="../images/3.%20Logo_NLB_Banka_CMYK_MAC-1.png" alt="NLB Banka logo">
<img src="../images/1.%20mkd%20embassy%20in%20slovenia.png" alt="Embassy of North Macedonia in Slovenia logo">
<img src="../images/2.%20Slo%20embassy%20in%20Skopje_mcd-1.webp" alt="Slovenian Embassy in Skopje logo">
<img src="../images/5.%20UL_EF-logoENG-HOR-CMYK_color-1.webp" alt="University of Ljubljana School of Economics and Business logo">
<img src="../images/3.%20Logo_NLB_Banka_CMYK_MAC-1.webp" alt="NLB Banka logo">
<img src="../images/1.%20mkd%20embassy%20in%20slovenia.webp" alt="Embassy of North Macedonia in Slovenia logo">
</div>
</section>

0
l.php Normal file
View File

View File

@ -205,22 +205,22 @@ document.addEventListener('DOMContentLoaded', function() {
const activitiesData = {
'Student Support': {
text: "We know moving to a new country can feel overwhelming, so were here to make it easier. From helping you with university applications to finding your way around student life in Slovenia, you can always count on us. We offer free consultations, answer your questions on Instagram and Facebook (yes, even late at night), and host events where you can meet others and hear real experiences first-hand. With mentorship, info sessions, and a friendly community by your side, youll never have to go through the journey alone.",
imgSrc: "../images/img1-08.09.2025.png",
imgSrc: "../images/img1-08.09.2025.webp",
altText: "Students receiving support and guidance"
},
'Fun & Social Life': {
text: "Student life is so much more than lectures and exams — its about the moments in between. At MSOS, we create those moments: from parties, concerts, and casual hangouts, to cinema nights, excursions, and team-building trips. We also host talks and events where you can share ideas, meet new people, and feel part of something bigger. Whether youre connecting with Macedonian students or making friends with Slovenians and internationals, our activities are all about building a community where you can relax, have fun, and create memories that last long after university.",
imgSrc: "../images/img2-08.09.2025.png",
imgSrc: "../images/img2-08.09.2025.webp",
altText: "Students socializing and having fun at an event"
},
'Education & Culture': {
text: "Studying abroad isnt only about lectures and exams — its also about growing as a person. Thats why we mix learning with culture. We run study groups and small workshops where you can share knowledge and pick up new skills. At the same time, we keep our traditions alive with cultural evenings, music, food, and gatherings that remind us of home. Its a balance: support for your studies, and a space to stay connected to who we are.",
imgSrc: "../images/img3-08.09.2025.png",
imgSrc: "../images/img3-08.09.2025.webp",
altText: "An educational workshop or cultural event"
},
'Student Representation': {
text: "Studying abroad comes with challenges, and sometimes students need a voice thats heard. At MSOS, we take that role seriously. We organize meetings with government representatives, ministries, embassies, universities, and other key institutions to make sure the interests of Macedonian students in Slovenia are on the table. From campus issues to academic policies and integration, we work to solve problems, push for positive changes, and create a better experience for all of us.",
imgSrc: "../images/img4-08.09.2025.png",
imgSrc: "../images/img4-08.09.2025.webp",
altText: "MSOS members representing students at a formal meeting"
}
};

View File

@ -9,7 +9,14 @@ PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) # Predvideva, da je sk
IMAGES_DIR_NAME = "images"
ORIGINAL_IMAGES_SUBDIR_NAME = "original" # Podmapa znotraj IMAGES_DIR_NAME
HTML_ROOT_DIRS = ['en', 'si', 'mk'] # Jezikovne mape, kjer se nahajajo HTML datoteke za posodobitev
# Mape, v katerih skripta išče datoteke za posodobitev referenc
DIRECTORIES_TO_SCAN = ['en', 'si', 'mk', 'css']
# Dodatne datoteke v korenski mapi za preverjanje
FILES_IN_ROOT_TO_SCAN = ['main.js']
# Končnice datotek, v katerih iščemo in posodabljamo reference na slike
FILE_EXTENSIONS_TO_UPDATE = ['.html', '.css', '.js']
WEBP_QUALITY = 80 # Kakovost kompresije za WebP (0-100). Višja številka = boljša kakovost, večja datoteka.
MAX_IMAGE_DIMENSION = 1920 # Maksimalna dimenzija (širina ali višina) za pomanjšanje, če je slika večja. Ohranijo se razmerja. Če je 0, se ne pomanjšuje.
@ -32,30 +39,18 @@ def optimize_image(image_path, output_path, quality, max_dim, dry_run=False):
with Image.open(image_path) as img:
original_size = img.size
# Pretvorba v RGB, če je potrebno (WebP ne podpira npr. paletnih slik brez RGB pretvorbe)
if img.mode in ('P', 'LA', 'RGBA'):
if img.mode == 'RGBA':
# Za RGBA slike, ki so shranjene v WebP, se shrani z alfa kanalom.
# Če želimo brez alfa, bi morali ustvariti belo ozadje:
# new_img = Image.new("RGB", img.size, (255, 255, 255))
# new_img.paste(img, mask=img.split()[3])
# img = new_img
pass # Ohranimo RGBA za WebP z alfa kanalom
else:
img = img.convert("RGB")
if img.mode != 'RGBA':
img = img.convert("RGBA")
# Pomanjšanje slike, če je prevelika
if max_dim > 0 and (img.width > max_dim or img.height > max_dim):
print(f" Pomanjšujem sliko {os.path.basename(image_path)} iz {img.width}x{img.height} ...", end="")
img.thumbnail((max_dim, max_dim), Image.LANCZOS) # Lanczos za kakovostno pomanjšanje
img.thumbnail((max_dim, max_dim), Image.LANCZOS)
print(f" na {img.width}x{img.height}")
else:
print(f" Obdelujem sliko {os.path.basename(image_path)} ({img.width}x{img.height})...", end="")
if not dry_run:
# Shrani v WebP
# Za RGBA WebP slike, `lossless=True` ali `quality` določita kompresijo.
# `method` (0-6) nadzoruje hitrost/kakovost kodiranja. Višja = počasneje/boljše.
img.save(output_path, "webp", quality=quality, method=6)
print(f" Shrani v {os.path.basename(output_path)} (kvaliteta: {quality}).")
else:
@ -69,111 +64,77 @@ def optimize_image(image_path, output_path, quality, max_dim, dry_run=False):
print(f" Napaka pri optimizaciji slike '{image_path}': {e}")
return False
def update_html_references(html_file_path, old_filename_with_ext, new_filename_with_ext, dry_run=False):
def update_file_references(file_path, old_filename_with_ext, new_filename_with_ext, dry_run=False):
"""
Poišče staro ime slike v HTML datoteki in ga zamenja z novim imenom WebP.
Poišče staro ime slike v datoteki (HTML, CSS, JS) in ga zamenja z novim imenom WebP.
"""
try:
with open(html_file_path, 'r', encoding='utf-8') as f:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
except Exception as e:
print(f" Napaka pri branju HTML datoteke '{html_file_path}': {e}")
print(f" Napaka pri branju datoteke '{file_path}': {e}")
return False
original_content = content
changed = False
# Uporabimo preprosto zamenjavo niza, ki je varna, saj zamenjujemo celotno ime datoteke z končnico.
# To bo delovalo za poti v narekovajih (HTML, JS) in v url() (CSS).
if old_filename_with_ext in content:
content = content.replace(old_filename_with_ext, new_filename_with_ext)
# Izdelava regularnega izraza, ki bo iskal staro ime datoteke znotraj poti
# in ga zamenjal z novim. Poskrbimo, da ujemanje ni preveč široko.
# Iščemo vzorce kot so src=".../staro_ime.ext", url('.../staro_ime.ext'), itd.
# Prvi del ujame začetek atributa/URL-ja (npr. src=" ali url()...)
# Drugi del ujame *katerokoli pot* pred imenom datoteke (npr. ../images/)
# Tretji del ujame staro ime datoteke z razširitvijo
# Četrti del ujame zaključek atributa/URL-ja
# Regex pattern to match filename.ext in various HTML/CSS contexts
# Example: 1-logo.png -> 1-logo.webp
# It must replace only the filename, not parts of other filenames.
# This pattern is specifically designed to handle common cases where image names appear
# in src/srcset/href attributes or url() CSS functions.
# It uses named groups for clarity and robustness.
# Group `before_path` captures anything before the actual filename to ensure we only
# target image references and not random text.
# Group `path` captures the relative path (e.g., ../images/).
# We need to escape the old filename for regex safety.
escaped_old_filename = re.escape(old_filename_with_ext)
# Pattern to find old_filename_with_ext in common image contexts.
# This pattern looks for the filename preceded by either:
# - `src="` or `srcset="` or `href="` followed by any path characters
# - `url(` followed by optional quotes and any path characters
# It attempts to capture the path prefix to preserve it.
# This is a complex regex. Let's simplify the strategy slightly to avoid over-matching.
# Iterate through potential contexts and replace just the filename within that context.
# Contexts: src="...", srcset="...", url('...'), url("..."), url(...)
patterns = [
# For src, srcset, href attributes (usually contain path/filename.ext)
re.compile(rf'(?P<attr>src|srcset|href)=["\'](?P<path>.*?){escaped_old_filename}(?P<end>["\'])', re.IGNORECASE),
# For url() in CSS (can be with single, double quotes or no quotes)
re.compile(rf'(url\([\'"]*)(?P<path>.*?){escaped_old_filename}([\'"]*\))', re.IGNORECASE)
]
for pattern in patterns:
content, num_replacements = pattern.subn(
lambda m: f"{m.group('attr')}=\"{m.group('path')}{new_filename_with_ext}\"" if 'attr' in m.groupdict() else f"{m.group(1)}{m.group('path')}{new_filename_with_ext}{m.group(3)}",
content
)
if num_replacements > 0:
changed = True
print(f" Zamenjano {num_replacements} referenc za '{old_filename_with_ext}' z '{new_filename_with_ext}' v '{html_file_path}'.")
if changed and not dry_run:
backup_path = html_file_path + ".bak"
if content != original_content:
if not dry_run:
backup_path = file_path + ".bak"
try:
shutil.copy2(html_file_path, backup_path)
# print(f" Varnostna kopija ustvarjena: {backup_path}") # Odkomentiraj za več izpisa
# Preverimo, ali datoteka obstaja, preden jo kopiramo
if os.path.exists(file_path):
shutil.copy2(file_path, backup_path)
except Exception as e:
print(f" Napaka pri ustvarjanju varnostne kopije za '{html_file_path}': {e}")
print(f" Napaka pri ustvarjanju varnostne kopije za '{file_path}': {e}")
return False
try:
with open(html_file_path, 'w', encoding='utf-8') as f:
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
# print(f" HTML datoteka posodobljena: {html_file_path}") # Odkomentiraj za več izpisa
print(f" Posodobljene reference za '{old_filename_with_ext}' v '{os.path.relpath(file_path, PROJECT_ROOT)}'.")
return True
except Exception as e:
print(f" Napaka pri zapisovanju v HTML datoteko '{html_file_path}': {e}")
print(f" Napaka pri zapisovanju v datoteko '{file_path}': {e}")
return False
elif changed and dry_run:
print(f" DRY RUN: HTML datoteka '{html_file_path}' bi bila posodobljena (reference za '{old_filename_with_ext}' z '{new_filename_with_ext}').")
return True # Return true in dry_run if changes would have occurred
else:
# print(f" Ni referenc za '{old_filename_with_ext}' v '{html_file_path}'.") # Odkomentiraj za več izpisa
print(f" DRY RUN: Reference za '{old_filename_with_ext}' bi bile posodobljene v '{os.path.relpath(file_path, PROJECT_ROOT)}'.")
return True
return False
def find_html_files(root_dir):
def find_files_to_update(scan_dirs, root_files):
"""
Rekurzivno poišče vse HTML datoteke v določenem korenskem imeniku.
Vrne seznam absolutnih poti do datotek.
Rekurzivno poišče vse datoteke z ustreznimi končnicami v podanih mapah.
"""
html_files = []
for dirpath, _, filenames in os.walk(root_dir):
found_files = []
# Najprej poišči datoteke v navedenih mapah
for directory in scan_dirs:
dir_path = os.path.join(PROJECT_ROOT, directory)
if os.path.isdir(dir_path):
for dirpath, _, filenames in os.walk(dir_path):
for filename in filenames:
if filename.endswith(".html"):
html_files.append(os.path.join(dirpath, filename))
return html_files
if any(filename.endswith(ext) for ext in FILE_EXTENSIONS_TO_UPDATE):
found_files.append(os.path.join(dirpath, filename))
else:
print(f"Opozorilo: Mapa za skeniranje '{dir_path}' ne obstaja. Preskakujem.")
# Nato dodaj posamezne datoteke iz korenske mape
for filename in root_files:
file_path = os.path.join(PROJECT_ROOT, filename)
if os.path.isfile(file_path):
found_files.append(file_path)
# Vrne unikaten, sortiran seznam poti
return sorted(list(set(found_files)))
# --- Glavna funkcija ---
def main():
parser = argparse.ArgumentParser(description="Skripta za optimizacijo slik (pretvorba v WebP) in posodobitev HTML referenc.")
parser = argparse.ArgumentParser(description="Skripta za optimizacijo slik (pretvorba v WebP) in posodobitev referenc v HTML, CSS in JS datotekah.")
parser.add_argument("--dry-run", action="store_true", help="Izvede operacije, vendar ne spreminja datotek in ne premika originalnih slik.")
args = parser.parse_args()
@ -185,19 +146,18 @@ def main():
return
if not args.dry_run:
# Ustvari mapo za originalne slike, če ne obstaja
os.makedirs(original_images_full_path, exist_ok=True)
print(f"Mapa za originalne slike: '{original_images_full_path}' (ustvarjena, če ni obstajala).")
else:
print(f"DRY RUN: Mapa za originalne slike bi bila '{original_images_full_path}'.")
optimized_images_map = [] # Seznam slovarjev: {'old_name': 'slika.jpg', 'new_name': 'slika.webp', 'old_full_path': ..., 'new_full_path': ...}
optimized_images_map = []
print("\n--- ZAČETEK OPTIMIZACIJE SLIK ---")
for filename in os.listdir(images_full_path):
if filename == ORIGINAL_IMAGES_SUBDIR_NAME:
continue # Preskoči mapo za originalne slike
continue
file_path = os.path.join(images_full_path, filename)
@ -213,27 +173,14 @@ def main():
new_filename = f"{name}.webp"
new_file_path = os.path.join(images_full_path, new_filename)
# Preveri, če WebP slika že obstaja in je starejša od originalne
if os.path.exists(new_file_path) and os.path.getmtime(new_file_path) > os.path.getmtime(file_path):
print(f" WebP različica '{new_filename}' že obstaja in je novejša od originala. Preskakujem optimizacijo.")
# Vseeno jo dodaj v mapo za posodobitev referenc
optimized_images_map.append({
'old_name': filename,
'new_name': new_filename,
'old_full_path': file_path,
'new_full_path': new_file_path
})
optimized_images_map.append({'old_name': filename, 'new_name': new_filename})
continue
if optimize_image(file_path, new_file_path, WEBP_QUALITY, MAX_IMAGE_DIMENSION, args.dry_run):
optimized_images_map.append({
'old_name': filename,
'new_name': new_filename,
'old_full_path': file_path,
'new_full_path': new_file_path
})
optimized_images_map.append({'old_name': filename, 'new_name': new_filename})
if not args.dry_run:
# Premakni originalno sliko v 'original' mapo
try:
shutil.move(file_path, os.path.join(original_images_full_path, filename))
print(f" Originalna slika premaknjena: '{filename}' -> '{ORIGINAL_IMAGES_SUBDIR_NAME}/'.")
@ -244,45 +191,40 @@ def main():
else:
print(f" Preskakujem datoteko (ni slika za optimizacijo): '{filename}'.")
else:
print(f" Preskakujem (ni datoteka): '{filename}'.")
if not optimized_images_map:
print("\nNi slik za optimizacijo ali pa so že optimizirane. Preskakujem posodabljanje HTML referenc.")
print("\nNi slik za optimizacijo ali pa so že optimizirane. Preskakujem posodabljanje referenc.")
print("\n--- OPTIMIZACIJA SLIK ZAKLJUČENA ---")
return
print("\n--- ZAČETEK POSODABLJANJA HTML REFERENC ---")
print("\n--- ZAČETEK POSODABLJANJA REFERENC V DATOTEKAH ---")
all_html_files = []
for lang_dir_name in HTML_ROOT_DIRS:
lang_full_path = os.path.join(PROJECT_ROOT, lang_dir_name)
if os.path.isdir(lang_full_path):
all_html_files.extend(find_html_files(lang_full_path))
else:
print(f"Opozorilo: Jezikovna mapa '{lang_full_path}' ne obstaja. Preskakujem iskanje HTML datotek v njej.")
all_files_to_update = find_files_to_update(DIRECTORIES_TO_SCAN, FILES_IN_ROOT_TO_SCAN)
if not all_html_files:
print("Ni najdenih HTML datotek za posodobitev referenc.")
if not all_files_to_update:
print("Ni najdenih datotek za posodobitev referenc (.html, .css, .js).")
print("\n--- OPTIMIZACIJA SLIK ZAKLJUČENA ---")
return
updated_html_files_count = 0
for html_file in all_html_files:
file_changed = False
updated_files_count = 0
processed_files = set()
for file_path in all_files_to_update:
if file_path in processed_files:
continue
file_changed_in_this_run = False
for img_info in optimized_images_map:
old_name = img_info['old_name']
new_name = img_info['new_name']
if update_file_references(file_path, img_info['old_name'], img_info['new_name'], args.dry_run):
file_changed_in_this_run = True
# Kliče update_html_references in preveri, ali je bila datoteka spremenjena
if update_html_references(html_file, old_name, new_name, args.dry_run):
file_changed = True
if file_changed_in_this_run:
updated_files_count += 1
if file_changed:
updated_html_files_count += 1
# print(f" Posodobljene reference v: {html_file}") # Odkomentiraj za več izpisa
processed_files.add(file_path)
print(f"\nPosodobljenih je bilo {updated_html_files_count} HTML datotek (vključno z DRY RUN).")
print(f"\nPregledanih je bilo {len(all_files_to_update)} datotek.")
print(f"Posodobljenih je bilo {updated_files_count} datotek (vključno z DRY RUN).")
print("\n--- OPTIMIZACIJA SLIK ZAKLJUČENA ---")
if __name__ == "__main__":