jekyll-streetview 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 743ebb835ef743e70095829170a02e537746736999edc79e6af22471507b2c69
4
+ data.tar.gz: 7e5c3317298e49775e8d1daafc5e3582a6024958dd61c6286dc6e19aec82357f
5
+ SHA512:
6
+ metadata.gz: cfeb9a0514872970f77718de17fb032d26de82efb890dcf22d46a4ca03ba6efdcb180fcece929e94f7e067c96aa18e334ce394c9ac165abb49fa2a32f247cacf
7
+ data.tar.gz: 2f9541d313802c8769ccb3e420fed4a686a801f4299cfca0632a61dbf397d0833db4b193514904953ae07a5d14e681fb1925b00d15e9689c092e0b10a5cd37ef
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] - 2026-08-20
9
+
10
+ ### Added
11
+ - Initial release
12
+ - `{% streetview %}` Liquid tag for embedding Google Street View Static API images
13
+ - Latitude/longitude direct input
14
+ - Address string geocoding via Google Geocoding API with local cache (`_streetview_cache.json`)
15
+ - Parameters: `width`, `height`, `heading`, `fov`, `pitch`, `radius`, `source`, `alt`
16
+ - Config-level defaults via `streetview:` block in `_config.yml`
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jason Chance
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # jekyll-streetview
2
+
3
+ A Jekyll plugin that adds a `{% streetview %}` Liquid tag for embedding Google Street View static images. No JavaScript required — just a responsive `<img>` tag powered by the Google Street View Static API.
4
+
5
+ ## Installation
6
+
7
+ Add the gem to your Jekyll site's `Gemfile`:
8
+
9
+ ```ruby
10
+ gem "jekyll-streetview", "~> 0.1"
11
+ ```
12
+
13
+ Then add it to the `plugins` list in `_config.yml`:
14
+
15
+ ```yaml
16
+ plugins:
17
+ - jekyll-streetview
18
+ ```
19
+
20
+ Run `bundle install` to install the gem.
21
+
22
+ ## Configuration
23
+
24
+ Add a `streetview:` block to `_config.yml` with your Google API key:
25
+
26
+ ```yaml
27
+ streetview:
28
+ key: AIzaSy...
29
+ width: 800 # optional default width
30
+ height: 400 # optional default height
31
+ fov: 90 # optional default field of view
32
+ pitch: 0 # optional default pitch
33
+ ```
34
+
35
+ Your Google API key must have the **Street View Static API** enabled. If you use address strings, it also needs the **Geocoding API** enabled.
36
+
37
+ ## Usage
38
+
39
+ ### By latitude and longitude
40
+
41
+ ```liquid
42
+ {% streetview lat=33.248329 lng=-84.263336 %}
43
+ ```
44
+
45
+ ### By address string
46
+
47
+ Pass a quoted address string and the plugin geocodes it at build time via the Google Geocoding API. Results are cached in `_streetview_cache.json`.
48
+
49
+ ```liquid
50
+ {% streetview "100 S Hill Street, Griffin, GA" %}
51
+ ```
52
+
53
+ ### Commit `_streetview_cache.json`
54
+
55
+ Commit `_streetview_cache.json` to your repo so CI builds don't re-geocode addresses on every run.
56
+
57
+ ## Parameters
58
+
59
+ All parameters are optional and override values in `_config.yml`.
60
+
61
+ | Parameter | Default | Description |
62
+ | --- | --- | --- |
63
+ | `lat` | — | Latitude (required if no address string) |
64
+ | `lng` | — | Longitude (required if no address string) |
65
+ | `width` | `800` | Image width in pixels |
66
+ | `height` | `400` | Image height in pixels |
67
+ | `heading` | auto | Camera compass heading (0-360). If omitted, Google points toward the location. |
68
+ | `fov` | `90` | Horizontal field of view in degrees (10-120). Lower = more zoom. |
69
+ | `pitch` | `0` | Camera up/down angle (-90 to 90). Positive = up, negative = down. |
70
+ | `radius` | `50` | Search radius in meters for nearest panorama |
71
+ | `source` | — | Set to `outdoor` to exclude indoor panoramas |
72
+ | `alt` | `"Street View"` | Alt text for the `<img>` tag |
73
+
74
+ ## Examples
75
+
76
+ ```liquid
77
+ {% streetview lat=33.248329 lng=-84.263336 %}
78
+
79
+ {% streetview "100 S Hill Street, Griffin, GA" heading=180 %}
80
+
81
+ {% streetview lat=33.248329 lng=-84.263336 fov=60 pitch=10 heading=90 width=1200 height=500 %}
82
+
83
+ {% streetview "City Hall, Atlanta, GA" source=outdoor alt="Atlanta City Hall" %}
84
+ ```
85
+
86
+ ## Output
87
+
88
+ The tag renders a single `<img>` element:
89
+
90
+ ```html
91
+ <img src="https://maps.googleapis.com/maps/api/streetview?location=33.248329%2C-84.263336&size=800x400&fov=90&pitch=0&radius=50&key=..." alt="Street View" width="800" height="400" class="jekyll-streetview" loading="lazy">
92
+ ```
93
+
94
+ Add styles for `.jekyll-streetview` in your site's CSS:
95
+
96
+ ```css
97
+ .jekyll-streetview {
98
+ width: 100%;
99
+ height: auto;
100
+ border-radius: 4px;
101
+ }
102
+ ```
103
+
104
+ ## Note on imagery availability
105
+
106
+ If Street View imagery is not available at the specified location, Google returns a gray placeholder image. Use a nearby address or adjust `radius` to find available coverage. You can check coverage in [Google Maps Street View](https://maps.google.com) before embedding.
107
+
108
+ ## GitHub Pages compatibility
109
+
110
+ This plugin is compatible with Jekyll sites deployed to GitHub Pages when the site is built through a custom GitHub Actions workflow.
111
+
112
+ It is not compatible with the default GitHub Pages safe-mode build, because custom plugins are not loaded there.
113
+
114
+ ## License
115
+
116
+ MIT License. See [LICENSE.txt](LICENSE.txt).
@@ -0,0 +1,126 @@
1
+ require "jekyll"
2
+ require "net/http"
3
+ require "uri"
4
+ require "json"
5
+ require "cgi"
6
+
7
+ module Jekyll
8
+ class StreetviewTag < Liquid::Tag
9
+ STREETVIEW_BASE = "https://maps.googleapis.com/maps/api/streetview"
10
+ GEOCODE_BASE = "https://maps.googleapis.com/maps/api/geocode/json"
11
+
12
+ DEFAULT_WIDTH = 800
13
+ DEFAULT_HEIGHT = 400
14
+ DEFAULT_FOV = 90
15
+ DEFAULT_PITCH = 0
16
+ DEFAULT_RADIUS = 50
17
+
18
+ def initialize(tag_name, markup, tokens)
19
+ super
20
+ @raw_markup = markup.strip
21
+ end
22
+
23
+ def render(context)
24
+ site = context.registers[:site]
25
+ config = site.config["streetview"] || {}
26
+ key = config["key"]
27
+
28
+ raise "jekyll-streetview: streetview.key is required in _config.yml" if key.nil? || key.strip.empty?
29
+
30
+ params = parse_markup(@raw_markup)
31
+
32
+ lat, lng = resolve_coordinates(params, key, site)
33
+ raise "jekyll-streetview: could not resolve coordinates from markup: #{@raw_markup}" if lat.nil?
34
+
35
+ width = (params["width"] || config["width"] || DEFAULT_WIDTH).to_i
36
+ height = (params["height"] || config["height"] || DEFAULT_HEIGHT).to_i
37
+ fov = (params["fov"] || config["fov"] || DEFAULT_FOV).to_i
38
+ pitch = (params["pitch"] || config["pitch"] || DEFAULT_PITCH).to_i
39
+ radius = (params["radius"] || config["radius"] || DEFAULT_RADIUS).to_i
40
+ heading = params["heading"] ? params["heading"].to_i : nil
41
+ source = params["source"] || config["source"]
42
+ alt = params["alt"] || "Street View"
43
+
44
+ url = build_url(lat, lng, width, height, fov, pitch, radius, heading, source, key)
45
+
46
+ %(<img src="#{url}" alt="#{CGI.escapeHTML(alt)}" width="#{width}" height="#{height}" class="jekyll-streetview" loading="lazy">)
47
+ end
48
+
49
+ private
50
+
51
+ def parse_markup(markup)
52
+ params = {}
53
+ rest = markup.dup
54
+
55
+ if rest =~ /\A["'](.+?)["']\s*(.*)\z/m
56
+ params["address"] = Regexp.last_match(1)
57
+ rest = Regexp.last_match(2)
58
+ end
59
+
60
+ rest.scan(/(\w+)=("([^"]*?)"|'([^']*?)'|(\S+))/) do |key, _full, dq, sq, bare|
61
+ params[key] = dq || sq || bare
62
+ end
63
+
64
+ params
65
+ end
66
+
67
+ def resolve_coordinates(params, key, site)
68
+ return [params["lat"].to_f, params["lng"].to_f] if params["lat"] && params["lng"]
69
+ return geocode(params["address"], key, site) if params["address"]
70
+ [nil, nil]
71
+ end
72
+
73
+ def geocode(address, key, site)
74
+ cache_key = address
75
+ cache = load_cache(site)
76
+ return cache[cache_key] if cache.key?(cache_key)
77
+
78
+ uri = URI.parse("#{GEOCODE_BASE}?address=#{URI.encode_www_form_component(address)}&key=#{key}")
79
+ response = Net::HTTP.get_response(uri)
80
+ raise "jekyll-streetview: geocoding failed (#{response.code}) for: #{address}" unless response.is_a?(Net::HTTPSuccess)
81
+
82
+ data = JSON.parse(response.body)
83
+ results = data["results"]
84
+ raise "jekyll-streetview: no geocoding results for: #{address}" if results.nil? || results.empty?
85
+
86
+ loc = results.first["geometry"]["location"]
87
+ result = [loc["lat"].round(6), loc["lng"].round(6)]
88
+ save_cache(site, cache.merge(cache_key => result))
89
+ result
90
+ end
91
+
92
+ def build_url(lat, lng, width, height, fov, pitch, radius, heading, source, key)
93
+ params = {
94
+ location: "#{lat},#{lng}",
95
+ size: "#{width}x#{height}",
96
+ fov: fov,
97
+ pitch: pitch,
98
+ radius: radius,
99
+ key: key
100
+ }
101
+ params[:heading] = heading if heading
102
+ params[:source] = source if source && !source.empty?
103
+
104
+ query = params.map { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
105
+ "#{STREETVIEW_BASE}?#{query}"
106
+ end
107
+
108
+ def cache_path(site)
109
+ File.join(site.source, "_streetview_cache.json")
110
+ end
111
+
112
+ def load_cache(site)
113
+ path = cache_path(site)
114
+ return {} unless File.exist?(path)
115
+ JSON.parse(File.read(path))
116
+ rescue JSON::ParserError
117
+ {}
118
+ end
119
+
120
+ def save_cache(site, cache)
121
+ File.write(cache_path(site), JSON.pretty_generate(cache))
122
+ end
123
+ end
124
+ end
125
+
126
+ Liquid::Template.register_tag("streetview", Jekyll::StreetviewTag)
@@ -0,0 +1,5 @@
1
+ module Jekyll
2
+ module Streetview
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ require "jekyll"
2
+ require_relative "jekyll-streetview/version"
3
+ require_relative "jekyll/streetview_tag"
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-streetview
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Chance
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2026-08-20 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: jekyll
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '4.0'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '5.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '4.0'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '5.0'
32
+ description: jekyll-streetview adds a {% streetview %} Liquid tag to Jekyll sites.
33
+ Pass a latitude/longitude or an address string and get a static Street View image
34
+ with no JavaScript required. Powered by the Google Street View Static API.
35
+ email:
36
+ - jason@jasonchance.com
37
+ executables: []
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - CHANGELOG.md
42
+ - LICENSE.txt
43
+ - README.md
44
+ - lib/jekyll-streetview.rb
45
+ - lib/jekyll-streetview/version.rb
46
+ - lib/jekyll/streetview_tag.rb
47
+ homepage: https://jasonchance.com/projects/jekyll-streetview/
48
+ licenses:
49
+ - MIT
50
+ metadata: {}
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 2.7.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.6.2
66
+ specification_version: 4
67
+ summary: A Jekyll plugin for embedding Google Street View static images with a simple
68
+ Liquid tag.
69
+ test_files: []