Skip to content

Commit

Permalink
Embed post and page IDs into generated HTML files and extract them in…
Browse files Browse the repository at this point in the history
… update actions
  • Loading branch information
vitalii-bezuhlyi committed Oct 8, 2024
1 parent 09f5ce6 commit 5172c03
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 21 deletions.
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

0 comments on commit 5172c03

Please sign in to comment.