diff --git a/layerindex/forms.py b/layerindex/forms.py index a9e7703..2cb9b52 100644 --- a/layerindex/forms.py +++ b/layerindex/forms.py @@ -118,8 +118,8 @@ class EditLayerForm(StyledModelForm): def clean_name(self): name = self.cleaned_data['name'].strip() - if re.compile(r'[^a-z0-9-]').search(name): - raise forms.ValidationError("Name must only contain alphanumeric characters and dashes") + if re.compile(r'[^a-z0-9-\.]').search(name): + raise forms.ValidationError("Name must only contain alphanumeric characters, dashes or periods") if name.startswith('-'): raise forms.ValidationError("Name must not start with a dash") if name.endswith('-'): diff --git a/layerindex/urls.py b/layerindex/urls.py index 1fcd11d..80ceaa7 100644 --- a/layerindex/urls.py +++ b/layerindex/urls.py @@ -46,7 +46,7 @@ urlpatterns = [ re_path(r'^layers/$', RedirectView.as_view(url=reverse_lazy('layer_list', args=('master',)), permanent=False)), - re_path(r'^layer/(?P[-\w]+)/$', + re_path(r'^layer/(?P[-\.\w]+)/$', RedirectParamsView.as_view(permanent=False), {'redirect_name': 'layer_item', 'branch': 'master'}), re_path(r'^recipes/$', RedirectView.as_view(url=reverse_lazy('recipe_search', args=('master',)), permanent=False)), @@ -65,23 +65,23 @@ urlpatterns = [ LayerReviewListView.as_view( template_name='layerindex/reviewlist.html'), name='layer_list_review'), - re_path(r'^review/(?P[-\w]+)/$', + re_path(r'^review/(?P[-\.\w]+)/$', LayerReviewDetailView.as_view( template_name='layerindex/reviewdetail.html'), name='layer_review'), - re_path(r'^layer/(?P[-\w]+)/addnote/$', + re_path(r'^layer/(?P[-\.\w]+)/addnote/$', edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="add_layernote"), - re_path(r'^layer/(?P[-\w]+)/editnote/(?P[-\w]+)/$', + re_path(r'^layer/(?P[-\.\w]+)/editnote/(?P[-\w]+)/$', edit_layernote_view, {'template_name': 'layerindex/editlayernote.html'}, name="edit_layernote"), - re_path(r'^layer/(?P[-\w]+)/deletenote/(?P[-\w]+)/$', + re_path(r'^layer/(?P[-\.\w]+)/deletenote/(?P[-\w]+)/$', delete_layernote_view, {'template_name': 'layerindex/deleteconfirm.html'}, name="delete_layernote"), - re_path(r'^layer/(?P[-\w]+)/delete/$', + re_path(r'^layer/(?P[-\.\w]+)/delete/$', delete_layer_view, {'template_name': 'layerindex/deleteconfirm.html'}, name="delete_layer"), re_path(r'^recipe/(?P[-\w]+)/$', RecipeDetailView.as_view( template_name='layerindex/recipedetail.html'), name='recipe'), - re_path(r'^layer/(?P[-\w]+)/publish/$', publish_view, name="publish"), + re_path(r'^layer/(?P[-\.\w]+)/publish/$', publish_view, name="publish"), re_path(r'^layerupdate/(?P[-\w]+)/$', LayerUpdateDetailView.as_view( template_name='layerindex/layerupdate.html'), diff --git a/layerindex/urls_branch.py b/layerindex/urls_branch.py index 40cd915..a9a4018 100644 --- a/layerindex/urls_branch.py +++ b/layerindex/urls_branch.py @@ -17,11 +17,11 @@ urlpatterns = [ LayerListView.as_view( template_name='layerindex/layers.html'), name='layer_list'), - re_path(r'^layer/(?P[-\w]+)/$', + re_path(r'^layer/(?P[-\.\w]+)/$', LayerDetailView.as_view( template_name='layerindex/detail.html'), name='layer_item'), - re_path(r'^layer/(?P[-\w]+)/recipes/csv/$', + re_path(r'^layer/(?P[-\.\w]+)/recipes/csv/$', layer_export_recipes_csv_view, name='layer_export_recipes_csv'), re_path(r'^recipes/$', @@ -40,8 +40,8 @@ urlpatterns = [ ClassSearchView.as_view( template_name='layerindex/classes.html'), name='class_search'), - re_path(r'^edit/(?P[-\w]+)/$', edit_layer_view, {'template_name': 'layerindex/editlayer.html'}, name="edit_layer"), - re_path(r'^update/(?P[-\w]+)/$', update_layer_view, {'template_name': 'layerindex/updatelayer.html'}, name="update_layer"), + re_path(r'^edit/(?P[-\.\w]+)/$', edit_layer_view, {'template_name': 'layerindex/editlayer.html'}, name="edit_layer"), + re_path(r'^update/(?P[-\.\w]+)/$', update_layer_view, {'template_name': 'layerindex/updatelayer.html'}, name="update_layer"), re_path(r'^duplicates/$', DuplicatesView.as_view( template_name='layerindex/duplicates.html'),