diff --git a/core/models/caves.py b/core/models/caves.py
index 20a7a96..d6650c0 100644
--- a/core/models/caves.py
+++ b/core/models/caves.py
@@ -113,7 +113,7 @@ class Cave(TroggleModel):
     def hassurveydata(self):
         if not self.underground_centre_line:
             return "No"
-        if self.survex_file:
+        if self.survex_filcavee:
             return "Yes"
         return "Missing"
          
@@ -167,7 +167,7 @@ class Cave(TroggleModel):
                 # undated.append(q)
         # sortedqms = sorted(dated, key=operator.attrgetter('block.date')) # sort by date of survexblock the QM was defined in
         # orderedqms = sorted(undated, key=operator.attrgetter('expoyear')) # sort by date of expoyear
-        # return orderedqms + sortedqms # a list, NOT a QuerySet
+        # return orderedqmcaves + sortedqms # a list, NOT a QuerySet
         
 
     # def new_QM_number(self, year=datetime.date.today().year):
@@ -338,7 +338,7 @@ class Entrance(TroggleModel):
     def has_photo(self):
         if self.photo:
             if (self.photo.find("<img") > -1 or self.photo.find("<a") > -1 or self.photo.find("<IMG") > -1 or self.photo.find("<A") > -1):
-                return "Yes"
+                return "Yecaves"
             else:
                 return "Missing"
         else:
@@ -365,7 +365,7 @@ class Entrance(TroggleModel):
         # if ancestor_titles:
             # res = '/'.join((self.get_root().cave.get_absolute_url(), ancestor_titles, self.title))
         # else:
-            # res = '/'.join((self.get_root().cave.get_absolute_url(), self.title))
+            # res = '/'.jocavein((self.get_root().cave.get_absolute_url(), self.title))
         # return res
         res = '/'.join((self.get_root().cave.get_absolute_url(), self.title))
         return res
@@ -403,7 +403,17 @@ class Entrance(TroggleModel):
         u = t.render(c)
         writetrogglefile(filepath, u)
         return
-
+        
+    def url_parent(self):
+        if self.url:
+            return self.url.rsplit("/", 1)[0]
+        else:
+            cavelist = self.cavelist()
+            if len(self.cavelist()) == 1:
+                return cavelist[0].url_parent()
+            else:
+                return ""
+                
 
 class LogbookEntry(TroggleModel):
     """Single parsed entry from Logbook
diff --git a/core/views/caves.py b/core/views/caves.py
index b56eacb..c98d28e 100644
--- a/core/views/caves.py
+++ b/core/views/caves.py
@@ -276,8 +276,11 @@ def cavepage(request, karea, subpath):
         r = rendercave(request, cave, cave.slug())
         return r
     except NoReverseMatch:
-        message = f'Failed to render cave: {kpath} (it does exist and is unique) because of a Django URL resolution error. Check urls.py.'
-        return render(request,'errors/generic.html', {'message': message})
+        if settings.DEBUG:
+            raise
+        else:
+            message = f'Failed to render cave: {kpath} (it does exist and is unique) because of a Django URL resolution error. Check urls.py.'
+            return render(request,'errors/generic.html', {'message': message})
     except:
         # anything else is a new problem. Add in specific error messages here as we discover new types of error 
         raise
@@ -365,7 +368,7 @@ def edit_cave(request, path = "", slug=None):
                                 })
 
 @login_required_if_public
-def edit_entrance(request, caveslug=None, slug=None):
+def edit_entrance(request, path = "", caveslug=None, slug=None):
     '''This is the form that edits the entrance data for a single entrance and writes out 
     an XML file in the :expoweb: repo folder
     The format for the file being saved is in templates/dataformat/entrance.xml
diff --git a/templates/cave.html b/templates/cave.html
index 416a450..7cbeef2 100644
--- a/templates/cave.html
+++ b/templates/cave.html
@@ -541,7 +541,7 @@ div#scene {
         {{ ent.entrance_letter|safe }}
         {% if ent.entrance.name %}
             {{ ent.entrance.name|safe }}
-        {% endif %}<a href="{% url "editentrance" cave.slug ent.entrance.slug %}">Edit</a>
+        {% endif %}<a href="{% url "editentrance" ent.entrance.url_parent cave.slug ent.entrance.slug %}">Edit</a>
         <dl>
         {% if ent.entrance.marking %}
             <dt>Marking</dt><dd>{{ ent.entrance.marking_val|safe }}</dd>
@@ -601,6 +601,6 @@ div#scene {
     </ul>
 
 {% endif %}</p>
-<a href="{% url "newentrance" cave.slug %}">New Entrance</a>
+<a href="{% url "newentrance" cave.url_parent cave.slug %}">New Entrance</a>
 </div>
 {% endblock content %}
diff --git a/urls.py b/urls.py
index 1c17b21..d89912f 100644
--- a/urls.py
+++ b/urls.py
@@ -130,15 +130,19 @@ trogglepatterns = [
     #re_path(r'^cave/description/([^/]+)/?$', caves.caveDescription), #!!!BAD, local links fail..
     #re_path(r'^cave/(?P<cave_id>[^/]+)/?$', caves.cave, name="cave"), # used only in testing !? XXXXXXXXXXXXXXXXXXXXXXXXXX
     #re_path(r'^cave/(?P<cave_id>[^/]+)/?(?P<ent_letter>[^/])$', ent), #!!!BAD, local links fail..# view_caves.ent
+    
+#   Edit caves and entrances
     re_path(r'^(?P<path>.*)/(?P<slug>[^/]+)_cave_edit/$',           edit_cave, name="edit_cave"), # edit_cave needed by cave.html template for url matching
+    re_path(r'^(?P<path>.*)/(?P<caveslug>[^/]+):(?P<slug>[^:]+)_entrance_edit', edit_entrance, name = "editentrance"), #edit existing entrance
+    re_path(r'^(?P<path>.*)/(?P<caveslug>[^/]+)_entrance_new$', edit_entrance, name = "newentrance"), # new entrance for a cave
+    
     re_path(r'^(.*)_edit$',         editexpopage, name="editexpopage"),
     re_path(r'^(?P<karea>\d\d\d\d)(?P<subpath>.*)$',   cavepage,  name="cavepage"), # shorthand /1623/264 or 1623/161/top.htm
     # Note that urls eg '/1623/161/l/rl89a.htm' are handled by cavepage which redirects them to 'expopage'    # Note that _edit$ for a cave description page in a subfolder e.g. /1623/204/204.html_edit  gets caught here and breaks with 404
 
 #   Entrances
     re_path(r'^cave/entrance/([^/]+)/?$',    caveEntrance), # lists all entrances !!!BAD, local links fail
-    re_path(r'^entrance/(?P<caveslug>[^/]+)/(?P<slug>[^/]+)/edit/', edit_entrance, name = "editentrance"), #edit existing entrance
-    re_path(r'^entrance/new/(?P<caveslug>[^/]+)$', edit_entrance, name = "newentrance"), # new entrance for a cave
+
    
 # System admin and monitoring
     path('statistics',  statistics.stats, name="stats"),