~netlandish/links

049af9601fd0ae8b03fe17eb96d49bba98e2d176 — Peter Sanchez 3 months ago bee0030
Adding features to homepage instead of a separate page
4 files changed, 160 insertions(+), 108 deletions(-)

M core/routes.go
M helpers.go
M templates/base.html
M templates/feature_tour.html
M core/routes.go => core/routes.go +66 -73
@@ 51,7 51,7 @@ type Service struct {

// RegisterRoutes ...
func (s *Service) RegisterRoutes() {
	s.eg.GET("/", s.Homepage).Name = "index"
	s.eg.GET("/", s.Homepage).Name = s.RouteName("index")
	s.eg.GET("/invalid/:d", s.InvalidDomain).Name = s.RouteName("invalid_domain")
	s.eg.GET("/:slug", s.OrgLinksList).Name = s.RouteName("org_link_list")
	s.eg.GET("/:slug/rss", s.OrgLinksList).Name = s.RouteName("org_link_list_rss")


@@ 260,7 260,7 @@ func (s *Service) InvalidDomain(c echo.Context) error {
		return err
	}
	if len(domains) == 0 {
		// NOTE Should not happens, but just in case
		// Should not happen, but just in case
		return echo.NotFoundHandler(c)
	}
	gmap := gobwebs.Map{"pd": pd, "domain": d}


@@ 281,59 281,7 @@ func (s *Service) Homepage(c echo.Context) error {
		return c.Redirect(http.StatusFound, c.Echo().Reverse(s.RouteName("home_link_list")))
	}

	lt := localizer.GetSessionLocalizer(c)
	pd := localizer.NewPageData(
		lt.Translate("Social bookmarking plus link sharing, shortening and listings all in one app."),
	)
	pd.Data["line1"] = lt.Translate(
		"Welcome to LinkTaco. Where you can mix all your link saving and sharing needs in one " +
			"tight little bundle. Much like a taco. A link taco if you will.",
	)
	pd.Data["line2"] = lt.Translate(
		"OK that's cheesy, I know... get it... cheesy? OK, I'll stop. Everyone knows you don't " +
			"actually put cheese in tacos.",
	)
	pd.Data["line3"] = lt.Translate("Seriously though...")
	pd.Data["line4"] = lt.Translate(
		"Social bookmarking is not new, it's just been forgotten. Link shortening with " +
			"analytics has been around forever. Link listings became cool once social media " +
			"started allowing us to post a link to our websites in our profiles.",
	)
	pd.Data["line5"] = lt.Translate(
		"Up until now, all of these things were hosted on different services:",
	)
	pd.Data["pinboard"] = lt.Translate("Social bookmarking: Pinboard (Delicious)")
	pd.Data["bitly"] = lt.Translate("Link shortening: Bitly et al")
	pd.Data["linktree"] = lt.Translate("Link listings: Linktree et al")
	pd.Data["line5"] = lt.Translate("Peace Pinboard. Bye Bitly. Later Linktree.")
	pd.Data["line6"] = lt.Translate(
		"Hello LinkTaco! A single, open source, platform for you to host all of your " +
			"links. Custom domains, QR codes, Analytics, full API, multiple organizations " +
			"w/ unlimited members are just some of what's included. See the full features " +
			"page for more.",
	)
	pd.Data["line7"] = lt.Translate(
		"Since we're a 100%% open source project you can host your own instance if you'd " +
			"like full control over your own platform. See the install docs for more.",
	)
	pd.Data["line8"] = lt.Translate(
		"Ready to get started? It's free to make an account and use it forever (with " +
			"some limitations). To use all features you have to pay just a few bucks a year, " +
			"or a few per month if you're a business, and that's it. Simple!",
	)

	pd.Data["login"] = lt.Translate("Login")
	pd.Data["email_address"] = lt.Translate("Email Address")
	pd.Data["password"] = lt.Translate("Password")
	pd.Data["forgot_password"] = lt.Translate("Forgot Password?")
	pd.Data["login"] = lt.Translate("Login")
	pd.Data["no_accounts"] = lt.Translate("No accounts? Click here to create one")

	gmap := gobwebs.Map{
		"pd": pd,
	}
	return links.Render(c, http.StatusOK, "index.html", gmap)

	return s.FeatureTour(c)
}

func (s *Service) PricingList(c echo.Context) error {


@@ 429,9 377,57 @@ func (s *Service) PricingList(c echo.Context) error {

func (s *Service) FeatureTour(c echo.Context) error {
	lt := localizer.GetSessionLocalizer(c)
	pd := localizer.NewPageData(lt.Translate("Explore Features"))
	pd.Data["organize_bookmarks"] = lt.Translate("Organize bookmarks")
	pd.Data["short_links"] = lt.Translate("Short Links")

	pd := localizer.NewPageData(
		lt.Translate("Social bookmarking plus link sharing, shortening and listings all in one app."),
	)
	pd.Data["welcome"] = lt.Translate("Welcome to LinkTaco!")
	pd.Data["line1"] = lt.Translate(
		"Here you can mix all your link saving and sharing needs in one " +
			"tight little bundle. Much like a taco. A link taco if you will.",
	)
	pd.Data["line2"] = lt.Translate(
		"LinkTaco is an open source platform where you can host all of your links. " +
			"Custom domains, QR codes, Analytics, full API, multiple organizations w/" +
			"unlimited members are just some of what's included.",
	)
	pd.Data["line4"] = lt.Translate(
		"Social bookmarking is not new, it's just been forgotten. Link shortening with " +
			"analytics has been around forever. Link listings became cool once social media " +
			"started allowing us to post a link to our websites in our profiles.",
	)
	pd.Data["line5"] = lt.Translate(
		"Up until now, all of these things were hosted on different services.",
	)
	pd.Data["pinboard"] = lt.Translate("Social bookmarking: Pinboard (Delicious)")
	pd.Data["bitly"] = lt.Translate("Link shortening: Bitly et al")
	pd.Data["linktree"] = lt.Translate("Link listings: Linktree et al")
	pd.Data["line3"] = lt.Translate("Peace Pinboard. Bye Bitly. Later Linktree. Hello LinkTaco!")

	repo := "https://code.netlandish.com/~netlandish/links"
	pd.Data["line7a"] = lt.Translate("Since we're a")
	pd.Data["line7b"] = lt.Translate("100%% open source project")
	pd.Data["line7c"] = lt.Translate(" you can host your own instance if you'd " +
		"like full control over your own platform. See the install docs for more.",
	)
	pd.Data["line8"] = lt.Translate(
		"Ready to get started? It's free to make an account and use it forever (with " +
			"some limitations). To use all features you have to pay just a few bucks a year, " +
			"or a few per month if you're a business, and that's it. Simple!",
	)

	pd.Data["login"] = lt.Translate("Login")
	pd.Data["email_address"] = lt.Translate("Email Address")
	pd.Data["password"] = lt.Translate("Password")
	pd.Data["forgot_password"] = lt.Translate("Forgot Password?")
	pd.Data["login"] = lt.Translate("Login")
	pd.Data["no_accounts"] = lt.Translate("No accounts? Click here to create one")

	pd.Data["explore"] = lt.Translate("Explore Features")

	// pd := localizer.NewPageData(lt.Translate("Explore Features"))
	pd.Data["organize_bookmarks"] = lt.Translate("Organize Bookmarks")
	pd.Data["short_links"] = lt.Translate("Link Shortening")
	pd.Data["link_lists"] = lt.Translate("Link Lists")
	pd.Data["collaboration"] = lt.Translate("Collaboration")
	pd.Data["integrations"] = lt.Translate("Integrations")


@@ 455,7 451,7 @@ func (s *Service) FeatureTour(c echo.Context) error {
	pd.Data["feature_link_short_3"] = lt.Translate("Filter/Search shorts")
	pd.Data["feature_link_short_4"] = lt.Translate("Unlimited QR codes per short")

	pd.Data["feature_link_listings_1"] = lt.Translate("Create link listings (ie, social media bios, etc.)")
	pd.Data["feature_link_listings_1"] = lt.Translate("Unlimited link listings (for social media bios, etc.)")
	pd.Data["feature_link_listings_2"] = lt.Translate("Organize listings by tag")
	pd.Data["feature_link_listings_3"] = lt.Translate("Filter/Search listings")
	pd.Data["feature_link_listings_4"] = lt.Translate("Unlimited QR codes per listing")


@@ 486,25 482,22 @@ func (s *Service) FeatureTour(c echo.Context) error {
	pd.Data["feature_analytics_6"] = lt.Translate("City analytics")
	pd.Data["feature_analytics_7"] = lt.Translate("Device analytics")

	pd.Data["slack_integration"] = lt.Translate("Slack integration")
	pd.Data["mattermost"] = lt.Translate("Mattermost")
	pd.Data["use_external_tools"] = lt.Translate("Use external tools to access your account")

	pd.Data["import_pinboard"] = lt.Translate("Import from Pinboard, Chrome, Firefox, Safari")
	pd.Data["export_json"] = lt.Translate("Export in JSON or HTML format")
	pd.Data["widget"] = lt.Translate("Browser bookmark widget")

	url := links.GetLinksDomainURL(c)
	url.Path = c.Echo().Reverse("core:feature_tour")
	// XXX Remove in the future. Testing combined feature/index page
	//url := links.GetLinksDomainURL(c)
	//url.Path = c.Echo().Reverse("core:feature_tour")
	seoData := links.GetSEOData(c)
	seoData.Title = pd.Title
	seoData.Description = lt.Translate("All feature details for LinkTaco.com")
	seoData.Keywords = lt.Translate("features, pricing, links, linktaco, feature, plans, pricing plans")
	seoData.URL = url.String()
	seoData.TwitterURL = url.String()
	//seoData.Title = pd.Title
	//seoData.Description = lt.Translate("All feature details for LinkTaco.com")
	//seoData.Keywords = lt.Translate("features, pricing, links, linktaco, feature, plans, pricing plans")
	//seoData.URL = url.String()
	//seoData.TwitterURL = url.String()

	gmap := gobwebs.Map{
		"pd":      pd,
		"seoData": seoData,
		"repo":    repo,
	}
	return links.Render(c, http.StatusOK, "feature_tour.html", gmap)
}


@@ 3742,7 3735,7 @@ func SwiftLang(c echo.Context) error {
	}
	refer := c.Request().Header.Get("Referer")
	if refer == "" {
		refer = c.Echo().Reverse("index")
		refer = c.Echo().Reverse("core:index")
	}
	return c.Redirect(http.StatusMovedPermanently, refer)
}

M helpers.go => helpers.go +2 -2
@@ 1015,8 1015,8 @@ func GetSEOData(c echo.Context) *SEOData {
	seoData := &SEOData{
		Title: lt.Translate("Social bookmarking plus link sharing, shortening and listings all in one app."),
		Description: lt.Translate(
			"Welcome to LinkTaco. Where you can mix all your link saving and sharing needs in one " +
				"tight little bundle. Much like a taco. A link taco if you will.",
			"Welcome to LinkTaco! Here you can mix all your link saving and sharing needs in " +
				"one tight little bundle. Much like a taco. A link taco if you will.",
		),
		Keywords:        lt.Translate("social bookmarks, bookmarking, links, link sharing, link shortening, link listings, bookmarks, link saving, qr codes, analytics"),
		URL:             url.String(),

M templates/base.html => templates/base.html +2 -2
@@ 68,7 68,7 @@
            <ul class="list-unstyled pl-0">
                {{if not .isAuthenticated}}
                <li>
                    <a class="menu-item{{if eq .navFlag "tour"}} menu-item--active{{end}}" href="{{reverse "core:feature_tour"}}">
                    <a class="menu-item{{if eq .navFlag "tour"}} menu-item--active{{end}}" href="{{reverse "core:index"}}#features">
                        <svg class="menu-item__icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 7.125C2.25 6.504 2.754 6 3.375 6h6c.621 0 1.125.504 1.125 1.125v3.75c0 .621-.504 1.125-1.125 1.125h-6a1.125 1.125 0 0 1-1.125-1.125v-3.75ZM14.25 8.625c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v8.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 0 1-1.125-1.125v-8.25ZM3.75 16.125c0-.621.504-1.125 1.125-1.125h5.25c.621 0 1.125.504 1.125 1.125v2.25c0 .621-.504 1.125-1.125 1.125h-5.25a1.125 1.125 0 0 1-1.125-1.125v-2.25Z" />
                        </svg>


@@ 251,7 251,7 @@
        </label>
        <ul class="menu">
            {{if not .isAuthenticated}}
                <li><a class="{{if eq .navFlag "tour"}} menu-item--active{{end}}" href="{{reverse "core:feature_tour"}}">{{.base_pd.Data.tour}}</a></li>
                <li><a class="{{if eq .navFlag "tour"}} menu-item--active{{end}}" href="{{reverse "core:index"}}#features">{{.base_pd.Data.tour}}</a></li>
                <li><a class="{{if eq .navFlag "pricing"}} menu-item--active{{end}}" href="{{reverse "core:pricing_list"}}">{{.base_pd.Data.pricing}}</a></li>
                <li><a class="{{if eq .navFlag "recent"}} menu-item--active{{end}}" href="{{reverse "core:recent_link_list"}}">{{.base_pd.Data.recent}}</a></li>
                <li><a class="{{if eq .navFlag "popular"}} menu-item--active{{end}}" href="{{reverse "core:popular_link_list"}}">{{.base_pd.Data.popular}}</a></li>

M templates/feature_tour.html => templates/feature_tour.html +90 -31
@@ 1,24 1,74 @@
{{template "base" .}}
{{ define "title" }}{{ .pd.Title }}{{ end }}
<section class="app-header">
  <h1 class="app-header__title">{{.pd.Title}}</h1>
  <h1 class="app-header__title"></h1>
</section>

<section class="card shadow-card">
    <div class="tour-intro">
<div class="row">
  <section class="col-8">
    <h2>{{.pd.Data.welcome}}</h2>
    <p>{{.pd.Data.line1}}</p>
    <p>{{.pd.Data.line2}}</p>
    <p>{{.pd.Data.line4}}</p>
    <p>{{.pd.Data.line5}}</p>
    <p>
      <ul>
        <li>{{.pd.Data.pinboard}}</li>
        <li>{{.pd.Data.bitly}}</li>
        <li>{{.pd.Data.linktree}}</li>
      </ul>
    </p>
    <p>{{.pd.Data.line3}}</p>
    <p>{{.pd.Data.line7a}} <a href="{{ .repo }}" target="_blank">{{ .pd.Data.line7b }}</a> {{ .pd.Data.line7c }}</p>
    <p>{{.pd.Data.line8}}</p>
  </section>
  <section class="col-4">
    <div class="card shadow-card">
      <header>
        <h2>{{ .pd.Data.login }}</h2>
      </header>
      <form method="post" action="{{ reverse "accounts:login_post"}}">
        <input type="hidden" name="csrf" value="{{ .CSRF }}">
        <input type="hidden" name="next" value="{{ .next }}">
        {{ if .errors._global_ -}}
        {{- range .errors._global_ -}}
        <p class="error">{{ . }}</p>
        {{- end }}
        {{- end }}
        <div>
          <label>{{ .pd.Data.email_address}}</label>
          <input type="email" name="email" value="{{ if .form.Email }}{{ .form.Email }}{{ end }}" required>
          {{ with .errors.Email }}
          <p class="error">{{ . }}</p>
          {{ end }}
        </div>
        <div>
          <label>{{.pd.Data.password}}</label>
          <input type="password" name="password" required>
          {{ with .errors.Password }}
          <p class="error">{{ . }}</p>
          {{ end }}
        </div>
        <div class="is-right">
          <input type="submit" value="{{.pd.Data.login}}" class="button dark">
        </div>
      </form>
      <footer>
        <p>
          <a href="{{ reverse "accounts:forgot_password" }}">{{.pd.Data.forgot_password}}</a>
        </p>
        <p>
            <strong>Welcome to Link Taco</strong>
            lorem ipsum dolor sit, amet consectetur adipisicing elit. Consequuntur fugiat sunt harum
            quia aliquid ipsum eligendi ad atque quasi maiores cumque, facere voluptatem debitis ea
            placeat illo? Atque, aperiam placeat.
          <a href="{{ reverse "accounts:register"}}">{{.pd.Data.no_accounts}}</a>
        </p>
        <ul>
            <li>Lorem ipsum dolor sit, amet</li>
            <li>consectetur adipisicing elit.</li>
            <li>Consequuntur fugiat sunt</li>
            <li>eligendi ad atque quasi maiores cumque</li>
        </ul>
        <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Consequuntur fugiat sunt harum</p>
      </footer>
    </div>
  </section>
</div>

<section class="card shadow-card">
    <div class="tour-intro">
    	<a name="features"></a>
        <h3>{{ .pd.Data.explore }}</h3>
    </div>
    <div class="tour-section row">
        <div class="col-8">


@@ 35,6 85,7 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{ staticURL "img/web/lt_bookmarks_small.png" }}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 51,6 102,7 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_linkshortening_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 67,6 119,25 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_linklistings_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">
        <div class="col-8">
            <h3 class="tour-title">{{.pd.Data.analytics}}</h3>
            <ul>
                <li>{{.pd.Data.feature_analytics_1}}</li>
                <li>{{.pd.Data.feature_analytics_2}}</li>
                <li>{{.pd.Data.feature_analytics_3}}</li>
                <li>{{.pd.Data.feature_analytics_4}}</li>
                <li>{{.pd.Data.feature_analytics_5}}</li>
                <li>{{.pd.Data.feature_analytics_6}}</li>
                <li>{{.pd.Data.feature_analytics_7}}</li>
            </ul>
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_analytics_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 80,6 151,7 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_collaborate_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 88,11 160,13 @@
            <ul>
                <li>{{.pd.Data.feature_collab_integrat_2}}</li>
                <li>{{.pd.Data.feature_collab_integrat_3}}</li>
                <li>{{.pd.Data.widget}}</li>
                <li>{{.pd.Data.feature_collab_integrat_4}}</li>
            </ul>
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_integrations_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 107,6 181,7 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_graphql_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
    <div class="tour-section row">


@@ 122,23 197,7 @@
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_import_small.png"}}"/>
        </div>
    </div>
    <div class="tour-section row">
        <div class="col-8">
            <h3 class="tour-title">{{.pd.Data.analytics}}</h3>
            <ul>
                <li>{{.pd.Data.feature_analytics_1}}</li>
                <li>{{.pd.Data.feature_analytics_2}}</li>
                <li>{{.pd.Data.feature_analytics_3}}</li>
                <li>{{.pd.Data.feature_analytics_4}}</li>
                <li>{{.pd.Data.feature_analytics_5}}</li>
                <li>{{.pd.Data.feature_analytics_6}}</li>
                <li>{{.pd.Data.feature_analytics_7}}</li>
            </ul>
        </div>
        <div class="col-4">
            <img class="tour-section-img" src="{{staticURL "img/web/lt_analytics_small.png"}}"/>
	    <p align="center">(click to expand)</p>
        </div>
    </div>
</section>