changeset 21:aba8ed4c8a06

semiprivate
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 13 Jun 2020 22:30:48 -0600
parents 47162510b27f
children b0e75dfe1853
files src/global/web/Index.java src/global/web/Index.jtp src/global/web/assets/global.css src/nabble/model/DbSiteCreator.java src/nabble/model/Site.java src/nabble/model/SiteImpl.java src/nabble/view/lib/Permissions.java src/nabble/view/naml/permissions.naml src/nabble/view/web/template/NabbleNamespace.java
diffstat 9 files changed, 211 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/src/global/web/Index.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/global/web/Index.java	Sat Jun 13 22:30:48 2020 -0600
@@ -43,9 +43,9 @@
 
 		out.print( "\r\n<!DOCTYPE html>\r\n<html lang=\"en\">\r\n	<head>\r\n		" );
  HtmlGlobalUtils.head(request, response, "Free Forum &bull; Embeddable Web Apps"); 
-		out.print( "\r\n		<link rel=\"canonical\" href=\"https://www.nabble.com/\">\r\n		<script src=\"/assets/jquery/jquery-1.9.1.min.js\"></script>\r\n		<script src=\"/trk5.js\" async=\"true\"></script>\r\n		<meta name=\"description\" content=\"Create a free forum online in less than one minute. All forums are embeddable and fully customizable with scripting language. Choose a unique style and build a discussion board for your community.\" />\r\n		<meta name=\"keywords\" content=\"free forum, free mailing list, mailing list archive, free photo gallery, free newspaper, free blog, best forum, free message board, message board hosting, bulletin board, customizable, private forum, phpBB, vBulletin, hosted, communities\">\r\n		<meta name=\"google-site-verification\" content=\"SUurO4gVJ46SZyzANkH4pJBGH8q-6Bv5P-ZgRBH8Cck\" />\r\n		<style>\r\n		div[actions] i.fa.fa-chevron-right{color:#DDD;float:right}\r\n		a[fixed]{margin-top:-3em;position:absolute;right:1em;text-decoration:none;background-color:#555;border-radius:.5em;padding:.5em;color:#D0D0D0;text-shadow:0px 1px 1px black;border-bottom:1px dotted #757474}\r\n		@media (max-width: 950px) {\r\n			div[footer]{padding-bottom:5em}\r\n		}\r\n		</style>\r\n		<script async=\"true\" src=\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\"></script>\r\n		<script>\r\n			 (adsbygoogle = window.adsbygoogle || []).push({\r\n				  google_ad_client: \"ca-pub-6750305871516672\",\r\n				  enable_page_level_ads: true\r\n			 });\r\n		</script>\r\n		<script>\r\n			$(document).ready(function() {\r\n				var $c1 = $('div[col1]');\r\n				var $c2 = $('div[col2]');\r\n				function centerAlign() {\r\n					var width = $c1.width() + $c2.width();\r\n					var margin = ($c1.parent().width() - width)/2;\r\n					margin = margin > 0? margin : 0;\r\n					$c1.css('margin-left',margin+'px');\r\n				};\r\n				centerAlign();\r\n				$(window).resize(centerAlign);\r\n			});\r\n\r\n			if (document.cookie.indexOf('st=1') >= 0)\r\n				$(window).focus(function(){try{window.close()}catch(err){}top.location='about:blank';});\r\n		</script>\r\n	</head>\r\n	<body lato>\r\n		" );
+		out.print( "\r\n		<link rel=\"canonical\" href=\"https://www.nabble.com/\">\r\n		<!--script src=\"/assets/jquery/jquery-1.9.1.min.js\"></script-->\r\n		<script src=\"/trk5.js\" async=\"true\"></script>\r\n		<meta name=\"description\" content=\"Create a free forum online in less than one minute. All forums are embeddable and fully customizable with scripting language. Choose a unique style and build a discussion board for your community.\" />\r\n		<meta name=\"keywords\" content=\"free forum, free mailing list, mailing list archive, free photo gallery, free newspaper, free blog, best forum, free message board, message board hosting, bulletin board, customizable, private forum, phpBB, vBulletin, hosted, communities\">\r\n		<meta name=\"google-site-verification\" content=\"SUurO4gVJ46SZyzANkH4pJBGH8q-6Bv5P-ZgRBH8Cck\" />\r\n		<style>\r\n			div[actions] i.fa.fa-chevron-right {\r\n				color: #DDD;\r\n				float: right;\r\n			}\r\n			a[fixed] {\r\n				margin-top: -3em;\r\n				position: absolute;\r\n				right: 1em;\r\n				text-decoration: none;\r\n				background-color: #555;\r\n				border-radius: .5em;\r\n				padding: .5em;\r\n				color: #D0D0D0;\r\n				text-shadow: 0px 1px 1px black;\r\n				border-bottom: 1px dotted #757474;\r\n			}\r\n			@media (max-width: 950px) {\r\n				div[footer] {\r\n					padding-bottom: 5em;\r\n				}\r\n			}\r\n			div[note] {\r\n				margin-top: 1em;\r\n				text-align: right;\r\n			}\r\n		</style>\r\n		<script async=\"true\" src=\"https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js\"></script>\r\n		<script>\r\n			 (adsbygoogle = window.adsbygoogle || []).push({\r\n				  google_ad_client: \"ca-pub-6750305871516672\",\r\n				  enable_page_level_ads: true\r\n			 });\r\n		</script>\r\n		<script>\r\n/*\r\n			$(document).ready(function() {\r\n				var $c1 = $('div[col1]');\r\n				var $c2 = $('div[col2]');\r\n				function centerAlign() {\r\n					var width = $c1.width() + $c2.width();\r\n					var margin = ($c1.parent().width() - width)/2;\r\n					margin = margin > 0? margin : 0;\r\n					$c1.css('margin-left',margin+'px');\r\n				};\r\n				centerAlign();\r\n				$(window).resize(centerAlign);\r\n			});\r\n\r\n			if (document.cookie.indexOf('st=1') >= 0)\r\n				$(window).focus(function(){try{window.close()}catch(err){}top.location='about:blank';});\r\n*/\r\n		</script>\r\n	</head>\r\n	<body lato>\r\n		" );
  HtmlGlobalUtils.header(request,response); 
-		out.print( "\r\n		<div full>\r\n			<div content>\r\n				<div col1 center>\r\n					<h1 oswald>Free Forum Hosting &amp; Online Web Apps!</h1>\r\n					<h2 lato gray>Clean Look <span light>&bull;</span> Embeddable <span light>&bull;</span> Customizable</h2>\r\n					<img src=\"/assets/images/home.png\" alt=\"Free forum hosting and online embeddable apps\"/>\r\n				</div>\r\n				<div col2 actions>\r\n					<ul>\r\n						<li><a href=\"" );
+		out.print( "\r\n		<div full>\r\n			<div content center>\r\n			<span style=\"display:inline-block\">\r\n				<div col1 center>\r\n					<h1 oswald>Free Forum Hosting &amp; Online Web Apps!</h1>\r\n					<h2 lato gray>Clean Look <span light>&bull;</span> Embeddable <span light>&bull;</span> Customizable</h2>\r\n					<img src=\"/assets/images/home.png\" alt=\"Free forum hosting and online embeddable apps\"/>\r\n				</div>\r\n				<div col2 actions>\r\n					<ul>\r\n						<li><a href=\"" );
 		out.print( (HtmlGlobalUtils.nabbleContextUrl) );
 		out.print( (ForumStart.path("forum")) );
 		out.print( "\" title=\"Click to create a free forum\">Create Free Forum</a> <i class=\"fa fa-chevron-right\"></i></li>\r\n						<li><a href=\"" );
@@ -60,7 +60,7 @@
 		out.print( "\" title=\"Click to create a free newspaper\">Create News Site</a> <i class=\"fa fa-chevron-right\"></i></li>\r\n						<li><a href=\"" );
 		out.print( (HtmlGlobalUtils.nabbleContextUrl) );
 		out.print( (ForumStart.path("blog")) );
-		out.print( "\" title=\"Click to create a free blog\">Create Blog</a> <i class=\"fa fa-chevron-right\"></i></li>\r\n						<li><a clck href=\"https://www.super-resume.com/\" title=\"Click to build a free resume\">Resume Builder</a> <i class=\"fa fa-chevron-right\"></i></li>\r\n					</ul>\r\n				</div>\r\n			</div>\r\n			<div content paddingTop>\r\n				<div col33 center>\r\n					<h2 oswald>Multi Language</h2>\r\n					<ul floating>\r\n						<li>English</li>\r\n						<li>Čeština (Czech Republic)</li>\r\n						<li>Español</li>\r\n						<li>Français</li>\r\n						<li>Polski</li>\r\n						<li>Português (Brasil)</li>\r\n						<li>Svenska</li>\r\n						<li>Türkçe</li>\r\n						<li>Русский</li>\r\n						<li>Ελληνικά</li>\r\n						<li>中文 (简体)</li>\r\n						<li><a href=\"http://support.nabble.com/Nabble-Translations-f6669344.html\">Translate to other languages</a> &raquo;</li>\r\n					</ul>\r\n				</div>\r\n				<div col33 center>\r\n					<h2 oswald>Embed into any Website</h2>\r\n					<p lineHeight marginHorizontal>All Nabble apps are naturally embeddable, which means that they can be easily displayed inside any web page.\r\n					</p>\r\n				</div>\r\n				<div col33 center>\r\n					<h2 oswald>Fully Customizable</h2>\r\n					<p lineHeight marginHorizontal>All Nabble apps are built with NAML, a scripting language that gives you full control over the app pages.</p>\r\n				</div>\r\n			</div>\r\n			<div content center paddingTop>\r\n				<h2 oswald>Browse Active Nabble Apps</h2>\r\n				" );
+		out.print( "\" title=\"Click to create a free blog\">Create Blog</a> <i class=\"fa fa-chevron-right\"></i></li>\r\n					</ul>\r\n				</div>\r\n				<div note>\r\n					To prevent spam, new forums and other apps will only be visible to registered users.\r\n				</div>\r\n			</span>\r\n			</div>\r\n			<div content paddingTop>\r\n				<div col33 center>\r\n					<h2 oswald>Multi Language</h2>\r\n					<ul floating>\r\n						<li>English</li>\r\n						<li>Čeština (Czech Republic)</li>\r\n						<li>Español</li>\r\n						<li>Français</li>\r\n						<li>Polski</li>\r\n						<li>Português (Brasil)</li>\r\n						<li>Svenska</li>\r\n						<li>Türkçe</li>\r\n						<li>Русский</li>\r\n						<li>Ελληνικά</li>\r\n						<li>中文 (简体)</li>\r\n						<li><a href=\"http://support.nabble.com/Nabble-Translations-f6669344.html\">Translate to other languages</a> &raquo;</li>\r\n					</ul>\r\n				</div>\r\n				<div col33 center>\r\n					<h2 oswald>Embed into any Website</h2>\r\n					<p lineHeight marginHorizontal>All Nabble apps are naturally embeddable, which means that they can be easily displayed inside any web page.\r\n					</p>\r\n				</div>\r\n				<div col33 center>\r\n					<h2 oswald>Fully Customizable</h2>\r\n					<p lineHeight marginHorizontal>All Nabble apps are built with NAML, a scripting language that gives you full control over the app pages.</p>\r\n				</div>\r\n			</div>\r\n			<div content center paddingTop>\r\n				<h2 oswald>Browse Active Nabble Apps</h2>\r\n				" );
  topSites(out); 
 		out.print( "\r\n			</div>\r\n		</div>\r\n		" );
  HtmlGlobalUtils.footer(request,response); 
--- a/src/global/web/Index.jtp	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/global/web/Index.jtp	Sat Jun 13 22:30:48 2020 -0600
@@ -46,17 +46,37 @@
 	<head>
 		<% HtmlGlobalUtils.head(request, response, "Free Forum &bull; Embeddable Web Apps"); %>
 		<link rel="canonical" href="https://www.nabble.com/">
-		<script src="/assets/jquery/jquery-1.9.1.min.js"></script>
+		<!--script src="/assets/jquery/jquery-1.9.1.min.js"></script-->
 		<script src="/trk5.js" async="true"></script>
 		<meta name="description" content="Create a free forum online in less than one minute. All forums are embeddable and fully customizable with scripting language. Choose a unique style and build a discussion board for your community." />
 		<meta name="keywords" content="free forum, free mailing list, mailing list archive, free photo gallery, free newspaper, free blog, best forum, free message board, message board hosting, bulletin board, customizable, private forum, phpBB, vBulletin, hosted, communities">
 		<meta name="google-site-verification" content="SUurO4gVJ46SZyzANkH4pJBGH8q-6Bv5P-ZgRBH8Cck" />
 		<style>
-		div[actions] i.fa.fa-chevron-right{color:#DDD;float:right}
-		a[fixed]{margin-top:-3em;position:absolute;right:1em;text-decoration:none;background-color:#555;border-radius:.5em;padding:.5em;color:#D0D0D0;text-shadow:0px 1px 1px black;border-bottom:1px dotted #757474}
-		@media (max-width: 950px) {
-			div[footer]{padding-bottom:5em}
-		}
+			div[actions] i.fa.fa-chevron-right {
+				color: #DDD;
+				float: right;
+			}
+			a[fixed] {
+				margin-top: -3em;
+				position: absolute;
+				right: 1em;
+				text-decoration: none;
+				background-color: #555;
+				border-radius: .5em;
+				padding: .5em;
+				color: #D0D0D0;
+				text-shadow: 0px 1px 1px black;
+				border-bottom: 1px dotted #757474;
+			}
+			@media (max-width: 950px) {
+				div[footer] {
+					padding-bottom: 5em;
+				}
+			}
+			div[note] {
+				margin-top: 1em;
+				text-align: right;
+			}
 		</style>
 		<script async="true" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
 		<script>
@@ -66,6 +86,7 @@
 			 });
 		</script>
 		<script>
+/*
 			$(document).ready(function() {
 				var $c1 = $('div[col1]');
 				var $c2 = $('div[col2]');
@@ -81,12 +102,14 @@
 
 			if (document.cookie.indexOf('st=1') >= 0)
 				$(window).focus(function(){try{window.close()}catch(err){}top.location='about:blank';});
+*/
 		</script>
 	</head>
 	<body lato>
 		<% HtmlGlobalUtils.header(request,response); %>
 		<div full>
-			<div content>
+			<div content center>
+			<span style="display:inline-block">
 				<div col1 center>
 					<h1 oswald>Free Forum Hosting &amp; Online Web Apps!</h1>
 					<h2 lato gray>Clean Look <span light>&bull;</span> Embeddable <span light>&bull;</span> Customizable</h2>
@@ -99,9 +122,12 @@
 						<li><a href="<%=HtmlGlobalUtils.nabbleContextUrl%><%=ForumStart.path("gallery")%>" title="Click to create a free photo gallery">Create Photo Gallery</a> <i class="fa fa-chevron-right"></i></li>
 						<li><a href="<%=HtmlGlobalUtils.nabbleContextUrl%><%=ForumStart.path("newspaper")%>" title="Click to create a free newspaper">Create News Site</a> <i class="fa fa-chevron-right"></i></li>
 						<li><a href="<%=HtmlGlobalUtils.nabbleContextUrl%><%=ForumStart.path("blog")%>" title="Click to create a free blog">Create Blog</a> <i class="fa fa-chevron-right"></i></li>
-						<li><a clck href="https://www.super-resume.com/" title="Click to build a free resume">Resume Builder</a> <i class="fa fa-chevron-right"></i></li>
 					</ul>
 				</div>
+				<div note>
+					To prevent spam, new forums and other apps will only be visible to registered users.
+				</div>
+			</span>
 			</div>
 			<div content paddingTop>
 				<div col33 center>
--- a/src/global/web/assets/global.css	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/global/web/assets/global.css	Sat Jun 13 22:30:48 2020 -0600
@@ -1,48 +1,155 @@
-body{margin:0 auto;font-family:Lato,Verdana,Arial,sans-serif}
-body>*{padding:1em;max-width:1200px;margin:0 auto}
-[full]{max-width:100%}
-[oswald]{font-family:Oswald,Arial,sans-serif}
-[lato]{font-family:Lato,Arial,sans-serif}
-[gray]{color:#444}
-[light]{color:#999}
-[center]{text-align:center}
-[dark],[dark] a{background:#444;color:#EEE}
-[paddingTop]{padding-top:2em}
-[marginTop]{margin-top:2em}
-[marginBottom]{margin-bottom:2em}
-[lineHeight]{line-height:1.6em}
-[invisible]{display:none}
-h1{margin-bottom:0}
-h2{margin-top:.4em}
-div[header]{padding:4em 0 1em}
-div[content]{max-width:1000px;margin:0 auto;clear:both}
-div[col1]{float:left;width:600px}
-div[col1]>img{max-width:100%}
-div[col2]{float:left}
-div[col2] > ul{font-size:1.5em;padding:.1em 1em;border-radius:1em}
-div[col2] > ul > li{list-style-type:none;margin:0 0 .3em;padding:.4em .5em;font-weight:bold}
-div[col2] > ul > li > a{text-decoration:none;color:#1E67D2;margin-right:1em}
-div[col2] > ul > li:hover{background:#EEF1F3;border-radius:20px}
-div[col33]{width:33%;display:inline-block;vertical-align:top}
-ul[floating] > li{display:inline-block;list-style-type:none;margin:.2em 1em .2em 0;height: 1.2em}
-div[footer] a{display:inline-block;margin:0 1em 1em 0;text-decoration:none;color:#D0D0D0;text-shadow:0px 1px 1px black;border-bottom:1px dotted #757474}
-[marginHorizontal]{margin:0 1em}
-i.fa.fa-chevron-right{font-size:.8em;margin-top:.5em}
+body {
+	margin: 0 auto;
+	font-family: Lato,Verdana,Arial,sans-serif;
+}
+body > * {
+	padding: 1em;
+	max-width: 1200px;
+	margin: 0 auto;
+}
+[full] {
+	max-width: 100%;
+}
+[oswald] {
+	font-family: Oswald,Arial,sans-serif;
+}
+[lato] {
+	font-family: Lato,Arial,sans-serif;
+}
+[gray] {
+	color: #444;
+}
+[light] {
+	color: #999;
+}
+[center] {
+	text-align: center;
+}
+[dark], [dark] a {
+	background: #444;
+	color: #EEE;
+}
+[paddingTop] {
+	padding-top: 2em;
+}
+[marginTop] {
+	margin-top: 2em;
+}
+[marginBottom] {
+	margin-bottom: 2em;
+}
+[lineHeight] {
+	line-height: 1.6em;
+}
+[invisible] {
+	display: none;
+}
+h1 {
+	margin-bottom: 0;
+}
+h2 {
+	margin-top: .4em;
+}
+div[header] {
+	padding: 4em 0 1em;
+}
+div[content] {
+	xmax-width: 1000px;
+	margin: 0 auto;
+	clear: both;
+}
+div[col1] {
+	display: inline-block;
+	width: 600px;
+}
+div[col1] > img {
+	max-width: 100%;
+}
+div[col2] {
+	display: inline-block;
+	text-align: left;
+	vertical-align: top;
+}
+div[col2] > ul {
+	font-size: 1.5em;
+	padding: .1em 1em;
+	border-radius: 1em;
+}
+div[col2] > ul > li {
+	list-style-type: none;
+	margin: 0 0 .3em;
+	padding: .4em .5em;
+	font-weight: bold;
+}
+div[col2] > ul > li > a {
+	text-decoration: none;
+	color: #1E67D2;
+	margin-right: 1em;
+}
+div[col2] > ul > li:hover {
+	background: #EEF1F3;
+	border-radius: 20px;
+}
+div[col33] {
+	width: 33%;
+	display: inline-block;
+	vertical-align: top;
+}
+ul[floating] > li {
+	display: inline-block;
+	list-style-type: none;
+	margin: .2em 1em .2em 0;
+	height: 1.2em;
+}
+div[footer] a {
+	display: inline-block;
+	margin: 0 1em 1em 0;
+	text-decoration: none;
+	color: #D0D0D0;
+	text-shadow: 0px 1px 1px black;
+	border-bottom: 1px dotted #757474;
+}
+[marginHorizontal] {
+	margin: 0 1em;
+}
+i.fa.fa-chevron-right {
+	font-size: .8em;
+	margin-top: .5em;
+}
 @media (max-width: 1000px) {
-	div[col1]{width:500px}
-	div[col2] > ul {font-size: 1.3em}
+	div[col1] {
+		width:500px;
+	}
+	div[col2] > ul {
+		font-size: 1.3em;
+	}
 }
 @media (max-width: 850px) {
-	[col1],[col2],[col33]{width:100% !important}
-	[col33]{padding-bottom:2em}
-	div[col2] > ul {font-size: 1.7em}
-	div[col2] > ul > li{padding:.4em .2em}
+	[col1], [col2], [col33] {
+		width: 100% !important;
+	}
+	[col33] {
+		padding-bottom: 2em;
+	}
+	div[col2] > ul {
+		font-size: 1.7em;
+	}
+	div[col2] > ul > li {
+		padding: .4em .2em;
+	}
 }
 @media (max-width: 600px) {
-	div[col2] > ul {font-size: 1.3em}
+	div[col2] > ul {
+		font-size: 1.3em;
+	}
 }
-input[type='text']{font-size:1.3em;border-radius:10px;border:1px solid #bbb;padding:.2em}
-input[type='submit']{
+input[type='text'] {
+	font-size: 1.3em;
+	border-radius: 10px;
+	border: 1px solid #bbb;
+	padding: .2em;
+}
+input[type='submit'] {
 	-webkit-box-shadow: rgba(0,0,0,0.2) 0 1px 0 0;
 	-moz-box-shadow: rgba(0,0,0,0.2) 0 1px 0 0;
 	box-shadow: rgba(0,0,0,0.2) 0 1px 0 0;
@@ -59,4 +166,4 @@
 	padding: 4px 16px;
 	text-shadow: #E0E0E0 0 1px 0;
 	vertical-align: 15%;
-}
\ No newline at end of file
+}
--- a/src/nabble/model/DbSiteCreator.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/model/DbSiteCreator.java	Sat Jun 13 22:30:48 2020 -0600
@@ -94,6 +94,7 @@
 		rootNode.setType(type);
 		rootNode.insert(false);
 		site.setRoot(rootNode);
+		site.setSemiprivate(true);
 		return site;
 	}
 
--- a/src/nabble/model/Site.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/model/Site.java	Sat Jun 13 22:30:48 2020 -0600
@@ -62,6 +62,9 @@
 	public List<Node> findTagNodes(String sqlCondition);
 	public List<Long> findTagNodeIds(String sqlCondition);
 
+	public boolean isSemiprivate();
+	public void setSemiprivate(boolean isSemiprivate);
+
 	public boolean isModuleEnabled(String moduleName);
 	public void setModuleEnabled(String moduleName,boolean isEnabled);
 	public Map<String,String> getCustomTweaks();
--- a/src/nabble/model/SiteImpl.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/model/SiteImpl.java	Sat Jun 13 22:30:48 2020 -0600
@@ -558,6 +558,19 @@
 	}
 
 
+	public boolean isSemiprivate() {
+		return hasTags(null,null,"label='semiprivate'");
+	}
+
+	public void setSemiprivate(boolean isSemiprivate) {
+		if( isSemiprivate ) {
+			addTag(null,null,"semiprivate");
+		} else {
+			deleteTags(null,null,"label='semiprivate'");
+		}
+	}
+
+
 	private FutureValue<Map<String,Boolean>> modulesEnabled = new FutureValue<Map<String,Boolean>>() {
 		protected Map<String,Boolean> compute() {
 			Map<String,Boolean> map = new HashMap<String,Boolean>();
--- a/src/nabble/view/lib/Permissions.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/view/lib/Permissions.java	Sat Jun 13 22:30:48 2020 -0600
@@ -336,8 +336,6 @@
 	}
 
 	public static Node getPrivateNode(Node node) {
-//System.out.println("qqqqqq getPrivateNode");
-//if(true) return node;
 		node = getPermissionNode(node,VIEW_PERMISSION);
 		return node==null || hasPermission(node.getSite(),node,ANYONE_GROUP,VIEW_PERMISSION) ? null : node;
 	}
--- a/src/nabble/view/naml/permissions.naml	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/view/naml/permissions.naml	Sat Jun 13 22:30:48 2020 -0600
@@ -333,10 +333,12 @@
 		<n.if.equal value1="[n.get_parameter name='macro'/]" value2="unauthorized">
 			<then.exit/>
 		</n.if.equal>
-		<n.if.not.is_private>
-			<then.exit/>
-		</n.if.not.is_private>
-		<n.get_private_node.id />
+		<n.if.is_private>
+			<then.get_private_node.id />
+			<else.if.is_semiprivate>
+				<then.id />
+			</else.if.is_semiprivate>
+		</n.if.is_private>
 	</n.get_node_from_parameter.>
 </macro>
 
--- a/src/nabble/view/web/template/NabbleNamespace.java	Fri Jun 05 13:16:45 2020 -0600
+++ b/src/nabble/view/web/template/NabbleNamespace.java	Sat Jun 13 22:30:48 2020 -0600
@@ -113,6 +113,10 @@
 		out.print( site.getId() );
 	}
 
+	@Command public void is_semiprivate(IPrintWriter out,Interpreter interp) {
+		out.print( site.isSemiprivate() );
+	}
+
 	@Command public void base_url(IPrintWriter out,Interpreter interp) {
 		out.print( interp.encode( site.getBaseUrl() ) );
 	}