Kanagawa.swiftのWebページをIgniteで作ってみた!
最近\(region).swiftの流れから、私も知り合いのエンジニアと一緒に地元の神奈川県で、Kanagawa.swiftをすることになりました
そこで色々情報をまとめるために、最初はSwift DocCを使おうかと思いましたが、同じ運営のIgniteに詳しいエンジニアの方が、「Igniteで作るのはどうですか?」と言っていたので、try!Swiftでもセッションがあったし、気になってはいたので、Igniteで作ることにしました!
この記事では今回初めてIgniteを触った自分が困ったところや気になったところなどを備忘録として残します
Igniteとは?
IgniteとはSwiftで書くことができる静的Webサイトのビルダーのframeworkです
Ignite側でTextやImage、NavigationBarなどいくつかコンポーネント(Element)が用意されていて通常のSwiftUIのViewを同じように書くことができます(以下、公式ページから引用)
resultBuilderが使われていて、宣言的に書くことができます
Text("Swift rocks")
.font(.title1)
Text(markdown: "Add *inline* Markdown")
.foregroundStyle(.secondary)
Link("Swift", target: "https://www.swift.org")
.linkStyle(.button)
Divider()
Image("logo.jpg")
.accessibilityLabel("The Swift logo.")
.padding()
Igniteのセットアップや基本的な使い方は公式サイトや参考サイトを確認してください
- Ignite公式ページ
- Ignite Example Site
- [Ignite]SwiftUIでWebサイトを開発する
- Swiftで始めるWeb開発(2) 静的サイトジェネレータIgniteを用いてWebページを構築する
Kanagawa.swiftのWebサイトの仕組み
ではKanagawa.swiftのWebサイトがどんな仕組みになっているかを確認しましょう
Webサイトのコードは、GitHubにアップロードされていて、GitHub PagesにHostingしています
まず画面上部にはNavigationBarを配置し、その中にイベントページなどの外部サイトへのリンク、同じページのセクションへのリンク、日本語↔︎英語を切り替えるボタンが配置されています
その下には以下を表示しています
- 神奈川県のいくつかの場所で撮影した写真を表示するためのカルーセル
- Kanagawa.swiftの説明
- イベントリスト
- 運営一覧
- Blogs
- \(region).swiftのコミュニティ一覧
Localize
このサイトはStaticPageというページの単位のstructを日本語用と英語用の2つ用意しています(参照)
このStaticPageのstruct名がそのままこのページのURLのpathに使用されます
そこで表示するコンテンツは共通のbaseというGroupのElementを呼び出してます
そのbaseを呼び出す際に、どの言語で表示するかのenumを渡していて、それによって、どの言語のリソースのjsonから、テキストを読み取るかを処理しています
基本的にこのページはTopページしか用意しない想定だったのでこの仕組みでも実装できますが、複数のページを実装する場合は工夫が必要かなと思います
NavigationBarからセクションへのリンクを実装する
IgniteではLinkというElementが用意されていて、基本的にタップした時にURLのページに遷移する機能を実装したい時などはこのLinkを利用します
セクションへのリンクにもこのLinkを使っています
NavigationBarのリンクを貼る箇所にLinkを使って、既存のElementをラップします
Link(target: "#\(rawValue)") {
Text(title(model: model))
.margin(.none)
.foregroundStyle(.primaryColor)
}
この時Linkのtargetに# + セクションのID、例えば、運営セクションへのリンクの場合は、#staffを指定します
そしてそのリンク先のElement、今回の場合はそのセクションのタイトルにid関数に同じ文字列を指定します(以下のコードはその文字列をenumで指定しています)
Text(navbar.organizer)
.font(.title2)
.id(NavigationOptions.staff.rawValue)
これでボタンをタップすることで、https://u5-03.github.io/kanagawa-swift/#staffのようなリンクを指定することになり、該当の運営セクションを表示することができるようになります
OGPを実装する
OGP(Open Graph Protocol)とは、TwitterやSlackなどのツールにURLを表示した時に、タイトルや画像、説明文など、そのWebサイトの補足情報を表示する仕組みです
仕組みとしては、HeaderにOGP用のMetaタグを追加すれば表示されます
Ignite自体には標準でその仕組みは用意されていないですが、ヘッダーにMetaタグをついかする仕組み自体は用意されているので、そこにタグを追加することでOGP対応をすることができます
Igniteでは、Themeの中でHeaderにタグを追加することができ、例えば以下のようにog:imageのMetaタグを追加することで、OGP用の画像を表示することができます
struct MyTheme: Theme {
func render(page: Page, context: PublishingContext) -> HTML {
HTML {
Head(for: page, in: context) {
MetaTag(name: "og:image", content: "https://u5-03.github.io/kanagawa-swift/images/regions/kanagawa.png")
MetaTag(name: "twitter:title", content: "Kanagawa.swift")
MetaTag(name: "twitter:image", content: "https://u5-03.github.io/kanagawa-swift/images/regions/kanagawa.png")
}
Body {
page.body
IgniteFooter()
}
.style("background-color: \(ColorAssets.background.rawValue)")
.padding(.top, 80)
.padding(.horizontal, 24)
}
}
}
Igniteを使ってみての感想
Swiftを使って、このようなWebサイトが簡単に実装できるのは非常に魅力的です
しかし実装してみると、そこまで細かなレイアウトやUIを作るのは現時点では難しいなと感じる部分が多かったです
例えば以下のカルーセルのUIですが、スマホサイズで表示しようとすると、UIKitやSwiftUIでいうとこの、AspectFitの状態になっているので、画像の左右が見切れてしまします
スマホの場合はAspect比を調整し、AspectFillで画像全体が表示されるようにしたかったですが、標準のCarouselではそのような機能が用意されていなかったので、現時点でその点は妥協しています
同様に運営メンバーのアイコンをタイル状に並べている箇所もスマホサイズにすると、アイコンの画像が画面幅いっぱいに表示されてしまい、想定したタイル状のUIにはならなかったです
このように細かなUIの制御やスマホ対応は現時点では難しそうで、基本的にはシンプルなテキスト中心で、部分的に画像を使うような静的サイトとして利用するのがいいかなと感じました
ただIgniteには、上記のThemeにはCSSのstyleも適用することができるので、CSSを自身で適用することで、細かなカスタマイズをすることができるかと思います(自分はそこまではやらなかったですが…)
まとめ
今回はKanagawa.swiftのWebサイトをIgniteを使って実装したことについて、まとめてみました!
Swiftは一般的にはiOSアプリやMac、VisionProなどAppleプラットフォームで動くデバイスのアプリを開発するものという認識ですが、それ以外にも今回のように静的Webサイトを生成したり、ServerSideやラズパイでも動かすことができたりと、Swiftが利用できる場面は広がっています
皆さんもぜひAppleプラットフォーム以外でのSwiftを試してみて、新しいSwiftの扉を開いてみませんか?
あとKanagawa.swiftもよろしくお願いします!