diff --git a/config.json b/config.json
index 5b82865a673b3a9e44e11281206f5a60f6720a96..167e18ee2948c631c007403a69b647ce04870509 100644
--- a/config.json
+++ b/config.json
@@ -1,8 +1,5 @@
 {
 	"relative_urls": true,
-	"static_directories": [
-		"images"
-	],
 	"homepage_slug": "index",
 	"theme": {
 		"default_tag_color": "hsl(289, 43%, 56%)",
diff --git a/fgs/__main__.py b/fgs/__main__.py
index 54bca9a1cd983cfc77afde2cf89964afc260af99..395c1ad4d3176dc2d605d8b65dadae158e7a592e 100644
--- a/fgs/__main__.py
+++ b/fgs/__main__.py
@@ -35,27 +35,19 @@ def main():
     factories['tag'] = datatypes.TagFactory(config, factories)
     factories['link'] = datatypes.LinkFactory(config, factories)
     factories['config'] = datatypes.LocalizedConfigFactory(config, factories)
+    factories['file'] = datatypes.FileFactory(config, factories)
 
-    mdreader = reader.MarkdownReader(config, factories)
-    pages = []
-    directory = os.path.join(CONTENT_DIR, ".")
-    parse_dir(directory, pages, mdreader)
+    readers = {}
+    readers['generic'] = reader.FileReader(config, factories)
+    readers['md'] = reader.MarkdownReader(config, factories)
 
-    static_dirs = []
-    for sdir in config['static_directories']:
-        if "." in sdir:
-            raise Exception("Illegal static directory name: ", sdir)
-        static_dirs.append(CONTENT_DIR + "/"+ sdir)
-    static_files = {}
-    for sdir in static_dirs:
-        read_static_dir(sdir, static_files)
-
-    read_static_dir(THEME_DIR + '/static', static_files, [config['theme']['static_dir']])
+    parse_dir(os.path.join(CONTENT_DIR, "."), readers)
+    parse_dir(THEME_DIR + '/static', readers, [config['theme']['static_dir']])
 
 
     context = {}
     gen = generator.Generator(config, context, factories)
-    gen.generate_context(pages, static_files)
+    gen.generate_context()
 
     wrt = writer.Writer(config, context, OUTPUT_DIR, THEME_DIR)
 
@@ -63,33 +55,18 @@ def main():
 
 
 
-
-
-
-def read_static_dir(directory, static_files, subpath = []):
-    print("static_dir: " + directory);
-    for filename in os.listdir(directory):
-        fp = os.path.join(directory, filename)
-        if os.path.isfile(fp) and not filename.startswith("."):
-            lpath = '/'.join(subpath + [filename])
-            with open(fp, "rb") as f:
-                static_files[lpath] = f.read()
-            print("read: ", fp, " as: ", lpath)
-        elif os.path.isdir(fp) and not filename.startswith("."):
-            read_static_dir(fp, static_files, subpath + [filename])
-
-
-def parse_dir(directory, pages, mdreader, subpath = []):
+def parse_dir(directory, readers, subpath = []):
     print("parse_dir: " + directory);
     for filename in os.listdir(directory):
+        if filename.startswith("."):
+            continue
         f = os.path.join(directory, filename)
-        if os.path.isfile(f) and filename.endswith(".md"):
-            pages.append(mdreader.read_and_parse_file(f, subpath))
-        elif os.path.isdir(f) and not filename.startswith("."):
-            parse_dir(f, pages, mdreader, subpath + [filename])
-
-
-
+        if os.path.isfile(f):
+            readers['generic'].read_file(f, subpath)
+            if filename.endswith(".md"):
+                readers['md'].read_and_parse_file(f, subpath)
+        elif os.path.isdir(f):
+            parse_dir(f, readers, subpath + [filename])
 
 
 
diff --git a/fgs/datatypes.py b/fgs/datatypes.py
index 222ac7526e9926f2ecea0f8a8ae557ca2342d80a..a527c6850f5cf9c1e428677273cf7a054cb1b30c 100644
--- a/fgs/datatypes.py
+++ b/fgs/datatypes.py
@@ -23,6 +23,8 @@ class DictConverter:
             return self.factories['link'].get_by_raw(item, lang)
         elif isinstance(item, str) and key == "tag":
             return self.factories['tag'].get(item, lang)
+        elif isinstance(item, str) and key == "file":
+            return self.factories['file'].get(item)
         #elif isinstance(item, str) and key == "slug":
         #    return self.factories['page'].get(item, lang)
         else:
@@ -41,6 +43,32 @@ class LocalizedConfigFactory(DictConverter):
             self.store[lang] = self.convert(self.config, lang, None)
         return self.store[lang]
 
+class FileFactory:
+    def __init__(self, config, factories):
+        self.config = config
+        self.factories = factories
+        self.store = {}
+    def get(self, filename):
+        if filename not in self.store:
+            self.store[filename] = File(filename, self.config, self.factories)
+        return self.store[filename];
+    def all(self):
+        return self.store
+class File:
+    def __init__(self, filename, config, factories):
+        self.name = filename
+        self._config = config
+        self._factories = factories
+        self.initialized = False
+
+    def init(self, rawcontents, subpathlist):
+        if self.initialized:
+            raise Exception("Tried initializing file twice. Perhaps two files with same name exist? ", self.name)
+        self.initialized = True
+        self.rawcontents = rawcontents
+        self.subpathlist = subpathlist
+        self.link = self._factories['link'].get_by_type("file", self.name)
+
 class PageFactory:
     def __init__(self, config, factories):
         self.config = config
@@ -56,6 +84,9 @@ class PageFactory:
         if not self.has(slug, lang):
             self.store[lang][slug] = Page(slug, lang, self.factories)
         return self.store[lang][slug];
+
+    def all(self):
+        return self.store
 class Page:
     def __init__(self, slug, lang, factories):
         self.slug = slug
@@ -331,8 +362,12 @@ class LinkFactory:
         if rawurl not in self.store[lang]:
             self.store[lang][rawurl] = link
         return self.store[lang][rawurl];
-    def get_by_type(self, reftype, refid, reflang):
-        rawurl = reftype + ':' + refid + ':' + reflang
+    def get_by_type(self, reftype, refid, reflang = None):
+        rawurl = reftype + ':' + refid
+        if reflang:
+            rawurl += ':' + reflang
+        else:
+            reflang = self.config['lang']['default']
         return self.get_by_raw(rawurl=rawurl, deflang=reflang)
 class Link:
     def __init__(self, rawurl, factories, deflang):
@@ -380,6 +415,13 @@ class Link:
                     self.type = reftype
                     self.lang = reflang
                     self.refid = refid
+                elif reftype == "file":
+                    # rawurl: 'file:logo.png'
+                    self._file = None
+                    self._url = None
+                    self.type = reftype
+                    self.lang = reflang
+                    self.refid = refid
                 else:
                     # rawurl: 'https://example.com'
                     self._url = urlwoa
@@ -402,6 +444,12 @@ class Link:
         return self._tag
     tag = property(get_tag, None, None)
 
+    def get_file(self):
+        if not self._file:
+            self._file = self._factories['file'].get(self.refid)
+        return self._file
+    file = property(get_file, None, None)
+
     def get_category(self):
         if self.type == "slug":
             return self.page.category
@@ -419,6 +467,8 @@ class Link:
             return '/'.join([self.page.lang, self.page.category.name, self.page.slug + '.html'])
         elif self.type == "tag":
             return '/'.join([self.tag.lang, 'tag', self.tag.name + '.html'])
+        elif self.type == "file":
+            return '/'.join(['file', self.file.name])
         else:
             raise Exception("path is not allowed to be called here", self.type)
     path = property(get_path, None, None)
diff --git a/fgs/generator.py b/fgs/generator.py
index 3a9738029bc882d60fb26ece9ef1928671dcf045..37b5f10827d0070b907407b214391c02c3c67e60 100644
--- a/fgs/generator.py
+++ b/fgs/generator.py
@@ -6,14 +6,16 @@ class Generator:
         self.context = context
         self.factories = factories
 
-    def generate_context(self, pages, static_files):
-        # static_files
-        self.context['static_files'] = static_files
+    def generate_context(self):
+        # files
+        self.context['files'] = self.factories['file'].all()
 
+        pages = self.factories['page'].all()
         published_pages = []
-        for page in pages:
-            if page.status == "published":
-                published_pages.append(page)
+        for lang in self.config['lang']['supported']:
+            for slug, page in pages[lang].items():
+                if page.status == "published":
+                    published_pages.append(page)
 
 
         # pages
@@ -81,9 +83,9 @@ class Generator:
 
 
     def generate_output(self, writer):
-        for sf, raw in self.context['static_files'].items():
-                print ("writing binary file: ", sf)
-                writer.write_file(sf, raw, mode="wb")
+        for fname, f in self.context['files'].items():
+                #print ("writing binary file: ", fname)
+                writer.write_file(f.link.path, f.rawcontents, mode="wb")
 
         for lang in self.config['lang']['supported']:
             # all pages
diff --git a/fgs/reader.py b/fgs/reader.py
index 1168bfc161801bacb286395efe196711fd768dcc..0dc76b6d16c80b65589ef2d1f78ac986347a16f6 100644
--- a/fgs/reader.py
+++ b/fgs/reader.py
@@ -8,6 +8,23 @@ from datetime import datetime
 import subprocess
 import os
 
+
+class FileReader:
+
+    def __init__(self, config, factories):
+        self.config = config
+        self.factories = factories
+
+    def read_file(self, path, subpath):
+        f = open(path, 'rb')
+        rawcontents = f.read()
+        f.close()
+        pathlist = path.split('/')
+        subpathlist = pathlist[:-1]
+        filename = pathlist[-1]
+
+        self.factories['file'].get(filename).init(rawcontents, subpathlist)
+
 class MarkdownReader:
 
     def __init__(self, config, factories):
diff --git a/theme/templates/base.html b/theme/templates/base.html
index 99f993c0fe2035a5fc709a905309629a1040fdfb..9f45890de2520ee02791c7fa14c71032e54b66db 100644
--- a/theme/templates/base.html
+++ b/theme/templates/base.html
@@ -15,8 +15,8 @@
 	<title>{% block title %}{{ t[l].title_prefix }}{{ t[l].sitename }}{{ t[l].title_suffix }}{%endblock%}</title>
 	<!-- <base target="_blank"> -->
 	<!-- <meta HTTP-EQUIV="REFRESH" content="500; url=#"> -->
-	<link rel="preload" href="{{ siteurl }}/{{ theme.static_dir }}/css/{{ theme.css_file }}" as="style" />
-	<link rel="stylesheet" type="text/css" href="{{ siteurl }}/{{ theme.static_dir }}/css/{{ theme.css_file }}" />
+	<link rel="preload" href="{{ siteurl }}/{{ files[theme.css_file].link.url }}" as="style" />
+	<link rel="stylesheet" type="text/css" href="{{ siteurl }}/{{ files[theme.css_file].link.url }}" />
 	<script src="{{ siteurl }}/mathjax/tex-chtml.js" id="MathJax-script" async></script>
 	{#- TODO load javascript? -#}
 	{#- TODO og: meta tags -#}
@@ -32,7 +32,7 @@
 	</nav>-->
 	<header>
 		{% block site_header %}
-		<a href="{{ siteurl }}/{{ l }}/" title="{{ t[l].banner.title|e }}" ><img alt="{{ t[l].banner.alt|e }}" src="{{ siteurl }}/{{ theme.static_dir }}/images/banner-logo.png"><span>{{ t[l].banner.prefix|e }}{{ t[l].sitename|e }}{{ t[l].banner.suffix|e }}</span></a>
+		<a href="{{ siteurl }}/{{ l }}/" title="{{ t[l].banner.title|e }}" ><img alt="{{ t[l].banner.alt|e }}" src="{{ siteurl }}/{{ files['banner-logo.png'].link.url }}"><span>{{ t[l].banner.prefix|e }}{{ t[l].sitename|e }}{{ t[l].banner.suffix|e }}</span></a>
 		{% block extra_header %}{% endblock extra_header %}
 		{% endblock site_header %}
 	</header>
diff --git a/theme/templates/macros/content_renderer.html b/theme/templates/macros/content_renderer.html
index b123c2ee79c4d4a5cd702d1297c8e01a3e030bad..4b0a747de846e59025c0ea22388540788d95be2a 100644
--- a/theme/templates/macros/content_renderer.html
+++ b/theme/templates/macros/content_renderer.html
@@ -55,11 +55,17 @@
 
 {%- macro render_image(link, alt, lang, attr = None, title = None) -%}
 	{%- call(resolvedlink, objtype, obj) linkr.resolve(link) -%}
-		<img {{ render_attr(attr, lang, extra={"src": resolvedlink.urlwithanchor, "title": {"value":title, "escape": true}}) }} alt="
+		{%- set ns = namespace(url=resolvedlink.urlwithanchor) -%}
+		{%- if not resolvedlink.is_external -%}
+			{%- if resolvedlink.url|length -%}
+				{%- set ns.url = [siteurl, ns.url]|join("/") -%}
+			{%- endif -%}
+		{%- endif -%}
+		<img {{ render_attr(attr, lang, extra={"src": ns.url, "title": {"value":title, "escape": true}}) }} alt="
 			{%- if alt is string -%}
 				{{ alt|e }}
 			{%- else -%}
-				{{ render_inlines(alt, lang) }}
+				{{ render_inlines(alt, lang)|striptags|e }}
 			{%- endif -%}
 		">
 	{%- endcall -%}
diff --git a/theme/templates/macros/link.html b/theme/templates/macros/link.html
index ac6d21f723436d16241d20b49d5667e0dfa4fb5a..19a4cb4e6ef63d26bcd52fead6363639f72567ea 100644
--- a/theme/templates/macros/link.html
+++ b/theme/templates/macros/link.html
@@ -9,6 +9,8 @@
 		{%- set ns.obj = link.tag -%}
 	{%- elif ns.objtype == "slug" -%}
 		{%- set ns.obj = link.page -%}
+	{%- elif ns.objtype == "file" -%}
+		{%- set ns.obj = link.file -%}
 	{%- endif -%}
 
 	{%- if link.alias -%}