Custom page link texts, optional post title
This commit is contained in:
parent
1f7167b076
commit
2a50773e2f
@ -43,11 +43,10 @@ final class PostListPageGenerator {
|
||||
private func makePostData(post: Post) -> FeedEntryData {
|
||||
let localized: LocalizedPost = post.localized(in: language)
|
||||
|
||||
#warning("Add post link text to settings or to each post")
|
||||
let linkUrl = post.linkedPage.map {
|
||||
FeedEntryData.Link(
|
||||
url: $0.absoluteUrl(in: language),
|
||||
text: language == .english ? "View" : "Anzeigen")
|
||||
text: localized.pageLinkText ?? post.content.settings.localized(in: language).defaultPageLinkText)
|
||||
}
|
||||
|
||||
// Use the tags of the page if one is linked
|
||||
@ -69,6 +68,7 @@ final class PostListPageGenerator {
|
||||
tags: tags,
|
||||
text: localized.text.components(separatedBy: "\n\n"),
|
||||
images: images)
|
||||
#warning("Treat post text as markdown")
|
||||
}
|
||||
|
||||
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>) {
|
||||
@ -89,6 +89,7 @@ final class PostListPageGenerator {
|
||||
totalPages: pageCount,
|
||||
languageButtonUrl: languageButtonUrl,
|
||||
linkPrefix: source.pageUrlPrefix(for: language))
|
||||
// Includes leading slash
|
||||
let filePath = pageUrl(in: language, pageNumber: pageIndex) + ".html"
|
||||
guard save(fileContent, to: filePath) else {
|
||||
source.results.unsavedOutput(filePath, source: .feed)
|
||||
|
@ -13,18 +13,6 @@ extension Content {
|
||||
originalUrl: tag.originalURL)
|
||||
}
|
||||
|
||||
private func convert(_ post: LocalizedPostFile, images: [String : FileResource]) -> LocalizedPost {
|
||||
LocalizedPost(
|
||||
content: self,
|
||||
title: post.title,
|
||||
text: post.content,
|
||||
lastModified: post.lastModifiedDate,
|
||||
images: post.images.compactMap { images[$0] },
|
||||
linkPreviewImage: post.linkPreviewImage.map { images[$0] },
|
||||
linkPreviewTitle: post.linkPreviewTitle,
|
||||
linkPreviewDescription: post.linkPreviewDescription)
|
||||
}
|
||||
|
||||
private func convert(_ page: LocalizedPageFile, images: [String : FileResource]) -> LocalizedPage {
|
||||
LocalizedPage(
|
||||
content: self,
|
||||
@ -96,8 +84,8 @@ extension Content {
|
||||
let posts: [String : Post] = postsData.reduce(into: [:]) { dict, data in
|
||||
let (postId, post) = data
|
||||
let linkedPage = post.linkedPageId.map { pages[$0] }
|
||||
let german = convert(post.german, images: images)
|
||||
let english = convert(post.english, images: images)
|
||||
let german = LocalizedPost(content: self, file: post.german, images: images)
|
||||
let english = LocalizedPost(content: self, file: post.english, images: images)
|
||||
|
||||
dict[postId] = Post(
|
||||
content: self,
|
||||
|
@ -83,16 +83,3 @@ private extension Post {
|
||||
linkedPageId: linkedPage?.id)
|
||||
}
|
||||
}
|
||||
|
||||
private extension LocalizedPost {
|
||||
|
||||
var postFile: LocalizedPostFile {
|
||||
.init(images: images.map { $0.id },
|
||||
title: title.nonEmpty,
|
||||
content: text,
|
||||
lastModifiedDate: lastModified,
|
||||
linkPreviewImage: linkPreviewImage?.id,
|
||||
linkPreviewTitle: linkPreviewTitle,
|
||||
linkPreviewDescription: linkPreviewDescription)
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ extension LocalizedItem {
|
||||
|
||||
func localized(in language: ContentLanguage) -> Localized {
|
||||
switch language {
|
||||
case .german: return german
|
||||
case .english: return english
|
||||
case .german: german
|
||||
case .english: english
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ final class LocalizedPost: ObservableObject {
|
||||
unowned let content: Content
|
||||
|
||||
@Published
|
||||
var title: String
|
||||
var title: String?
|
||||
|
||||
@Published
|
||||
var text: String
|
||||
@ -17,6 +17,10 @@ final class LocalizedPost: ObservableObject {
|
||||
@Published
|
||||
var images: [FileResource]
|
||||
|
||||
/// The text to show for the link to the `linkedPage`
|
||||
@Published
|
||||
var pageLinkText: String?
|
||||
|
||||
@Published
|
||||
var linkPreviewImage: FileResource?
|
||||
|
||||
@ -31,18 +35,50 @@ final class LocalizedPost: ObservableObject {
|
||||
text: String,
|
||||
lastModified: Date? = nil,
|
||||
images: [FileResource] = [],
|
||||
pageLinkText: String? = nil,
|
||||
linkPreviewImage: FileResource? = nil,
|
||||
linkPreviewTitle: String? = nil,
|
||||
linkPreviewDescription: String? = nil) {
|
||||
self.content = content
|
||||
self.title = title ?? ""
|
||||
self.title = title
|
||||
self.text = text
|
||||
self.lastModified = lastModified
|
||||
self.images = images
|
||||
self.pageLinkText = pageLinkText
|
||||
self.linkPreviewImage = linkPreviewImage
|
||||
self.linkPreviewTitle = linkPreviewTitle
|
||||
self.linkPreviewDescription = linkPreviewDescription
|
||||
}
|
||||
|
||||
init(content: Content, file: LocalizedPostFile, images: [String : FileResource]) {
|
||||
self.content = content
|
||||
self.title = file.title
|
||||
self.text = file.content
|
||||
self.lastModified = file.lastModifiedDate
|
||||
self.images = file.images.compactMap { images[$0] }
|
||||
self.pageLinkText = file.pageLinkText
|
||||
self.linkPreviewImage = file.linkPreviewImage.map { images[$0] }
|
||||
self.linkPreviewTitle = file.linkPreviewTitle
|
||||
self.linkPreviewDescription = file.linkPreviewDescription
|
||||
}
|
||||
|
||||
var postFile: LocalizedPostFile {
|
||||
.init(images: images.map { $0.id },
|
||||
title: title,
|
||||
content: text,
|
||||
lastModifiedDate: lastModified,
|
||||
pageLinkText: pageLinkText,
|
||||
linkPreviewImage: linkPreviewImage?.id,
|
||||
linkPreviewTitle: linkPreviewTitle,
|
||||
linkPreviewDescription: linkPreviewDescription)
|
||||
}
|
||||
|
||||
func contains(_ string: String) -> Bool {
|
||||
if let title, title.contains(string) {
|
||||
return true
|
||||
}
|
||||
return text.contains(string)
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedPost: LinkPreviewItem {
|
||||
|
@ -107,11 +107,17 @@ final class Post: Item {
|
||||
tags.append(tag)
|
||||
}
|
||||
|
||||
func localized(in language: ContentLanguage) -> LocalizedPost {
|
||||
switch language {
|
||||
case .english: return english
|
||||
case .german: return german
|
||||
}
|
||||
/**
|
||||
A title for the UI, not the generation.
|
||||
*/
|
||||
override func title(in language: ContentLanguage) -> String {
|
||||
localized(in: language).title ?? id
|
||||
}
|
||||
|
||||
func contains(_ string: String) -> Bool {
|
||||
id.contains(string) ||
|
||||
german.contains(string) ||
|
||||
english.contains(string)
|
||||
}
|
||||
|
||||
func isValid(id: String) -> Bool {
|
||||
@ -134,3 +140,7 @@ final class Post: Item {
|
||||
extension Post: DateItem {
|
||||
|
||||
}
|
||||
|
||||
extension Post: LocalizedItem {
|
||||
|
||||
}
|
||||
|
@ -11,10 +11,14 @@ final class LocalizedPostSettings: ObservableObject {
|
||||
@Published
|
||||
var feedUrlPrefix: String
|
||||
|
||||
init(title: String, description: String, feedUrlPrefix: String) {
|
||||
@Published
|
||||
var defaultPageLinkText: String
|
||||
|
||||
init(title: String, description: String, feedUrlPrefix: String, defaultPageLinkText: String) {
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.feedUrlPrefix = feedUrlPrefix
|
||||
self.defaultPageLinkText = defaultPageLinkText
|
||||
}
|
||||
|
||||
// MARK: Storage
|
||||
@ -23,12 +27,14 @@ final class LocalizedPostSettings: ObservableObject {
|
||||
self.title = file.feedTitle
|
||||
self.description = file.feedDescription
|
||||
self.feedUrlPrefix = file.feedUrlPrefix
|
||||
self.defaultPageLinkText = file.defaultPageLinkText ?? "View"
|
||||
}
|
||||
|
||||
var file: LocalizedPostSettingsFile {
|
||||
.init(
|
||||
feedTitle: title,
|
||||
feedDescription: description,
|
||||
feedUrlPrefix: feedUrlPrefix)
|
||||
feedUrlPrefix: feedUrlPrefix,
|
||||
defaultPageLinkText: defaultPageLinkText)
|
||||
}
|
||||
}
|
||||
|
@ -27,13 +27,15 @@ extension LocalizedPostSettings {
|
||||
.init(
|
||||
title: "Titel",
|
||||
description: "Beschreibung",
|
||||
feedUrlPrefix: "blog")
|
||||
feedUrlPrefix: "blog",
|
||||
defaultPageLinkText: "Anzeigen")
|
||||
}
|
||||
|
||||
static var english: LocalizedPostSettings {
|
||||
.init(
|
||||
title: "A Title",
|
||||
description: "Description",
|
||||
feedUrlPrefix: "feed")
|
||||
feedUrlPrefix: "feed",
|
||||
defaultPageLinkText: "View")
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ struct LocalizedPostFile {
|
||||
|
||||
let lastModifiedDate: Date?
|
||||
|
||||
let pageLinkText: String?
|
||||
|
||||
let linkPreviewImage: String?
|
||||
|
||||
let linkPreviewTitle: String?
|
||||
|
@ -9,6 +9,13 @@ struct LocalizedPostSettingsFile {
|
||||
|
||||
/// The path to the feed in the final website, appended with the page number
|
||||
let feedUrlPrefix: String
|
||||
|
||||
/**
|
||||
The text to display when linking to a page
|
||||
|
||||
Each post may define a custom text.
|
||||
*/
|
||||
let defaultPageLinkText: String?
|
||||
}
|
||||
|
||||
extension LocalizedPostSettingsFile: Codable { }
|
||||
@ -18,6 +25,7 @@ extension LocalizedPostSettingsFile {
|
||||
static var `default`: LocalizedPostSettingsFile {
|
||||
.init(feedTitle: "A title",
|
||||
feedDescription: "A description",
|
||||
feedUrlPrefix: "blog")
|
||||
feedUrlPrefix: "blog",
|
||||
defaultPageLinkText: "View")
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ struct LocalizedPostDetailView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
OptionalStringPropertyView(
|
||||
title: "Custom Page Link Text",
|
||||
text: $post.pageLinkText,
|
||||
footer: "The custom text to show for the link to the linked page")
|
||||
|
||||
OptionalStringPropertyView(
|
||||
title: "Preview Title",
|
||||
text: $post.linkPreviewTitle,
|
||||
|
@ -38,7 +38,7 @@ private struct LocalizedTitle: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
TextField("", text: $post.title)
|
||||
OptionalTextField("", text: $post.title)
|
||||
.font(.system(size: 24, weight: .bold))
|
||||
.foregroundStyle(Color.primary)
|
||||
.textFieldStyle(.plain)
|
||||
|
@ -22,7 +22,7 @@ struct PostListView: View {
|
||||
guard !searchString.isEmpty else {
|
||||
return content.posts
|
||||
}
|
||||
return content.posts.filter { $0.localized(in: language).title.contains(searchString) }
|
||||
return content.posts.filter { $0.contains(searchString) }
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
@ -31,7 +31,7 @@ struct PostListView: View {
|
||||
.textFieldStyle(.roundedBorder)
|
||||
.padding(.horizontal, 8)
|
||||
List(filteredPosts, selection: $selectedPost) { post in
|
||||
Text(post.localized(in: language).title).tag(post)
|
||||
Text(post.title(in: language)).tag(post)
|
||||
}
|
||||
}.onAppear {
|
||||
if selectedPost == nil {
|
||||
|
@ -7,6 +7,11 @@ struct LocalizedPostFeedSettingsView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
StringPropertyView(
|
||||
title: "Default Page Link Text",
|
||||
text: $settings.defaultPageLinkText,
|
||||
footer: "The text to display when linking from a post to a page. Each post can provide a custom text.")
|
||||
|
||||
StringPropertyView(
|
||||
title: "Title",
|
||||
text: $settings.title,
|
||||
|
@ -17,7 +17,7 @@ private struct PostSelectionView: View {
|
||||
let isSelected = post.contains(tag)
|
||||
Image(systemSymbol: isSelected ? .checkmarkCircleFill : .circle)
|
||||
.foregroundStyle(Color.blue)
|
||||
Text(post.localized(in: language).title)
|
||||
Text(post.title(in: language))
|
||||
}
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
|
@ -39,7 +39,7 @@ struct TagContentView: View {
|
||||
}
|
||||
Section("Posts") {
|
||||
ForEach(selectedPosts) { post in
|
||||
Text(post.localized(in: language).title)
|
||||
Text(post.title(in: language))
|
||||
}
|
||||
Button(action: { showPostSelection = true }) {
|
||||
Text("Select posts")
|
||||
|
Loading…
x
Reference in New Issue
Block a user