Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed post and page IDs into generated HTML files and extract them in… #14

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions Apps.Wordpress/Actions/PageActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ public async Task<FileResponse> GetPageByIdAsHtml([ActionParameter] PageRequest

var html = (post.Title.Rendered, post.Content.Rendered).AsHtml();

var metaTag = $"<meta name=\"blackbird-page-id\" content=\"{input.Id}\">";
var headIndex = html.IndexOf("<head>", StringComparison.Ordinal) + "<head>".Length;
html = html.Insert(headIndex, metaTag);

using var stream = new MemoryStream(Encoding.UTF8.GetBytes(html));
var file = await _fileManagementClient.UploadAsync(stream, MediaTypeNames.Text.Html,
$"{post.Title.Rendered}.html");
Expand All @@ -131,9 +135,12 @@ public Task<WordPressItem> CreatePage([ActionParameter] ModificationRequest inpu
}

[Action("Create page from HTML", Description = "Create a new page from an HTML file. With Polylang enabled it can also be used to create translations of other pages.")]
public Task<WordPressItem> CreatePageFromHtml([ActionParameter] FileModificationRequest input, [ActionParameter] PageTranslationOptions translationOptions)
public async Task<WordPressItem> CreatePageFromHtml([ActionParameter] FileModificationRequest input, [ActionParameter] PageTranslationOptions translationOptions)
{
return ExecuteModification(input, translationOptions, null);
var fileStream = await _fileManagementClient.DownloadAsync(input.File);
var fileBytes = await fileStream.GetByteData();
var html = Encoding.UTF8.GetString(fileBytes);
return await ExecuteModification(html, translationOptions, null);
}

[Action("Update page", Description = "Update page. With Polylang enabled it can also be used to set the language and update its associations.")]
Expand All @@ -147,21 +154,29 @@ [ActionParameter] PageTranslationOptions translationOptions
}

[Action("Update page from HTML", Description = "Update a page from an HTML file. With Polylang enabled it can also be used to set the language and update its associations.")]
public Task<WordPressItem> UpdatePageFromHtml(
[ActionParameter] PageRequest page,
public async Task<WordPressItem> UpdatePageFromHtml(
[ActionParameter] PageOptionalRequest page,
[ActionParameter] FileModificationRequest input,
[ActionParameter] PageTranslationOptions translationOptions
)
{
return ExecuteModification(input, translationOptions, page.Id);
}

private async Task<WordPressItem> ExecuteModification(FileModificationRequest input, PageTranslationOptions translationOptions, string? id)
{
var fileStream = await _fileManagementClient.DownloadAsync(input.File);
var fileBytes = await fileStream.GetByteData();
var html = Encoding.UTF8.GetString(fileBytes);
var htmlDocument = html.AsHtmlDocument();

var metaTag = htmlDocument.DocumentNode.SelectSingleNode("//meta[@name='blackbird-page-id']");
var pageIdValue = metaTag?.GetAttributeValue("content", null);

var pageId = page.Id ?? pageIdValue
?? throw new Exception("Page ID not found in HTML file. Please make sure the file was created with the 'Get page as HTML' action, or provide the Page ID.");

return await ExecuteModification(html, translationOptions, pageId);
}

private async Task<WordPressItem> ExecuteModification(string html, PageTranslationOptions translationOptions, string? id)
{
var htmlDocument = html.AsHtmlDocument();
var title = htmlDocument.GetTitle();
var body = htmlDocument.GetBody();
return await ExecuteModification(new ModificationRequest { Title = title, Content = body }, translationOptions, id);
Expand Down
34 changes: 25 additions & 9 deletions Apps.Wordpress/Actions/PostActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ public async Task<FileResponse> GetPostByIdAsHtml([ActionParameter] PostRequest
var post = await Client.ExecuteWithHandling<Post>(request);

var html = (post.Title.Rendered, post.Content.Rendered).AsHtml();

var metaTag = $"<meta name=\"blackbird-post-id\" content=\"{post.Id}\">";
var headIndex = html.IndexOf("<head>", StringComparison.Ordinal) + "<head>".Length;
html = html.Insert(headIndex, metaTag);

using var stream = new MemoryStream(Encoding.UTF8.GetBytes(html));
var file = await _fileManagementClient.UploadAsync(stream, MediaTypeNames.Text.Html,
Expand All @@ -130,9 +134,13 @@ public Task<WordPressItem> CreatePost([ActionParameter] ModificationRequest inpu
}

[Action("Create post from HTML", Description = "Create a new post from an HTML file. With Polylang enabled it can also be used to create translations of other posts.")]
public Task<WordPressItem> CreatePostFromHtml([ActionParameter] FileModificationRequest input, [ActionParameter] PostTranslationOptions translationOptions)
public async Task<WordPressItem> CreatePostFromHtml([ActionParameter] FileModificationRequest input, [ActionParameter] PostTranslationOptions translationOptions)
{
return ExecuteModification(input, translationOptions, null);
var fileStream = await _fileManagementClient.DownloadAsync(input.File);
var fileBytes = await fileStream.GetByteData();
var html = Encoding.UTF8.GetString(fileBytes);

return await ExecuteModification(html, translationOptions, null);
}

[Action("Update post", Description = "Update post. With Polylang enabled it can also be used to set the language and update its associations.")]
Expand All @@ -146,21 +154,29 @@ [ActionParameter] PostTranslationOptions translationOptions
}

[Action("Update post from HTML", Description = "Update a post from an HTML file. With Polylang enabled it can also be used to set the language and update its associations.")]
public Task<WordPressItem> UpdatePostFromHtml(
[ActionParameter] PostRequest post,
public async Task<WordPressItem> UpdatePostFromHtml(
[ActionParameter] PostOptionalRequest post,
[ActionParameter] FileModificationRequest input,
[ActionParameter] PostTranslationOptions translationOptions
)
{
return ExecuteModification(input, translationOptions, post.Id);
}

private async Task<WordPressItem> ExecuteModification(FileModificationRequest input, PostTranslationOptions translationOptions, string? id)
{
var fileStream = await _fileManagementClient.DownloadAsync(input.File);
var fileBytes = await fileStream.GetByteData();
var html = Encoding.UTF8.GetString(fileBytes);
var htmlDocument = html.AsHtmlDocument();

var metaTag = htmlDocument.DocumentNode.SelectSingleNode("//meta[@name='blackbird-post-id']");
var postIdValue = metaTag?.GetAttributeValue("content", null);

var postId = post.Id ?? postIdValue
?? throw new Exception("Post ID not found in HTML file. Please make sure the file was created with the 'Get post as HTML' action. Or add optional Post ID parameter.");

return await ExecuteModification(html, translationOptions, postId);
}

private async Task<WordPressItem> ExecuteModification(string html, PostTranslationOptions translationOptions, string? id)
{
var htmlDocument = html.AsHtmlDocument();
var title = htmlDocument.GetTitle();
var body = htmlDocument.GetBody();
return await ExecuteModification(new ModificationRequest { Title = title, Content = body }, translationOptions, id);
Expand Down
7 changes: 6 additions & 1 deletion Apps.Wordpress/Apps.Wordpress.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Product>Wordpress (+ Polylang)</Product>
<Version>1.2.3</Version>
<Version>1.2.4</Version>
<Description>The world’s most popular website builder</Description>
<AssemblyName>Apps.Wordpress</AssemblyName>
</PropertyGroup>
Expand All @@ -18,4 +18,9 @@
<ItemGroup>
<EmbeddedResource CopyToOutputDirectory="Always" Include="image\icon.png"></EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Content Include="..\README.md">
<Link>README.md</Link>
</Content>
</ItemGroup>
</Project>
12 changes: 12 additions & 0 deletions Apps.Wordpress/Models/Requests/Page/PageOptionalRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Apps.Wordpress.DataSourceHandlers;
using Blackbird.Applications.Sdk.Common;
using Blackbird.Applications.Sdk.Common.Dynamic;

namespace Apps.Wordpress.Models.Requests.Page;

public class PageOptionalRequest
{
[Display("Page ID")]
[DataSource(typeof(PageDataHandler))]
public string? Id { get; set; }
}
4 changes: 2 additions & 2 deletions Apps.Wordpress/Models/Requests/Page/PageRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Apps.Wordpress.Models.Requests.Page;

public class PageRequest
{
[Display("Page")]
[Display("Page ID")]
[DataSource(typeof(PageDataHandler))]
public string Id { get; set; }
public string Id { get; set; } = string.Empty;
}
12 changes: 12 additions & 0 deletions Apps.Wordpress/Models/Requests/Post/PostOptionalRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Apps.Wordpress.DataSourceHandlers;
using Blackbird.Applications.Sdk.Common;
using Blackbird.Applications.Sdk.Common.Dynamic;

namespace Apps.Wordpress.Models.Requests.Post;

public class PostOptionalRequest
{
[Display("Post ID")]
[DataSource(typeof(PostDataHandler))]
public string? Id { get; set; }
}
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ All create and update actions optionally take a language and "as translation of"

- **Get languages (P)** returns all languages configured and their additional information. Polylang required.

### HTML features

We add metadata to the HTML file to include `Post ID` and `Page ID`. This metadata is used to update the correct post or page. The metadata is added as a `meta` tag in the `head` of the HTML file. The `name` attribute is `blackbird-post-id` or `blackbird-page-id` and the `content` attribute is the ID of the post or page.

```html
<html>
<head>
<meta name="blackbird-page-id" content="2">
<title>Sample Page</title>
</head>
<body>
<p>This is an example page. It&#8217;s different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:</p>
<blockquote class="wp-block-quote">
<p>Hi there! I&#8217;m a bike messenger by day, aspiring actor by night, and this is my website. I live in Los Angeles, have a great dog named Jack, and I like pi&#241;a coladas. (And gettin&#8217; caught in the rain.)</p>
</blockquote>
<p>&#8230;or something like this:</p>
<blockquote class="wp-block-quote">
<p>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</p>
</blockquote>
<p>As a new WordPress user, you should go to <a href="https://dev-blackbird-test.pantheonsite.io/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!</p>
</body>
</html>
```

Example of how we include metadata in the HTML file:
### Missing features

In the future we will add actions for:
Expand Down