[Ignite]SwiftUIでWebサイトを開発する
try! Swift Tokyo 2024に参加しました!
その中のSwiftで次世代のウェブサイトを構築しよう
のセッションでIgniteという、
SwiftUIのコードからHTMLやCSSを生成できる静的サイトジェネレーターが紹介されていました。
今回はIgniteを使用したWebサイトの開発方法を紹介します。
1. プロジェクトの作成
XcodeのFile -> New -> Package -> macOS -> Command-Line Toolで新規プロジェクトを作成します。
今後RyoDeveloperSite
の文字が出てきたときは、自分のプロジェクト名に置き換えて読んでください。
2. Igniteの追加
IgniteはSwift Package Managerを使って追加できます。
Package.swiftを下記のように書き換えます。
import PackageDescription
let package = Package(
name: "RyoDeveloperSite",
platforms: [.macOS(.v13)],
dependencies: [
.package(url: "https://github.com/twostraws/Ignite.git", branch: "main"),
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.executableTarget(
name: "RyoDeveloperSite",
dependencies: ["Ignite"]
),
]
)
BuildするとPackageが追加されます。
3. サイトの生成
Hello, world!
を表示してみます。
ファイルはSouresのフォルダー内に追加してください。
import Foundation
import Ignite
struct Home: StaticPage {
var title = "RyoDeveloper"
func body(context: PublishingContext) -> [BlockElement] {
Text("Hello, world!")
.font(.title1)
}
}
Themeを追加します。
ThemeではCSSの適応やHeaderやFooterの追加などを行っています。
Header, Footerについては後の章で紹介します。
import Foundation
import Ignite
struct MyTheme: Theme {
func render(page: Page, context: PublishingContext) -> HTML {
HTML {
Head(for: page, in: context)
Body {
page.body
}
}
}
}
Siteを追加します。
import Foundation
import Ignite
struct MySite: Site {
var name = "RyoDeveloper"
var url = URL("https://ryodeveloper.com") // Base URL
var author = "RyoDeveloper"
var language = Language.japanese
var homePage = Home() // Root domainのPage
var theme = MyTheme()
var pages: [any StaticPage] {
Home()
}
}
エントリーポイントを修正します。
import Foundation
import Ignite
@main
struct RyoDeveloperSite {
static func main() {
let site = MySite()
do {
try site.publish()
} catch {
print(error.localizedDescription)
}
}
}
プロジェクトの配下にAssets
というフォルダーを追加します。
XcodeでBuildをするとAlertが表示されるので許可をクリックします。
プロジェクトの配下にBuild
というフォルダーが生成され、その中にHTMLやCSSが出力されます。
ここまでで、サイトの生成が完了しました。
4. サイトの確認
ローカルサーバーを立てて、正しくサイトが動作するか確認してみます。
HomebrewでPythonをインストールします。
brew install python
先ほど生成されたBuild
のディレクトリで、サーバーを立ち上げます。
python3 -m http.server 8888
http://localhost:8888
にアクセスすることでプレビューを見ることができます。
無事にHello, world!
の表示を確認できました。
4. HeaderとFooterの作成
Headerから他のPageに遷移できるようにします。
遷移先のPageを作ります。
今回は、Assetsフォルダーに追加したFujimiIcon.svg
を表示してみます。
import Foundation
import Ignite
struct Fujimi: StaticPage {
var title = "Fujimi"
func body(context: PublishingContext) -> [BlockElement] {
Image("/FujimiIcon.svg")
.resizable()
.frame(width: 100)
}
}
MySiteのpagesに今作成したFujimi()
を追加します。
struct MySite: Site {
var name = "RyoDeveloper"
var url = URL("https://ryodeveloper.com") // Base URL
var author = "RyoDeveloper"
var language = Language.japanese
var homePage = Home() // Root domainのPage
var theme = MyTheme()
var pages: [any StaticPage] {
Home()
+ Fujimi()
}
}
Headerを作成します。
import Foundation
import Ignite
struct Header: Component {
func body(context: PublishingContext) -> [any PageElement] {
NavigationBar(logo: "RyoDeveloper") {
Link("Fujimi", target: Fujimi())
}
.backgroundColor(.whiteSmoke)
.position(.fixedTop)
}
}
MainThemeにHeader()を追加します。
struct MainTheme: Theme {
func render(page: Page, context: PublishingContext) -> HTML {
HTML {
Head(for: page, in: context)
Body {
+ Header()
page.body
}
+ .padding(.vertical, 80)
}
}
}
Home | Fujimi |
---|---|
Footerも同じ要領で自由なデザインを追加できます。
今回は応援の意味も込めて、デフォルトで入っているIgniteFooter()
を追加してみます。
/// Displays "Created by Ignite", with a link back to the Ignite project on GitHub.
/// Including this is definitely not required for your site, but it's most appreciated 🙌
struct MainTheme: Theme {
func render(page: Page, context: PublishingContext) -> HTML {
HTML {
Head(for: page, in: context)
Body {
Header()
page.body
IgniteFooter()
}
.padding(.vertical, 80)
}
}
}
後は、下記のURLを参考に自由にコンポーネントを追加するだけです。
Discussion