mirror of
https://github.com/MarginaliaSearch/MarginaliaSearch.git
synced 2025-02-23 13:09:00 +00:00
(search) Completely remove all old hdb templates
Create new views for conversion results, dictionary results, and site crosstalk.
This commit is contained in:
parent
9287ee0141
commit
f3382b5bd8
@ -7,4 +7,8 @@ public record DictionaryResponse(String word, List<DictionaryEntry> entries) {
|
||||
this.word = word;
|
||||
this.entries = entries.stream().toList(); // Make an immutable copy
|
||||
}
|
||||
|
||||
public boolean hasEntries() {
|
||||
return !entries.isEmpty();
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,6 @@ dependencies {
|
||||
|
||||
|
||||
implementation project(':code:index:api')
|
||||
implementation project(':code:common:renderer')
|
||||
|
||||
implementation project(':code:features-search:screenshots')
|
||||
implementation project(':code:features-search:random-websites')
|
||||
|
@ -1,12 +0,0 @@
|
||||
package nu.marginalia.search;
|
||||
|
||||
import com.github.jknack.handlebars.Handlebars;
|
||||
import nu.marginalia.renderer.config.HandlebarsConfigurator;
|
||||
|
||||
public class SearchHandlebarsConfigurator implements HandlebarsConfigurator {
|
||||
|
||||
@Override
|
||||
public void configure(Handlebars handlebars) {
|
||||
|
||||
}
|
||||
}
|
@ -4,13 +4,10 @@ import com.google.inject.AbstractModule;
|
||||
import nu.marginalia.LanguageModels;
|
||||
import nu.marginalia.WebsiteUrl;
|
||||
import nu.marginalia.WmsaHome;
|
||||
import nu.marginalia.renderer.config.HandlebarsConfigurator;
|
||||
|
||||
public class SearchModule extends AbstractModule {
|
||||
|
||||
public void configure() {
|
||||
bind(HandlebarsConfigurator.class).to(SearchHandlebarsConfigurator.class);
|
||||
|
||||
bind(LanguageModels.class).toInstance(WmsaHome.getLanguageModels());
|
||||
|
||||
bind(WebsiteUrl.class).toInstance(new WebsiteUrl(
|
||||
|
@ -14,7 +14,7 @@ public class CommandEvaluator {
|
||||
|
||||
@Inject
|
||||
public CommandEvaluator(
|
||||
BrowseCommand browse,
|
||||
BrowseRedirectCommand browse,
|
||||
ConvertCommand convert,
|
||||
DefinitionCommand define,
|
||||
BangCommand bang,
|
||||
|
@ -9,11 +9,11 @@ import java.util.Optional;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BrowseCommand implements SearchCommandInterface {
|
||||
public class BrowseRedirectCommand implements SearchCommandInterface {
|
||||
private final Predicate<String> queryPatternPredicate = Pattern.compile("^browse:[.A-Za-z\\-0-9:]+$").asPredicate();
|
||||
|
||||
@Inject
|
||||
public BrowseCommand()
|
||||
public BrowseRedirectCommand()
|
||||
{
|
||||
|
||||
}
|
@ -1,35 +1,35 @@
|
||||
package nu.marginalia.search.command.commands;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import nu.marginalia.renderer.MustacheRenderer;
|
||||
import nu.marginalia.renderer.RendererFactory;
|
||||
import nu.marginalia.search.JteRenderer;
|
||||
import nu.marginalia.search.command.SearchCommandInterface;
|
||||
import nu.marginalia.search.command.SearchParameters;
|
||||
import nu.marginalia.search.model.NavbarModel;
|
||||
import nu.marginalia.search.svc.SearchUnitConversionService;
|
||||
import spark.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ConvertCommand implements SearchCommandInterface {
|
||||
private final SearchUnitConversionService searchUnitConversionService;
|
||||
private final MustacheRenderer<Map<String, String>> conversionRenderer;
|
||||
private final JteRenderer renderer;
|
||||
|
||||
@Inject
|
||||
public ConvertCommand(SearchUnitConversionService searchUnitConversionService, RendererFactory rendererFactory) throws IOException {
|
||||
public ConvertCommand(SearchUnitConversionService searchUnitConversionService,
|
||||
JteRenderer renderer) {
|
||||
this.searchUnitConversionService = searchUnitConversionService;
|
||||
|
||||
conversionRenderer = rendererFactory.renderer("search/conversion-results");
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> process(Response response, SearchParameters parameters) {
|
||||
var conversion = searchUnitConversionService.tryConversion(parameters.query());
|
||||
return conversion.map(s -> conversionRenderer.render(Map.of(
|
||||
"query", parameters.query(),
|
||||
"result", s,
|
||||
"profile", parameters.profileStr())
|
||||
return conversion.map(s -> renderer.render("serp/unit-conversion.jte", Map.of(
|
||||
"parameters", parameters,
|
||||
"navbar", NavbarModel.SEARCH,
|
||||
"result", s)
|
||||
));
|
||||
|
||||
}
|
||||
|
@ -4,15 +4,14 @@ package nu.marginalia.search.command.commands;
|
||||
import com.google.inject.Inject;
|
||||
import nu.marginalia.api.math.MathClient;
|
||||
import nu.marginalia.api.math.model.DictionaryResponse;
|
||||
import nu.marginalia.renderer.MustacheRenderer;
|
||||
import nu.marginalia.search.JteRenderer;
|
||||
import nu.marginalia.search.command.SearchCommandInterface;
|
||||
import nu.marginalia.search.command.SearchParameters;
|
||||
import nu.marginalia.renderer.RendererFactory;
|
||||
import nu.marginalia.search.model.NavbarModel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import spark.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -22,19 +21,17 @@ import java.util.regex.Pattern;
|
||||
public class DefinitionCommand implements SearchCommandInterface {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final MustacheRenderer<DictionaryResponse> dictionaryRenderer;
|
||||
private final MathClient mathClient;
|
||||
private final JteRenderer renderer;
|
||||
|
||||
|
||||
private final Predicate<String> queryPatternPredicate = Pattern.compile("^define:[A-Za-z\\s-0-9]+$").asPredicate();
|
||||
|
||||
@Inject
|
||||
public DefinitionCommand(RendererFactory rendererFactory, MathClient mathClient)
|
||||
throws IOException
|
||||
{
|
||||
public DefinitionCommand(MathClient mathClient, JteRenderer renderer) {
|
||||
|
||||
dictionaryRenderer = rendererFactory.renderer("search/dictionary-results");
|
||||
this.mathClient = mathClient;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,11 +40,12 @@ public class DefinitionCommand implements SearchCommandInterface {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
var results = lookupDefinition(parameters.query());
|
||||
DictionaryResponse result = lookupDefinition(parameters.query());
|
||||
|
||||
return Optional.of(dictionaryRenderer.render(results,
|
||||
Map.of("query", parameters.query(),
|
||||
"profile", parameters.profileStr())
|
||||
return Optional.of(renderer.render("serp/dict-lookup.jte",
|
||||
Map.of("parameters", parameters,
|
||||
"result", result,
|
||||
"navbar", NavbarModel.SEARCH)
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package nu.marginalia.search.svc;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import nu.marginalia.renderer.MustacheRenderer;
|
||||
import nu.marginalia.renderer.RendererFactory;
|
||||
import nu.marginalia.search.JteRenderer;
|
||||
import nu.marginalia.search.SearchOperator;
|
||||
import nu.marginalia.search.model.NavbarModel;
|
||||
import nu.marginalia.search.model.SimpleSearchResults;
|
||||
import nu.marginalia.search.model.UrlDetails;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -15,18 +15,18 @@ import spark.Response;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SearchCrosstalkService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SearchCrosstalkService.class);
|
||||
private final SearchOperator searchOperator;
|
||||
private final MustacheRenderer<CrosstalkResult> renderer;
|
||||
private final JteRenderer renderer;
|
||||
|
||||
@Inject
|
||||
public SearchCrosstalkService(SearchOperator searchOperator,
|
||||
RendererFactory rendererFactory) throws IOException
|
||||
public SearchCrosstalkService(SearchOperator searchOperator, JteRenderer renderer) throws IOException
|
||||
{
|
||||
this.searchOperator = searchOperator;
|
||||
this.renderer = rendererFactory.renderer("search/site-info/site-crosstalk");
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
public Object handle(Request request, Response response) throws SQLException {
|
||||
@ -48,23 +48,28 @@ public class SearchCrosstalkService {
|
||||
|
||||
CrosstalkResult model = new CrosstalkResult(parts[0], parts[1], resAtoB.results, resBtoA.results);
|
||||
|
||||
return renderer.render(model);
|
||||
return renderer.render(
|
||||
"siteinfo/crosstalk.jte",
|
||||
Map.of("model", model,
|
||||
"navbar", NavbarModel.SITEINFO));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private record CrosstalkResult(String domainA,
|
||||
public record CrosstalkResult(String domainA,
|
||||
String domainB,
|
||||
List<UrlDetails> forward,
|
||||
List<UrlDetails> backward)
|
||||
List<UrlDetails> aToB,
|
||||
List<UrlDetails> bToA)
|
||||
{
|
||||
|
||||
public boolean isFocusDomain() {
|
||||
return true; // Hack to get the search result templates behave well
|
||||
}
|
||||
public boolean hasBoth() {
|
||||
return !forward.isEmpty() && !backward.isEmpty();
|
||||
return !aToB.isEmpty() && !bToA.isEmpty();
|
||||
}
|
||||
public boolean hasA() {
|
||||
return !aToB.isEmpty();
|
||||
}
|
||||
public boolean hasB() {
|
||||
return !bToA.isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import nu.marginalia.WebsiteUrl;
|
||||
import nu.marginalia.renderer.RendererFactory;
|
||||
import nu.marginalia.search.JteRenderer;
|
||||
import nu.marginalia.search.model.NavbarModel;
|
||||
import org.slf4j.Logger;
|
||||
@ -34,8 +33,7 @@ public class SearchFrontPageService {
|
||||
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
@Inject
|
||||
public SearchFrontPageService(RendererFactory rendererFactory,
|
||||
HikariDataSource dataSource,
|
||||
public SearchFrontPageService(HikariDataSource dataSource,
|
||||
JteRenderer jteRenderer,
|
||||
SearchQueryCountService searchVisitorCount, WebsiteUrl websiteUrl
|
||||
) throws IOException {
|
||||
@ -51,10 +49,6 @@ public class SearchFrontPageService {
|
||||
return jteRenderer.render("serp/first.jte",
|
||||
Map.of("navbar", NavbarModel.SEARCH, "websiteUrl", websiteUrl)
|
||||
);
|
||||
// return template.render(new IndexModel(
|
||||
// getNewsItems(),
|
||||
// searchVisitorCount.getQueriesPerMinute()
|
||||
// ));
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,8 +11,6 @@ import nu.marginalia.api.feeds.RpcFeedItem;
|
||||
import nu.marginalia.api.livecapture.LiveCaptureClient;
|
||||
import nu.marginalia.db.DbDomainQueries;
|
||||
import nu.marginalia.model.EdgeDomain;
|
||||
import nu.marginalia.renderer.MustacheRenderer;
|
||||
import nu.marginalia.renderer.RendererFactory;
|
||||
import nu.marginalia.screenshot.ScreenshotService;
|
||||
import nu.marginalia.search.JteRenderer;
|
||||
import nu.marginalia.search.SearchOperator;
|
||||
@ -26,7 +24,6 @@ import org.slf4j.LoggerFactory;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@ -41,7 +38,6 @@ public class SearchSiteInfoService {
|
||||
private final DomainInfoClient domainInfoClient;
|
||||
private final SearchFlagSiteService flagSiteService;
|
||||
private final DbDomainQueries domainQueries;
|
||||
private final MustacheRenderer<Object> renderer;
|
||||
private final FeedsClient feedsClient;
|
||||
private final LiveCaptureClient liveCaptureClient;
|
||||
private final ScreenshotService screenshotService;
|
||||
@ -52,22 +48,19 @@ public class SearchSiteInfoService {
|
||||
@Inject
|
||||
public SearchSiteInfoService(SearchOperator searchOperator,
|
||||
DomainInfoClient domainInfoClient,
|
||||
RendererFactory rendererFactory,
|
||||
SearchFlagSiteService flagSiteService,
|
||||
DbDomainQueries domainQueries,
|
||||
FeedsClient feedsClient,
|
||||
LiveCaptureClient liveCaptureClient,
|
||||
ScreenshotService screenshotService,
|
||||
HikariDataSource dataSource,
|
||||
JteRenderer jteRenderer) throws IOException
|
||||
JteRenderer jteRenderer)
|
||||
{
|
||||
this.searchOperator = searchOperator;
|
||||
this.domainInfoClient = domainInfoClient;
|
||||
this.flagSiteService = flagSiteService;
|
||||
this.domainQueries = domainQueries;
|
||||
|
||||
this.renderer = rendererFactory.renderer("search/site-info/site-info");
|
||||
|
||||
this.feedsClient = feedsClient;
|
||||
this.liveCaptureClient = liveCaptureClient;
|
||||
this.screenshotService = screenshotService;
|
||||
|
@ -0,0 +1,86 @@
|
||||
@import nu.marginalia.api.math.model.DictionaryEntry
|
||||
@import nu.marginalia.search.command.SearchParameters
|
||||
@import nu.marginalia.search.model.NavbarModel
|
||||
@import nu.marginalia.search.model.SearchFilters
|
||||
@import nu.marginalia.api.math.model.DictionaryResponse
|
||||
|
||||
@param SearchParameters parameters
|
||||
@param DictionaryResponse result
|
||||
@param NavbarModel navbar
|
||||
|
||||
!{SearchFilters filters = new SearchFilters(parameters);}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
@template.part.head(title = "Marginalia Search - " + parameters.query())
|
||||
|
||||
<body class="min-h-screen bg-slate-100 font-sans" >
|
||||
@template.part.navbar(navbar = navbar)
|
||||
|
||||
<div>
|
||||
<header class="border-b border-gray-300 bg-white static top-0 shadow-md">
|
||||
<div class="max-w-[1400px] mx-auto px-4 py-2 sm:py-4">
|
||||
<div class="flex items-center">
|
||||
<div class="hidden sm:block md:w-32 md:mr-16 md:ml-16"><h1 class="text-md sm:text-xl mr-8 font-serif whitespace-nowrap"><a href="/">Marginalia Search</a></h1></div>
|
||||
<div class="w-full p-2 border-none backdrop-blur-sm">
|
||||
@template.serp.part.searchform(query = parameters.query(), profile = parameters.profileStr(), filters = filters)
|
||||
</div>
|
||||
<div class="grow"></div>
|
||||
<button class="fixed bottom-10 right-5 sm:hidden text-sm bg-margeblue text-white p-4 rounded-xl active:text-slate-200" id="filter-button">
|
||||
<i class="fas fa-filter mr-3"></i>
|
||||
Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="max-w-[1400px] mx-auto flex gap-6">
|
||||
<!-- Sidebar -->
|
||||
@template.serp.part.sidebar(filters = filters)
|
||||
|
||||
<!-- Main content -->
|
||||
<main class="flex-1 py-4 p-2 sm:p-4 max-w-3xl space-y-4">
|
||||
<div class="border rounded p-4 bg-white">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-book text-margeblue mx-2"></i> ${result.word()}
|
||||
</div>
|
||||
|
||||
@if (result.hasEntries())
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead>
|
||||
<tr class="bg-gray-50">
|
||||
<th scope="col" class="px-2 py-1 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
|
||||
<th scope="col" class="px-2 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Definition</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200 text-xs">
|
||||
@for (DictionaryEntry entry : result.entries())
|
||||
<tr>
|
||||
<td class="px-3 py-3 whitespace-nowrap">${entry.type()}</td>
|
||||
<td class="px-3 py-3 whitespace-nowrap">${entry.definition()}</td>
|
||||
</tr>
|
||||
@endfor
|
||||
</tbody>
|
||||
</table>
|
||||
@else
|
||||
<div>No definition found.</div>
|
||||
@endif
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@template.serp.part.footerHowto()
|
||||
|
||||
@template.part.footerLegal()
|
||||
|
||||
<%-- Put this last to not bother SR users with double menus --%>
|
||||
@template.serp.part.mobile-menu(filters = filters)
|
||||
|
||||
</body>
|
||||
<script lang="javascript" src="js/mobile-button.js"></script>
|
||||
<script lang="javascript" src="js/typeahead.js"></script>
|
||||
|
||||
</html>
|
@ -0,0 +1,66 @@
|
||||
@import nu.marginalia.search.command.SearchParameters
|
||||
@import nu.marginalia.search.model.NavbarModel
|
||||
@import nu.marginalia.search.model.SearchFilters
|
||||
|
||||
@param SearchParameters parameters
|
||||
@param String result
|
||||
@param NavbarModel navbar
|
||||
|
||||
!{SearchFilters filters = new SearchFilters(parameters);}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
@template.part.head(title = "Marginalia Search - " + parameters.query())
|
||||
|
||||
<body class="min-h-screen bg-slate-100 font-sans" >
|
||||
@template.part.navbar(navbar = navbar)
|
||||
|
||||
<div>
|
||||
<header class="border-b border-gray-300 bg-white static top-0 shadow-md">
|
||||
<div class="max-w-[1400px] mx-auto px-4 py-2 sm:py-4">
|
||||
<div class="flex items-center">
|
||||
<div class="hidden sm:block md:w-32 md:mr-16 md:ml-16"><h1 class="text-md sm:text-xl mr-8 font-serif whitespace-nowrap"><a href="/">Marginalia Search</a></h1></div>
|
||||
<div class="w-full p-2 border-none backdrop-blur-sm">
|
||||
@template.serp.part.searchform(query = parameters.query(), profile = parameters.profileStr(), filters = filters)
|
||||
</div>
|
||||
<div class="grow"></div>
|
||||
<button class="fixed bottom-10 right-5 sm:hidden text-sm bg-margeblue text-white p-4 rounded-xl active:text-slate-200" id="filter-button">
|
||||
<i class="fas fa-filter mr-3"></i>
|
||||
Filters
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="max-w-[1400px] mx-auto flex gap-6">
|
||||
<!-- Sidebar -->
|
||||
@template.serp.part.sidebar(filters = filters)
|
||||
|
||||
<!-- Main content -->
|
||||
<main class="flex-1 py-4 p-2 sm:p-4 max-w-3xl space-y-4">
|
||||
<div class="border rounded p-4 bg-white">
|
||||
<div class="mb-4">
|
||||
<i class="fas fa-calculator text-margeblue mx-2"></i> ${parameters.query()}
|
||||
</div>
|
||||
<div>
|
||||
${result}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@template.serp.part.footerHowto()
|
||||
|
||||
@template.part.footerLegal()
|
||||
|
||||
<%-- Put this last to not bother SR users with double menus --%>
|
||||
@template.serp.part.mobile-menu(filters = filters)
|
||||
|
||||
</body>
|
||||
<script lang="javascript" src="js/mobile-button.js"></script>
|
||||
<script lang="javascript" src="js/typeahead.js"></script>
|
||||
|
||||
</html>
|
@ -0,0 +1,112 @@
|
||||
@import nu.marginalia.search.model.NavbarModel
|
||||
@import nu.marginalia.search.model.UrlDetails
|
||||
@import nu.marginalia.model.EdgeDomain
|
||||
@import nu.marginalia.search.svc.*
|
||||
|
||||
@param SearchCrosstalkService.CrosstalkResult model
|
||||
@param NavbarModel navbar
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
@template.part.head(title = "Marginalia Search - " + model.domainA() + "/" + model.domainB())
|
||||
|
||||
<body class="min-h-screen bg-slate-100 font-sans" >
|
||||
|
||||
@template.part.navbar(navbar = navbar)
|
||||
|
||||
<header class="border-gray-300 bg-white shadow-md">
|
||||
<div class="max-w-[1400px] mx-auto p-2 md:p-4">
|
||||
<div class="flex flex-col place-items-center md:flex-row md:place-items-baseline space-x-2">
|
||||
<div class="text-gray-900 text-md font-mono rounded-sm block p-2.5 break-all">
|
||||
<a class="underline" href="/site/${model.domainA()}"> ${model.domainA()}</a>
|
||||
</div>
|
||||
|
||||
@if (model.hasBoth())
|
||||
<div class="hidden md:block">
|
||||
<i class="text-margeblue fa-solid fa-arrows-left-right"></i>
|
||||
</div>
|
||||
<div class="block md:hidden">
|
||||
<i class="text-margeblue fa-solid fa-up-down"></i>
|
||||
</div>
|
||||
@elseif (model.hasA())
|
||||
<div class="hidden md:block">
|
||||
<i class="text-margeblue fa-solid fa-arrow-right"></i>
|
||||
</div>
|
||||
<div class="block md:hidden">
|
||||
<i class="text-margeblue fa-solid fa-arrow-down"></i>
|
||||
</div>
|
||||
@else
|
||||
<div class="hidden md:block">
|
||||
<i class="text-margeblue fa-solid fa-arrow-left"></i>
|
||||
</div>
|
||||
<div class="block md:hidden">
|
||||
<i class="text-margeblue fa-solid fa-arrow-up"></i>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="text-gray-900 text-md font-mono rounded-sm block p-2.5 break-all">
|
||||
<a class="underline" href="/site/${model.domainB()}"> ${model.domainB()}</a>
|
||||
</div>
|
||||
<span class="grow"></span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="max-w-[1000px] mx-auto flex gap-1 flex-col md:flex-row place-items-center md:place-items-start py-4">
|
||||
|
||||
@if (model.hasA())
|
||||
<div class="border rounded bg-white flex flex-col overflow-hidden mx-4">
|
||||
<div class="flex space-x-2 flex-row place-items-baseline bg-margeblue text-white p-2 text-md">
|
||||
<span class="fas fa-globe"></span>
|
||||
<a href="/site/${model.domainA()}">${model.domainA()}</a>
|
||||
<span class="grow"></span>
|
||||
<a rel="nofollow noopener external" href="${new EdgeDomain(model.domainA()).toRootUrlHttps().toString()}" class="fa-solid fa-arrow-up-right-from-square" ></a>
|
||||
</div>
|
||||
|
||||
@for (UrlDetails details : model.aToB())
|
||||
<div class="p-2 font-medium text-sm text-gray-800 mx-2 mt-2">$unsafe{details.displayTitle()}</div>
|
||||
<div class="p-2 mx-2 text-gray-700 text-sm">
|
||||
$unsafe{details.displayDescription()}
|
||||
</div>
|
||||
<div class="p-2 text-sm border-b pb-6">
|
||||
<a rel="external noopener nofollow" href="${details.url.toString()}" class="mx-3 text-liteblue flex space-x-2 place-items-baseline hyphens-auto">
|
||||
<i class="fa fa-link"></i>
|
||||
<span class="grow break-all">$unsafe{details.displayUrl()}</span>
|
||||
</a>
|
||||
</div>
|
||||
@endfor
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (model.hasB())
|
||||
<div class="border rounded bg-white flex flex-col overflow-hidden mx-4">
|
||||
<div class="flex space-x-2 flex-row place-items-baseline bg-margeblue text-white p-2 text-md">
|
||||
<span class="fas fa-globe"></span>
|
||||
<a href="/site/${model.domainB()}">${model.domainB()}</a>
|
||||
<span class="grow"></span>
|
||||
<a rel="nofollow noopener external" href="${new EdgeDomain(model.domainB()).toRootUrlHttps().toString()}" class="fa-solid fa-arrow-up-right-from-square" ></a>
|
||||
</div>
|
||||
|
||||
@for (UrlDetails details : model.bToA())
|
||||
<div class="p-2 font-medium text-sm text-gray-800 mx-2 mt-2">$unsafe{details.displayTitle()}</div>
|
||||
<div class="p-2 mx-2 text-gray-700 text-sm">
|
||||
$unsafe{details.displayDescription()}
|
||||
</div>
|
||||
<div class="p-2 text-sm border-b pb-6">
|
||||
<a rel="external noopener nofollow" href="${details.url.toString()}" class="mx-3 text-liteblue flex space-x-2 place-items-baseline hyphens-auto">
|
||||
<i class="fa fa-link"></i>
|
||||
<span class="grow break-all">$unsafe{details.displayUrl()}</span>
|
||||
</a>
|
||||
</div>
|
||||
@endfor
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@template.part.footerLegal()
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1727,6 +1727,10 @@ video {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.md\:hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.md\:w-32 {
|
||||
width: 8rem;
|
||||
}
|
||||
@ -1755,6 +1759,10 @@ video {
|
||||
place-items: start;
|
||||
}
|
||||
|
||||
.md\:place-items-baseline {
|
||||
place-items: baseline;
|
||||
}
|
||||
|
||||
.md\:gap-8 {
|
||||
gap: 2rem;
|
||||
}
|
||||
@ -1771,6 +1779,10 @@ video {
|
||||
margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
|
||||
}
|
||||
|
||||
.md\:p-4 {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.md\:px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
|
@ -1,12 +0,0 @@
|
||||
<section class="card browse-result">
|
||||
<h2 title="{{url.domain}}">{{displayDomain}}</h2>
|
||||
|
||||
<a href="{{url.proto}}://{{url.domain}}/">
|
||||
<img src="/screenshot/{{domainId}}" title="{{displayDomain}} screenshot" alt="{{displayDomain}} screenshot" loading="lazy" width="400" height="300" />
|
||||
</a>
|
||||
|
||||
<div class="utils">
|
||||
<a href="/site/{{url.domain}}">Info</a>
|
||||
<a href="/explore/{{url.domain}}">Similar Domains</a>
|
||||
</div>
|
||||
</section>
|
@ -1,34 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{query}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
<span id="content-start"></span>
|
||||
<div class="infobox">
|
||||
{{#if focusDomain}}
|
||||
Showing domains similar to <tt>{{focusDomain}}</tt>.
|
||||
{{/if}}
|
||||
{{#unless focusDomain}}
|
||||
This list of domains is random. <a href="https://search.marginalia.nu/explore/random">Refresh</a> to get
|
||||
new domains, or click <b>Similar Domains</b> to
|
||||
take the helm.
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
<section class="cards">
|
||||
{{#each results}}{{>search/browse-result}}{{/each}}
|
||||
</section>
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{query}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
<span id="content-start"></span>
|
||||
<div class="infobox">
|
||||
{{query}} = {{result}}
|
||||
</div>
|
||||
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{query}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
<span id="content-start"></span>
|
||||
<div class="infobox">
|
||||
{{#unless entries}}
|
||||
No definitions were found for that word
|
||||
{{/unless}}
|
||||
|
||||
{{#if entries}}
|
||||
<ul>
|
||||
{{#each entries}}
|
||||
<li>{{word}}, {{type}}: {{definition}}<br></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if entries}}
|
||||
<div class="infobox">
|
||||
<h2>Legal</h2>
|
||||
This data is derived from <a href="https://en.wiktionary.org/">wiktionary</a>,
|
||||
available under GFDL and CC BY-SA 3.0. <a href="https://dumps.wikimedia.org/legal.html">More Information</a>.
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
@ -1,24 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{title}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
<span id="content-start"></span>
|
||||
<div class="infobox">
|
||||
<h2> {{ title }} </h2>
|
||||
<div class="info"> {{{message}}} </div>
|
||||
</div>
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
@ -1,20 +0,0 @@
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Error</title>
|
||||
<link rel="stylesheet" href="serp.css">
|
||||
<meta http-equiv="refresh" content="5">
|
||||
</head>
|
||||
<body>
|
||||
<div class="infobox">
|
||||
<h1>Error</h1>
|
||||
<p>Oops! It appears the index server is <span class="headline">{{indexState}}</span>.</p>
|
||||
<p>The server was probably restarted to bring online some changes. Restarting the index typically takes
|
||||
a few minutes, during which searches can't be served. </p>
|
||||
|
||||
<p>In the event of a longer outage, the <a rel="nofollow" href="https://twitter.com/MarginaliaNu">@marginalianu</a> feed
|
||||
on Twitter may have details, otherwise you can always send me an email at <tt>kontakt@marginalia.nu</tt>.</p>
|
||||
|
||||
<p>This page will attempt to refresh automatically every few seconds.</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,22 +0,0 @@
|
||||
<section id="frontpage-about">
|
||||
<h2>About</h2>
|
||||
<div class="info">
|
||||
<p>This is an independent DIY search engine that focuses on non-commercial content, and attempts to
|
||||
show you sites you perhaps weren't aware of in favor of the sort of sites you probably already knew
|
||||
existed. </p>
|
||||
<p>
|
||||
The software for this search engine is all custom-built, and all crawling and indexing is
|
||||
done in-house. The project is open source. Feel free to poke about in the <a
|
||||
href="https://git.marginalia.nu/">source code</a> or contribute
|
||||
to the development!
|
||||
</p>
|
||||
<p>
|
||||
The search engine is currently serving about <tt>{{searchPerMinute}}</tt> queries/minute.
|
||||
</p>
|
||||
<p>Consider <a href="https://memex.marginalia.nu/projects/edge/supporting.gmi">supporting the
|
||||
project</a>!</p>
|
||||
</div>
|
||||
<div class="utils">
|
||||
<a href="https://memex.marginalia.nu/projects/edge/about.gmi">Read More</a>
|
||||
</div>
|
||||
</section>
|
@ -1,17 +0,0 @@
|
||||
|
||||
{{#if news}}
|
||||
<section id="frontpage-news">
|
||||
<h2>Publicity, Discussion and Events</h2>
|
||||
<div class="info">
|
||||
<dl>
|
||||
{{#each news}}
|
||||
<dt><a href="{{url}}" rel="nofollow">{{title}}</a></dt>
|
||||
<dd>{{date}} {{source}} </dd>
|
||||
{{/each}}
|
||||
</dl>
|
||||
</div>
|
||||
<div class="utils">
|
||||
<a href="/news.xml">📡 RSS Feed</a>
|
||||
</div>
|
||||
</section>
|
||||
{{/if}}
|
@ -1,21 +0,0 @@
|
||||
<section id="frontpage-tips">
|
||||
<h2>Tips</h2>
|
||||
<div class="info">
|
||||
<p>
|
||||
This search engine isn't particularly well equipped to answering queries
|
||||
posed like questions, instead try to imagine some text that might appear
|
||||
in the website you are looking for, and search for that.</p>
|
||||
<p>
|
||||
Where this search engine really shines is finding small, old and obscure websites about some
|
||||
given topic, perhaps
|
||||
<a href="/search?query=commander+keen&profile=yolo&js=default">old video games</a>,
|
||||
<a href="/search?query=voynich+&profile=yolo&js=default">a mystery</a>,
|
||||
<a href="/search?query=augustine+confessions&profile=yolo&js=default">theology</a>,
|
||||
<a href="/search?query=Hermes+Trismegistus&profile=yolo&js=default">the occult</a>,
|
||||
<a href="/search?query=knitting&profile=yolo&js=default">knitting</a>,
|
||||
<a href="/search?query=scc+graph+algorithm&profile=yolo&js=default">computer science</a>,
|
||||
or <a href="/search?query=salvador+dali&profile=yolo&js=default">art</a>.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</section>
|
@ -1,31 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<meta property="og:description" content="search.marginalia.nu is a small independent do-it-yourself search engine for surprising but content-rich websites that never ask you to accept cookies or subscribe to newsletters. The goal is to bring you the sort of grass fed, free range HTML your grandma used to write. " />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:site_name" content="search.marginalia.nu" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://search.marginalia.nu/" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Hi there, fellow human being :-) -->
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
<section id="frontpage">
|
||||
{{>search/index/index-news}}
|
||||
{{>search/index/index-about}}
|
||||
{{>search/index/index-tips}}
|
||||
</section>
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
@ -1,46 +0,0 @@
|
||||
<h2>Filters</h2>
|
||||
<ul>
|
||||
{{#with removeJsOption}}
|
||||
<li title="Exclude results with javascript"
|
||||
{{#if set}}aria-checked="true" class="current"{{/if}}
|
||||
{{#unless set}}aria-checked="false"{{/unless}}
|
||||
role="checkbox">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
{{/with}}
|
||||
{{#with reduceAdtechOption}}
|
||||
<li title="Exclude results with tracking or likely affiliate links"
|
||||
{{#if set}}aria-checked="true" class="current"{{/if}}
|
||||
{{#unless set}}aria-checked="false"{{/unless}}
|
||||
role="checkbox">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
{{/with}}
|
||||
{{#with showRecentOption}}
|
||||
<li title="Prefer recent results"
|
||||
{{#if set}}aria-checked="true" class="current"{{/if}}
|
||||
{{#unless set}}aria-checked="false"{{/unless}}
|
||||
role="checkbox">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
{{/with}}
|
||||
{{#with searchTitleOption}}
|
||||
<li title="Require title match"
|
||||
{{#if set}}aria-checked="true" class="current"{{/if}}
|
||||
{{#unless set}}aria-checked="false"{{/unless}}
|
||||
role="checkbox">
|
||||
<a href="{{url}}">{{name}}</a>
|
||||
</li>
|
||||
{{/with}}
|
||||
</ul>
|
||||
<h3>Domains</h3>
|
||||
<ul>
|
||||
{{#each filterGroups}}
|
||||
{{#each .}}
|
||||
<li {{#if current}}aria-selected="true" class="current"{{/if}}><a href="{{url}}">{{displayName}}</a></li>
|
||||
{{/each}}
|
||||
<hr>
|
||||
{{/each}}
|
||||
</ul>
|
||||
<!-- load this ASAP to avoid flicker -->
|
||||
<script src="/menu.js"></script>
|
@ -1,124 +0,0 @@
|
||||
<footer class="onlyscreen">
|
||||
<section id="tips-syntax">
|
||||
<h1>Syntax</h1>
|
||||
This is a keyword-based search engine. When entering multiple search terms, the search engine will
|
||||
attempt to match them against documents where the terms occur in close proximity.<p>
|
||||
|
||||
Search terms can be excluded with a hyphen.<p>
|
||||
|
||||
While the search engine at present does not allow full text search, quotes can be used to
|
||||
specifically search for names or terms in the title. Using quotes will also cause the search engine
|
||||
to be as literal as possible in interpreting the query.<p>
|
||||
|
||||
Parentheses can be used to add terms to the query without giving weight to the terms when ranking
|
||||
the search results.<p>
|
||||
|
||||
<h2>Samples</h2>
|
||||
<dl class="query-samples">
|
||||
<dt>soup -chicken</dt>
|
||||
<dd>Look for keywords that contain <sample>soup</sample>, but not
|
||||
<sample>chicken</sample>.</dd>
|
||||
<dt>"keyboard"</dt>
|
||||
<dd>Look for pages containing the exact word
|
||||
<sample>keyboard</sample>, not <sample>keyboards</sample> or the like.</dd>
|
||||
<dt>"steve mcqueen"</dt>
|
||||
<dd>Look for pages containing the exact words <sample>steve mcqueen</sample>
|
||||
in that order, with no words in between.</dd>
|
||||
<dt>apology (plato)</dt>
|
||||
<dd>Look for pages containing <sample>apology</sample> and <sample>plato</sample>, but only rank them
|
||||
based on their relevance to <sample>apology</sample></dd>
|
||||
</dl>
|
||||
</section>
|
||||
<section id="tips-keywords">
|
||||
<h1>Special Keywords</h1>
|
||||
Several special keywords are supported by the search engine.
|
||||
<p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th>Keyword</th><th>Meaning</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr><td>site:<em>example.com</em></td><td>Display site information about <em>example.com</em></td></tr>
|
||||
<tr><td>site:<em>example.com</em> <em>keyword</em></td><td>Search <em>example.com</em> for <em>keyword</em></td></tr>
|
||||
<tr><td>browse:<em>example.com</em></td><td>Show similar websites to <em>example.com</em></td></tr>
|
||||
<tr><td>ip:<em>127.0.0.1</em></td><td>Search documents hosted at <em>127.0.0.1</em></td></tr>
|
||||
<tr><td>links:<em>example.com</em></td><td>Search documents linking to <em>example.com</em></td></tr>
|
||||
|
||||
<tr><td>tld:<em>edu</em> <em>keyword</em></td><td>Search documents with the top level domain <em>edu</em>.</td></tr>
|
||||
<tr><td>?tld:<em>edu</em> <em>keyword</em></td><td>Prefer but do not require results with the top level domain <em>edu</em>.
|
||||
This syntax is also possible for links:..., ip:... and site:...</td></tr>
|
||||
|
||||
<tr><td>q>5</td><td>The amount of javascript and modern features is at least 5 (on a scale 0 to 25)</td></tr>
|
||||
<tr><td>q<5</td><td>The amount of javascript and modern features is at most 5 (on a scale 0 to 25)</td></tr>
|
||||
|
||||
<tr><td>year>2005</td><td>(beta) The document was ostensibly published in or after 2005</td></tr>
|
||||
<tr><td>year=2005</td><td>(beta) The document was ostensibly published in 2005</td></tr>
|
||||
<tr><td>year<2005</td><td>(beta) The document was ostensibly published in or before 2005</td></tr>
|
||||
|
||||
<tr><td>rank>50</td><td>The ranking of the website is at least 50 in a span of 1 - 255</td></tr>
|
||||
<tr><td>rank<50</td><td>The ranking of the website is at most 50 in a span of 1 - 255</td></tr>
|
||||
|
||||
<tr><td>count>10</td><td> The search term must appear in at least 10 results form the domain</td></tr>
|
||||
<tr><td>count<10</td><td> The search term must appear in at most 10 results from the domain</td></tr>
|
||||
|
||||
|
||||
<tr><td>format:html5</td><td>Filter documents using the HTML5 standard. This is typically modern websites.</td></tr>
|
||||
<tr><td>format:xhtml</td><td>Filter documents using the XHTML standard</td></tr>
|
||||
<tr><td>format:html123</td><td>Filter documents using the HTML standards 1, 2, and 3. This is typically very old websites. </td></tr>
|
||||
|
||||
<tr><td>generator:wordpress</td><td>Filter documents with the specified generator, in this case wordpress</td></tr>
|
||||
|
||||
<tr><td>file:zip</td><td>Filter documents containing a link to a zip file (most file-endings work)</td></tr>
|
||||
<tr><td>file:audio</td><td>Filter documents containing a link to an audio file</td></tr>
|
||||
<tr><td>file:video</td><td>Filter documents containing a link to a video file</td></tr>
|
||||
<tr><td>file:archive</td><td>Filter documents containing a link to a compressed archive</td></tr>
|
||||
<tr><td>file:document</td><td>Filter documents containing a link to a document</td></tr>
|
||||
|
||||
<tr><td>-special:media</td><td>Filter out documents with audio or video tags</td></tr>
|
||||
<tr><td>-special:scripts</td><td>Filter out documents with javascript</td></tr>
|
||||
<tr><td>-special:affiliate</td><td>Filter out documents with likely Amazon affiliate links</td></tr>
|
||||
<tr><td>-special:tracking</td><td>Filter out documents with analytics or tracking code</td></tr>
|
||||
<tr><td>-special:cookies</td><td>Filter out documents with cookies</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
<section>
|
||||
<h1>Results Legend</h1>
|
||||
<p>
|
||||
The estimated relevance of the search result is indicated using the color saturation
|
||||
of the color of the search result, as well as the order the results are presented.
|
||||
</p>
|
||||
<p>
|
||||
Information about the position of the match is indicated using a dot matrix
|
||||
in the bottom bar of each search result. Each dot represents four sentences,
|
||||
and are presented in an order of top-to-bottom, left-to-right.
|
||||
|
||||
<br><br><span class="meta positions">⣿⠃⠀⠀</span> — The terms occur heavily toward the beginning of the document.
|
||||
<br><br><span class="meta positions">⠠⠀⡄⠁</span> — The terms occur sparsely throughout the document.
|
||||
<br><br><span class="meta positions">⠀⠁⠀⠀</span> — The terms occur only in a single sentence.
|
||||
</p>
|
||||
<p> Potentially problems with the document are presented with a warning triangle, e.g. ⚠ 3.
|
||||
Desktop users can mouse-over this to get a detailed breakdown.
|
||||
</section>
|
||||
<section id="legal">
|
||||
<h1>Policies</h1>
|
||||
This website complies with the GDPR by <em>not collecting any personal
|
||||
information</em>, and with the EU Cookie Directive by <em>not using
|
||||
cookies</em>. <a href="https://memex.marginalia.nu/projects/edge/privacy.gmi">More Information</a>.
|
||||
<h1> Contact </h1>
|
||||
Reach me at <tt><a href="mailto://kontakt@marginalia.nu">kontakt@marginalia.nu</a></tt>,
|
||||
<tt><a href="https://twitter.com/MarginaliaNu">@MarginaliaNu</a></tt> on twitter.
|
||||
<h1> Open Source </h1>
|
||||
The search engine is open source with an AGPL license. The sources can be perused at
|
||||
<tt><a href="https://git.marginalia.nu/">https://git.marginalia.nu/</a></tt>.
|
||||
<h1>Data Sources</h1>
|
||||
IP geolocation is sourced from the IP2Location LITE data available from
|
||||
<a rel="external noopener nofollow" href="https://lite.ip2location.com/">https://lite.ip2location.com/</a>
|
||||
under
|
||||
<a rel="external noopener nofollow" href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA 4.0</a>.
|
||||
</section>
|
||||
|
||||
</footer>
|
||||
|
||||
<script src="/tts.js"></script>
|
@ -1,18 +0,0 @@
|
||||
<form action="/search" method="get" id="search-form">
|
||||
<div id="search-box">
|
||||
<h1>
|
||||
Search The Internet
|
||||
</h1>
|
||||
<div id="suggestions-anchor"></div>
|
||||
<input {{#unless query}}autofocus{{/unless}} type="text" id="query" name="query" placeholder="Search..." value="{{query}}">
|
||||
<input type="hidden" name="js" value="{{js}}">
|
||||
<input type="hidden" name="adtech" value="{{adtech}}">
|
||||
<input type="hidden" name="searchTitle" value="{{searchTitle}}">
|
||||
<input type="hidden" name="profile" value="{{profile}}">
|
||||
<input type="hidden" name="recent" value="{{recent}}">
|
||||
|
||||
<input type="submit" form="search-form" title="Execute Search" value="Search" autocomplete="off">
|
||||
</div>
|
||||
</form>
|
||||
<!-- load the first stage mobile customizations script early to avoid flicker -->
|
||||
<script src="/main.js"></script>
|
@ -1,21 +0,0 @@
|
||||
<a name="top"></a>
|
||||
<header>
|
||||
<nav>
|
||||
<a href="#" class="screenreader-only" onClick="">Skip to content</a>
|
||||
<a href="https://www.marginalia.nu/">Marginalia</a>
|
||||
<a href="https://memex.marginalia.nu/projects/edge/about.gmi">About</a>
|
||||
<a href="https://memex.marginalia.nu/projects/edge/supporting.gmi">Donate</a>
|
||||
<a class="extra" href="https://search.marginalia.nu/explore/random">Random</a>
|
||||
</nav>
|
||||
<div id="theme">
|
||||
<label for="theme-select" class="screenreader-only">Color Theme</label>
|
||||
<select id="theme-select">
|
||||
<option value="system" selected>System</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- load this ASAP to avoid color theme flicker -->
|
||||
<script src="/theme.js"></script>
|
@ -1,32 +0,0 @@
|
||||
|
||||
<section data-ms-rank="{{first.matchRank}}" class="card search-result" >
|
||||
{{#with first}}
|
||||
<div class="url"><a rel="nofollow external" href="{{url}}">{{url}}</a></div>
|
||||
<h2> <a tabindex="-1" class="title" rel="nofollow external" href="{{url}}">{{title}}</a> </h2>
|
||||
<p class="description">{{description}}</p>
|
||||
|
||||
{{/with}}
|
||||
<div class="utils">
|
||||
Also from {{first.url.domain}}
|
||||
</div>
|
||||
<ul class="additional-results">
|
||||
{{#each rest}}
|
||||
<li><a href="{{url}}">{{title}}</a></li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{#with first}}
|
||||
<div class="utils">
|
||||
<a href="/site/{{url.domain}}" title="Domain Information">Info</a>
|
||||
<a href="/site-search/{{url.domain}}/{{query}}?profile={{profile}}" title="More results from this domain">{{resultsFromSameDomain}}+</a>
|
||||
<div class="meta">
|
||||
{{#each problems}}
|
||||
<span class="problem" title="{{description}}">{{name}}</span>
|
||||
{{/each}}
|
||||
<span aria-hidden="true" class="meta positions"
|
||||
title="Positions where keywords were found within the document">{{positions}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/with}}
|
||||
</section>
|
||||
|
||||
<hr class="w3m-helper" />
|
@ -1,22 +0,0 @@
|
||||
<!-- {{termScore}} -->
|
||||
<section data-ms-rank="{{matchRank}}" class="card search-result" >
|
||||
|
||||
<div class="url"><a rel="nofollow external" href="{{url}}">{{url}}</a></div>
|
||||
<h2> <a tabindex="-1" class="title" rel="nofollow external" href="{{url}}">{{title}}</a> </h2>
|
||||
<p class="description">{{description}}</p>
|
||||
|
||||
<div class="utils">
|
||||
{{#unless focusDomain}}
|
||||
<a href="/site/{{url.domain}}" title="Domain Information">Info</a>
|
||||
{{#if hasMoreResults}}<a href="/site-search/{{url.domain}}/{{query}}?profile={{profile}}" title="More results from this domain">{{resultsFromSameDomain}}+</a>{{/if}}{{/unless}}
|
||||
<div class="meta">
|
||||
{{#each problems}}
|
||||
<span class="problem" title="{{description}}">{{name}}</span>
|
||||
{{/each}}
|
||||
<span aria-hidden="true" class="meta positions"
|
||||
title="Positions where keywords were found within the document">{{positions}}</span>
|
||||
<div class="screenreader-only">Terms appear in {{positionsCount}} positions</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<hr class="w3m-helper" />
|
@ -1,75 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{query}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
|
||||
<body data-filter="{{filters.currentFilter}}">
|
||||
|
||||
{{#if newFilter}} <div class="screenreader-only" aria-role="status">Search Filters Updated</div> {{/if}}
|
||||
|
||||
<!-- Hi there, fellow human being :-) -->
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
|
||||
|
||||
<span id="content-start"></span>
|
||||
|
||||
<section class="sidebar-narrow">
|
||||
<section id="results" class="sb-left">
|
||||
{{#if focusDomain}}
|
||||
<div class="infobox">
|
||||
Showing search results from <a href="/site/{{focusDomain}}">{{focusDomain}}</a>.
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#unless results}}
|
||||
<div class="infobox">
|
||||
No search results found. If you believe this is an error, consider either
|
||||
<a href="https://github.com/MarginaliaSearch/MarginaliaSearch/issues">submitting an issue on GitHub</a>,
|
||||
or sending an email to <a href="mailto:kontakt@marginalia.nu">kontakt@marginalia.nu</a> describing
|
||||
the problem.
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
{{#unless focusDomain}}
|
||||
<div class="infobox screenreader-only">
|
||||
Showing {{resultCount}} search results.
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{#each results}}
|
||||
{{#if hasMultiple}}
|
||||
{{>search/parts/search-result-rest}}
|
||||
{{else}}
|
||||
{{#with first}}
|
||||
{{>search/parts/search-result}}
|
||||
{{/with}}
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
|
||||
{{#if multipage}}
|
||||
<nav aria-label="pagination">
|
||||
{{#each resultPages}}
|
||||
<a {{#unless current}}href="{{{href}}}"{{/unless}} class="page-link {{#if current}}active{{/if}}">{{number}}</a>
|
||||
{{/each}}
|
||||
</nav>
|
||||
{{/if}}
|
||||
</section>
|
||||
|
||||
{{#with filters}}
|
||||
<section id="filters" class="sb-right">
|
||||
{{>search/parts/search-filters}}
|
||||
</section>
|
||||
{{/with}}
|
||||
|
||||
</section>
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
||||
</html>
|
@ -1,40 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{domainA}} and {{domainB}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
{{>search/parts/search-form}}
|
||||
|
||||
<span id="content-start"></span>
|
||||
|
||||
<div class="infobox">
|
||||
Showing results containing links between <a href="/site/{{domainA}}">{{domainA}}</a> and <a href="/site/{{domainB}}">{{domainB}}</a>.
|
||||
</div>
|
||||
{{#each tests}}{{.}}{{/each}}
|
||||
<div {{#if hasBoth}}id="crosstalk-view"{{/if}}>
|
||||
<div>
|
||||
{{#each forward}}
|
||||
{{>search/parts/search-result}}
|
||||
{{/each}}
|
||||
</div>
|
||||
<div>
|
||||
{{#each backward}}
|
||||
{{>search/parts/search-result}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
{{#if feed.items}}
|
||||
{{#with feed}}
|
||||
<h2><a title="Atom/RSS feed" target="external" href="{{feedUrl}}"><img width="16" height="16" src="/rss.svg"></a> Feed</h2>
|
||||
|
||||
<dl>
|
||||
{{#each items}}
|
||||
<dt><a href="{{url}}" rel="external noopener ugc">{{title}}</a></dt>
|
||||
<dd><date>{{pubDay}}</date><br>{{{descriptionSafe}}}</dd>
|
||||
{{/each}}
|
||||
</dl>
|
||||
{{/with}}
|
||||
{{/if}}
|
||||
|
||||
{{#unless feed.items}}{{#if samples}}
|
||||
<h2>Sample</h2>
|
||||
<dl>
|
||||
{{#each samples}}
|
||||
<dt><a href="{{url}}" rel="external noopener ugc">{{title}}</a></dt>
|
||||
<dd>{{description}}</dd>
|
||||
{{/each}}
|
||||
</dl>
|
||||
{{/if}}{{/unless}}
|
@ -1,8 +0,0 @@
|
||||
<p>This website is <em>blacklisted</em>. This excludes it from crawling and indexing.</p>
|
||||
|
||||
<p>This is usually because of some form of misbehavior on the webmaster's end.
|
||||
Either annoying search engine spam, or tasteless content bad faith content.</p>
|
||||
|
||||
<p>Occasionally this is done hastily and in error. If you would like the decision
|
||||
reviewed, you may use the <a href="?v=report">report form</a> to file an appeal.</tt>
|
||||
</p>
|
@ -1,13 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>Index</legend>
|
||||
State: {{state}}<br/>
|
||||
Domain ID: {{domainId}} <br/>
|
||||
Node Affinity: {{nodeAffinity}} <br/>
|
||||
Pages Known: {{pagesKnown}} <br/>
|
||||
Pages Crawled: {{pagesFetched}} <br/>
|
||||
Pages Indexed: {{pagesIndexed}} <br/>
|
||||
<p></p>
|
||||
IP: {{ip}} {{#if ipCountry}}<span title="{{ipCountry}}">{{getIpFlag}}</span>{{/if}}<br/>
|
||||
<span title="Autonomous System">AS</span>: {{#if asn}}<a href="/search?query=as:{{asn}}&profile=corpo">{{asn}}</a> {{asnOrg}} {{asnCountry}}{{/if}} <br/>
|
||||
</fieldset>
|
||||
<br/>
|
@ -1,12 +0,0 @@
|
||||
<form method="POST" action="/site/suggest/">
|
||||
<fieldset>
|
||||
<legend>Crawling</legend>
|
||||
This website is not queued for crawling. If you would like it to be crawled,
|
||||
use the checkbox and button below.<p/>
|
||||
<input type="hidden" name="id" value="{{domainId}}" />
|
||||
<input type="checkbox" id="nomisclick" name="nomisclick" /> <label for="nomisclick"> This is not a mis-click </label>
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="submit" value="Add {{domain}} to queue" />
|
||||
</fieldset>
|
||||
</form>
|
@ -1,9 +0,0 @@
|
||||
<fieldset>
|
||||
<legend>Crawling</legend>
|
||||
This website is not known to the search engine.
|
||||
|
||||
To submit the website for crawling, follow <a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href="https://github.com/MarginaliaSearch/submit-site-to-marginalia-search">these instructions</a>.
|
||||
</fieldset>
|
@ -1,23 +0,0 @@
|
||||
<h2>Indexing Information</h2>
|
||||
{{#if domainState.blacklisted}}
|
||||
{{>search/site-info/site-info-index-blacklisted}}
|
||||
{{/if}}
|
||||
|
||||
{{#if domainState.unknownDomain}}
|
||||
{{>search/site-info/site-info-index-unknown}}
|
||||
{{/if}}
|
||||
|
||||
{{#if domainState.inCrawlQueue}}
|
||||
<p>
|
||||
This website is in the queue for crawling.
|
||||
It may take up to a month before it is indexed.
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if domainState.suggestForCrawling}}
|
||||
{{>search/site-info/site-info-index-suggest}}
|
||||
{{/if}}
|
||||
|
||||
{{#if domainState.indexed}}
|
||||
{{>search/site-info/site-info-index-indexed}}
|
||||
{{/if}}
|
@ -1,7 +0,0 @@
|
||||
<h2>Links</h2>
|
||||
<fieldset>
|
||||
<legend>Link Graph</legend>
|
||||
Ranking: {{ranking}}%<br/>
|
||||
Incoming Links: {{incomingLinks}} <br/>
|
||||
Outbound Links: {{outboundLinks}} <br/>
|
||||
</fieldset>
|
@ -1,60 +0,0 @@
|
||||
<section id="complaint">
|
||||
{{#if submitted}}
|
||||
<h2>Your complaint against {{domain}} has been submitted</h2>
|
||||
<p>The review process is manual and may take a while. If urgent action is necessary,
|
||||
reach me at kontakt@marginalia.nu!
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#unless submitted}}
|
||||
<h2>Flag {{domain}} for review</h2>
|
||||
<p>
|
||||
Note, this is not intended to police acceptable thoughts or ideas.
|
||||
<p>
|
||||
That said, offensive content in obvious bad faith is not tolerated, especially when designed
|
||||
to crop up when you didn't go looking for it. How and where it is said is more
|
||||
important than what is said.
|
||||
<p>
|
||||
This form can also be used to appeal unfairly blacklisted sites.
|
||||
<p>
|
||||
|
||||
<form method="POST">
|
||||
<fieldset>
|
||||
<legend>Flag for Review</legend>
|
||||
|
||||
<label for="category">Category</label><br>
|
||||
<select name="category" id="category">
|
||||
{{#each category}} <option value="{{categoryName}}">{{categoryDesc}}</option> {{/each}}
|
||||
</select>
|
||||
<br>
|
||||
<br>
|
||||
<label for="description">Description</label><br>
|
||||
<textarea type="text" name="description" id="description" rows=4></textarea><br>
|
||||
<br>
|
||||
<label for="samplequery">(Optional) Search Query </label><br>
|
||||
<input type="text" name="samplequery" id="samplequery" length=255 /><br>
|
||||
<br>
|
||||
<br/>
|
||||
<input type="submit" value="File complaint" />
|
||||
</fieldset>
|
||||
</form>
|
||||
<p>
|
||||
Communicating through forms and tables is a bit impersonal,
|
||||
you may also reach a human being through email at <tt>kontakt@marginalia.nu</tt>.
|
||||
{{/unless}}
|
||||
|
||||
{{#if complaints}}
|
||||
<hr>
|
||||
<h2> Complaints against {{domain}} </h2>
|
||||
<table border width=100%>
|
||||
<tr><th>Category</th><th>Submitted</th><th>Reviewed</th></tr>
|
||||
{{#each complaints}}
|
||||
<tr>
|
||||
<td>{{category}}</td>
|
||||
<td>{{submitTime}}</td>
|
||||
<td>{{#if reviewed}}✓{{/if}}</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
{{/if}}
|
||||
</section>
|
@ -1,124 +0,0 @@
|
||||
<div class="infobox">
|
||||
A <a href="/explore/{{domain}}">visual exploration</a> mode is also available.
|
||||
</div>
|
||||
|
||||
|
||||
<div id="similar-view" data-layout="{{layout}}">
|
||||
<div id="similar-info">
|
||||
<h2><span title="External Link">🌎</span> <a rel="external noopener" href="{{siteUrl}}">{{domain}}</a></h2>
|
||||
|
||||
|
||||
{{#if hasScreenshot}}
|
||||
<a rel="external noopener" href="{{siteUrl}}">
|
||||
<img class="screenshot" width="300" height="225" src="/screenshot/{{domainId}}" alt="Screenshot of {{domain}}" />
|
||||
</a>
|
||||
{{/if}}
|
||||
|
||||
{{#unless hasScreenshot}}
|
||||
<p>Screenshot not yet available.</p>
|
||||
{{/unless}}
|
||||
|
||||
{{#with domainInformation}}
|
||||
{{> search/site-info/site-info-feed}}
|
||||
{{> search/site-info/site-info-index}}
|
||||
{{> search/site-info/site-info-links}}
|
||||
{{/with}}
|
||||
</div>
|
||||
|
||||
{{#if linking}}
|
||||
<div id="similar-links">
|
||||
<h2>Linking Domains</h2>
|
||||
|
||||
<table class="similarity-table">
|
||||
<tr>
|
||||
<th colspan="3">Meta</th>
|
||||
<th>Rank</th>
|
||||
<th>Domain</th>
|
||||
<th>Similarity</th>
|
||||
</tr>
|
||||
{{#each linking}}
|
||||
<tr>
|
||||
<td>
|
||||
{{#if indexed}}
|
||||
{{#if active}}
|
||||
<span title="Indexed">👀</span>
|
||||
{{/if}}
|
||||
{{#unless active}}
|
||||
<span title="Problem">🔥</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{#if screenshot}}📷{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{#if linkType.isLinked}}
|
||||
<span title="{{linkType.description}}"><a href="/crosstalk/?domains={{domain}},{{url.domain}}">{{{linkType}}}</a></span>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
<span title="{{rank}}%">{{{rankSymbols}}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/site/{{url.domain}}?view=similar" rel="external noopener nofollow">{{url.domain}}</a></td>
|
||||
<td>
|
||||
<progress value="{{relatedness}}" max="100.0">{{relatedness}}</progress><br>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
{{#if similar}}
|
||||
<div id="similar-domains">
|
||||
<h2>Similar Domains</h2>
|
||||
|
||||
<table class="similarity-table">
|
||||
<tr>
|
||||
<th colspan="3">Meta</th>
|
||||
<th>Rank</th>
|
||||
<th>Domain</th>
|
||||
<th>Similarity</th>
|
||||
</tr>
|
||||
{{#each similar}}
|
||||
<tr>
|
||||
<td>
|
||||
{{#if indexed}}
|
||||
{{#if active}}
|
||||
<span title="Indexed">👀</span>
|
||||
{{/if}}
|
||||
{{#unless active}}
|
||||
<span title="Problem">🔥</span>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{#if screenshot}}📷{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
{{#if linkType.isLinked}}
|
||||
<span title="{{linkType.description}}"><a href="/crosstalk/?domains={{domain}},{{url.domain}}">{{{linkType}}}</a></span>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td>
|
||||
<span title="{{rank}}%">{{{rankSymbols}}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="/site/{{url.domain}}?view=similar" rel="external noopener nofollow">{{url.domain}}</a></td>
|
||||
<td>
|
||||
<progress value="{{relatedness}}" max="100.0">{{relatedness}}</progress><br>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
<p><b>Note</b>: Because two domains are considered similar does not always mean they're in
|
||||
cahoots. Similarity is a measure of how often they appear in the same contexts,
|
||||
which may be an association like peas and carrots, but some pairings are also defined by their
|
||||
contrasting opposition, like Sparta and Athens.</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
</div>
|
@ -1,58 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Marginalia Search - {{domain}}</title>
|
||||
|
||||
<link rel="stylesheet" href="/serp.css" />
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Marginalia">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="robots" content="noindex" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
{{>search/parts/search-header}}
|
||||
|
||||
{{>search/parts/search-form}}
|
||||
<span id="content-start"></span>
|
||||
|
||||
{{#with view}}
|
||||
<nav id="siteinfo-nav">
|
||||
<h2>{{domain}}</h2>
|
||||
<ul>
|
||||
<li {{#if info}}class="current"{{/if}}><a href="?view=info">Info</a></li>
|
||||
<li {{#if docs}}class="current"{{/if}}>{{#if known}}<a href="?view=docs">Docs</a>{{/if}}{{#unless known}}<a class="link-unavailable" title="This domain is not known by the search engine">Docs</a>{{/unless}}</li>
|
||||
<li {{#if links}}class="current"{{/if}}><a href="?view=links">Backlinks</a></li>
|
||||
|
||||
<li {{#if report}}class="current"{{/if}}>{{#if known}}<a href="?view=report">Report</a>{{/if}}{{#unless known}}<a class="link-unavailable" title="This domain is not known by the search engine">Report</a>{{/unless}}</li>
|
||||
</ul>
|
||||
</nav>
|
||||
{{/with}}
|
||||
|
||||
{{#if view.links}}
|
||||
<div class="infobox">
|
||||
Showing search results with links to {{domain}}.
|
||||
</div>
|
||||
{{#each results}}{{>search/parts/search-result}}{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if view.docs}}
|
||||
<div class="infobox">
|
||||
Showing documents found in {{domain}}.
|
||||
</div>
|
||||
|
||||
{{#each results}}{{>search/parts/search-result}}{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if view.report}}
|
||||
{{>search/site-info/site-info-report}}
|
||||
{{/if}}
|
||||
|
||||
{{#if view.info}}
|
||||
{{>search/site-info/site-info-summary}}
|
||||
{{/if}}
|
||||
|
||||
{{>search/parts/search-footer}}
|
||||
</body>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user