{"id":19233683,"url":"https://github.com/brightdigit/contributewordpress","last_synced_at":"2025-04-21T04:33:22.497Z","repository":{"id":180175897,"uuid":"653868496","full_name":"brightdigit/ContributeWordPress","owner":"brightdigit","description":"Import your Wordpress site into Publish","archived":false,"fork":false,"pushed_at":"2023-09-07T01:46:50.000Z","size":390,"stargazers_count":6,"open_issues_count":2,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-01T09:47:12.168Z","etag":null,"topics":["publish-plugin","swift","wordpress"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brightdigit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-14T23:21:07.000Z","updated_at":"2024-10-02T16:24:32.000Z","dependencies_parsed_at":"2023-11-10T12:09:12.597Z","dependency_job_id":null,"html_url":"https://github.com/brightdigit/ContributeWordPress","commit_stats":null,"previous_names":["brightdigit/contributewordpress"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FContributeWordPress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FContributeWordPress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FContributeWordPress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brightdigit%2FContributeWordPress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brightdigit","download_url":"https://codeload.github.com/brightdigit/ContributeWordPress/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249996241,"owners_count":21358095,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["publish-plugin","swift","wordpress"],"created_at":"2024-11-09T16:11:30.985Z","updated_at":"2025-04-21T04:33:22.491Z","avatar_url":"https://github.com/brightdigit.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg alt=\"ContributeWordPress\" title=\"ContributeWordPress\" src=\"Sources/ContributeWordPress/Documentation.docc/Resources/ContributeWordPressLogo.png\" height=\"125\"\u003e\n\u003c/p\u003e\n\u003ch1 align=\"center\"\u003eContributeWordPress\u003c/h1\u003e\n\nImport your WordPress site into Publish.\n\n[![SwiftPM](https://img.shields.io/badge/SPM-Linux%20%7C%20iOS%20%7C%20macOS%20%7C%20watchOS%20%7C%20tvOS-success?logo=swift)](https://swift.org)\n[![Twitter](https://img.shields.io/badge/twitter-@brightdigit-blue.svg?style=flat)](http://twitter.com/brightdigit)\n![GitHub](https://img.shields.io/github/license/brightdigit/ContributeWordPress)\n![GitHub issues](https://img.shields.io/github/issues/brightdigit/ContributeWordPress)\n![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/brightdigit/ContributeWordPress/ContributeWordPress.yml?label=actions\u0026logo=github\u0026?branch=main)\n\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbrightdigit%2FContributeWordPress%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/brightdigit/ContributeWordPress)\n[![](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fbrightdigit%2FContributeWordPress%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/brightdigit/ContributeWordPress)\n\n\n[![Codecov](https://img.shields.io/codecov/c/github/brightdigit/ContributeWordPress)](https://codecov.io/gh/brightdigit/ContributeWordPress)\n[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/brightdigit/ContributeWordPress)](https://www.codefactor.io/repository/github/brightdigit/ContributeWordPress)\n[![codebeat badge](https://codebeat.co/badges/4dadaf1f-863e-4bd2-8038-747b1db3ce88)](https://codebeat.co/projects/github-com-brightdigit-ContributeWordPress-main)\n[![Code Climate maintainability](https://img.shields.io/codeclimate/maintainability/brightdigit/ContributeWordPress)](https://codeclimate.com/github/brightdigit/ContributeWordPress)\n[![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/brightdigit/ContributeWordPress?label=debt)](https://codeclimate.com/github/brightdigit/ContributeWordPress)\n[![Code Climate issues](https://img.shields.io/codeclimate/issues/brightdigit/ContributeWordPress)](https://codeclimate.com/github/brightdigit/ContributeWordPress)\n[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)\n\n# Table of Contents\n\n* [Introduction](#introduction)\n   * [Requirements](#requirements)\n   * [Installation](#installation)\n   * [How It Works](#how-it-works)\n   * [Exporting from WordPress](#exporting-from-wordpress)\n* [Usage](#usage)\n   * [Getting Started](#getting-started)\n   * [Exporting to Publish](#exporting-to-publish)\n   * [Dowloading Resources from Active Site](#dowloading-resources-from-active-site)\n   * [Copy Resources from Local Backup](#copy-resources-from-local-backup)\n   * [Converting Posts to Markdown](#converting-posts-to-markdown)\n   * [Using ShellOut and Pandoc for Markdown](#using-shellout-and-pandoc-for-markdown)\n   * [Filtering Posts](#filtering-posts)\n   * [Redirecting Old URLs](#redirecting-old-urls)\n   * [Using SwiftArgumentParser for Settings](#using-swiftargumentparser-for-settings)\n   * [Further Documentation](#further-documentation)\n* [License](#license)\n\n# Introduction\n\n**ContributeWordPress** provides an easy to use API for importing a **WordPress** site into **Publish**.\n\n## Requirements \n\n**Apple Platforms**\n\n- Xcode 14.3.1 or later\n- Swift 5.8 or later\n- macOS 12 or later deployment targets\n\n**Linux**\n\n- Ubuntu 18.04 or later\n- Swift 5.8 or later\n\n## Installation\n\nUse the Swift Package Manager to install this library via the repository url:\n\n```\nhttps://github.com/brightdigit/ContributeWordPress.git\n```\n\nUse version up to `1.0.0`.\n\n## How It Works\n\n**ContributeWordPress** uses the exported XML (also referred to as WXR file) to import content into your existing **Publish** site. \n\n```swift\nimport ContributeWordPress\n\nlet fromURL = URL(\n    fileURLWithPath: \"directory/containing/your/export/xml/files\"\n)\nlet toURL = URL(\n    fileURLWithPath: \"Path/to/Publish/root\"\n)\n\ntry MarkdownProcessor.beginImport(\n    from: fromURL, \n    to: toURL\n)\n```\n\nIn order to begin, you need:\n\n* The exported **XML file** \n* The active WordPress site or a complete download of the site's files (for the images on your site)\n\n## Exporting from WordPress\n\n**ContributeWordPress** needs a backup XML file from your **WordPress** site. To do this:\n\n1. Login to your WordPress Administration Dashboard.\n2. Go to Tools... Export:\n![WordPress-Tools...Export](Sources/ContributeWordPress/Documentation.docc/Resources/tools-export-download-file.png)\n3. Download your export file by:\n    * Clicking the Export All button (if you have a site without plugins installed.)\n    * Selecting all content and clicking the Download Export File button (if you have a site with plugins installed.)\n    * Download specific content only, like posts, pages, or feedback.\n4. You will receive a .zip file to save to your computer with the .xml file inside of it. This file contains your posts, pages, comments, categories, tags, and references to your site’s images.\n\nLarger sites will include more than one XML file to ensure that your export process will be fast and complete successfully, for instance if you are running multi-site **WordPress**. Luckily **ContributeWordPress** supports importing multiple xml files! \n\nWhen importing the BrightDigit website, the content was importing for the learningswift.brightdigit.com into brightdigit.com/tutorials and brightdigit.com into brightdigit.com/articles.\n\nFor more details on the export process, please read [the documentation on the **WordPress** site.](https://wordpress.com/support/export/)\n\n# Usage\n\n## Getting Started\n\nBesides exporting your **WordPress site**, you need access to the images by either:\n* downloading directly from the site\n* having a copy of the site's files\n\n![Example Copy of the WordPress Site's Files](Sources/ContributeWordPress/Documentation.docc/Resources/wordpress-site-files.png \"Example Copy of the WordPress Site's Files\")\n\nOnce you have both components, [you need to setup a **Publish** site]((https://github.com/JohnSundell/Publish)). There are several great tutorials online:\n\n* [JohnSundell/Publish: A static site generator for Swift developers](https://github.com/JohnSundell/Publish)\n* [How to Create a Personal Website in Swift using Publish | Danijela's blog](https://www.danijelavrzan.com/posts/2022/06/create-portfolio-website-using-publish/)\n* [Static Site Generation with Swift using Publish, Plot and Ink](https://www.createwithswift.com/static-site-generation-with-swift-using-publish/)\n* [Getting started with static-site generation in Swift using Publish | Andy Regensky](https://andyregensky.dev/articles/publish-getting-started/)\n\nOnce the site is setup, we can:\n\n* convert and translate the HTML inside your exported XML (also referred to as WXR file) to Markdown files inside your _Content_ directory\n* download (or copy) your images and other files inside your WordPress upload folder to your _Resources_ directory\n## Exporting to Publish\n\nThe simplest way to import your **WordPress** site is by just passing the path to your xml files as well as the root of your **Publish** site.\n\n```swift\nimport ContributeWordPress\n\nlet fromURL = URL(\n    fileURLWithPath: \"directory/containing/your/export/xml/files\"\n)\nlet toURL = URL(\n    fileURLWithPath: \"Path/to/Publish/root\"\n)\n\ntry MarkdownProcessor.beginImport(\n    from: fromURL, \n    to: toURL\n)\n```\n\nIf you wish to create a small command line application you can take in command line arguments for the two paths:\n\n```swift\nimport ContributeWordPress\n\nlet fromURL : URL\nlet toURL : URL\n\nguard CommandLine.arguments.count == 2 else {\n  exit(1)\n}\n\nfromURL = .init(fileURLWithPath: CommandLine.arguments[0])\ntoURL = .init(fileURLWithPath: CommandLine.arguments[1])\n\ntry! MarkdownProcessor.beginImport(from: fromURL, to: toURL)\n```\n\n## Dowloading Resources from Active Site\n\nBy default, **ContributeWordPress** will download the images from your active **WordPress** site. Therefore if it comes across a reference to url to your site it will change the url to the new address it will be imported to.\n\nTherefore HTML from your exports file will change from:\n\n```html\n\u003cfigure class=\"wp-block-image\"\u003e\u003cimg src=\"https://leogdion.name/wp-content/uploads/2019/01/image-e1547230562842-1024x682.jpg\" alt=\"A JavaScript Meetup I hosted in 2018 \" class=\"wp-image-105\"/\u003e\u003cfigcaption\u003eA JavaScript Meetup I hosted in 2018 \u003c/figcaption\u003e\u003c/figure\u003e\n```\n\nto this in your markdown file:\n\n```html\n\u003cfigure class=\"wp-block-image\"\u003e\n\u003cimg\nsrc=\"/media/wp-assets/default/2019/01/image-e1547230562842-1024x682.jpg\"\nclass=\"wp-image-105\" alt=\"A JavaScript Meetup I hosted in 2018 \" /\u003e\n\u003cfigcaption\u003eA JavaScript Meetup I hosted in 2018\u003c/figcaption\u003e\n\u003c/figure\u003e\n```\n\n## Copy Resources from Local Backup\n\n\nIf your site is no longer active but you have a local copy of the site, you can pass in that directory to be used instead.\n\nLet's expand on our previous command line example by adding an optional parameter:\n\n```swift\nlet fromURL : URL\nlet toURL : URL\n\nlet importAssetsSetting : AssetImportSetting\n\nguard CommandLine.arguments.count \u003e= 2 else {\n  exit(1)\n}\n\nfromURL = URL(fileURLWithPath: CommandLine.arguments[0])\ntoURL = URL(fileURLWithPath: CommandLine.arguments[1])\n\n// if a third argument is passed\nif CommandLine.arguments.count \u003e 2 {\n  // assume they want to copy the resources directly\n  importAssetsSetting = .copyFilesFrom(\n    URL(fileURLWithPath: CommandLine.arguments[2])\n  )\n} else {\n  // otherwise use the default `download` option\n  importAssetsSetting = .download\n}\n\ntry! MarkdownProcessor.beginImport(\n  from: fromURL,\n  to: toURL,\n  importAssetsBy: importAssetsSetting\n)\n\n```\n\nTherefore you can call:\n\n```bash\n\u003e wpublish \\\n  directory/with/export/xml/files \\\n  Path/to/Publish/root \\\n  path/to/root/wordpress/files\n```\n\nThe `AssetImportSetting` option contains three options:\n* `none` - don't do anything\n* `download` - download them from the WordPress site\n* `copyFilesFrom(URL)` - copy the files from a local mapped location\n\n## Converting Posts to Markdown\n\nBy default, **ContributeWordPress** doesn't implement any specific method to convert HTML from your WordPress posts to markdown. \n\nHowever there are a few easy to use implementations as well the ability to plug in your own.\n\nSpecifically this can done by passing a `MarkdownGenerator` to the processor:\n\n```swift\ntry! MarkdownProcessor.beginImport(\n  from: fromURL,\n  to: toURL,\n  usingGenerator: // your `MarkdownGenerator` here,\n  importAssetsBy: importAssetsSetting\n)\n```\n\n`MarkdownGenerator` is a simple protocol from the **Contribute** base library which takes an HTML `String` and returns a new markdown `String`.\n\n```swift\n/// A protocol for generating Markdown from HTML.\npublic protocol MarkdownGenerator {\n  /// Converts an HTML string to Markdown.\n  ///\n  /// - Parameter htmlString: The HTML string to convert.\n  /// - Returns: The generated Markdown string.\n  /// - Throws: An error if the conversion fails.\n  func markdown(fromHTML htmlString: String) throws -\u003e String\n}\n```\n\nBy default, we use the `PassthroughMarkdownGenerator` which does nothing. However you can implement your own or use `HTMLtoMarkdown` to pass in a closure.\n\n## Using ShellOut and Pandoc for Markdown\n\nIf you wish to convert the HTML from your WordPress posts to Markdown, the recommended solution is to use the `PanddocMarkdownGenerator` included with the **Contribute** library. The `PanddocMarkdownGenerator` requires the **ShellOut** library to run an installation of **Pandoc**.\n\nThe recommended way to install **Pandoc** on your machine is via homebrew:\n\n```bash\n\u003e brew install pandoc\n```\n\nOnce **Pandoc** is installed, you can run the command as part of your import using **ShellOut**.\n\nHere is a simple code snippet for using plugging in **ShellOut**:\n\n```swift\nextension PandocMarkdownGenerator {\n  public static func defaultShellOut(to command: String, arguments: [String]) throws -\u003e String {\n    try ShellOut.shellOut(to: command, arguments: arguments)\n  }\n  \n  public init (temporaryFile: @escaping (String) throws -\u003e URL = Temporary.file(fromContent:)) {\n    self.init(shellOut: Self.defaultShellOut(to:arguments:), temporaryFile: temporaryFile)\n  }\n}\n```\n\nFrom here we can now simply use the `PandocMarkdownGenerator` to convert our WordPress HTML to markdown:\n\n```swift\ntry! MarkdownProcessor.beginImport(\n  from: fromURL,\n  to: toURL,\n  usingGenerator: PandocMarkdownGenerator(),\n  importAssetsBy: importAssetsSetting\n)\n```\n\n## Filtering Posts\n\nThe export files from WordPress contain a plethora of information including non-published posts as well as non-post items. **By default, the import filters for only published posts.** These are set using the `RegexKeyPostFilter` type which takes in a `KeyPath` of a `WordPressPost` property with a `String` type from the `SyndiKit` library and a `NSRegularExpression`.\n\nHere's the example for the default `RegexKeyPostFilter` items:\n\n```swift\n    [\n        RegexKeyPostFilter(pattern: \"post\", keyPath: \\.type),\n        RegexKeyPostFilter(pattern: \"publish\", keyPath: \\.status)\n    ]\n```\n\nAdditionally you can implement your own `PostFilter` of any kind and pass it in:\n\n```swift\ntry! MarkdownProcessor.beginImport(\n  from: fromURL,\n  to: toURL,\n  filteringPostsWith: // array of `PostFilter` items\n  importAssetsBy: importAssetsSetting\n)\n```\n\n## Redirecting Old URLs\n\nIf you are migrating from **WordPress** to a **Publish** site, probably need to redirect several old urls to you new site. This can be done by passing a `RedirectFormatter`. This requires two methods to be implemented:\n\n* `formatRedirects` which takes a collection of `RedirectItem` object (i.e. old URL, new URL) and expects a single string which will be written out somehere.\n* `redirectsURL(basedOnResourcesDirectoryURL:)` which returns the url for the file which that `String` needs to be written.\n\nBy default no redirect file is exported so you'll need to supply your own if needed. Otherwise, only **Netlify** is supported via `NetlifyRedirectFormatter`. More granular control is available via the `RedirectFileWriter` if needed. \n\nFeel free to post an issue or pull request for your own implementations or questions.\n\n## Using SwiftArgumentParser for Settings\n\nWhile you may wish the parse the arguments yourself using the `CommandLine` object, it is highly recommended you use the **Swift Argument Parser** for more complex options.\n\nFeel free to check out [the example here](https://github.com/leogdion/leogdion.name/blob/main/Sources/LeoGDionNameArgs/Commands/Import/WordPress.swift).\n\n## Further Documentation\n\nFurther documentation is available at [the Swift Package Index.](https://swiftpackageindex.com/brightdigit/ContributeWordPress/1.0.0/documentation/ContributeWordPress)\n\n# License \n\nThis code is distributed under the MIT license. See the [LICENSE](https://github.com/brightdigit/ContributeWordPress/LICENSE) file for more info.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightdigit%2Fcontributewordpress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrightdigit%2Fcontributewordpress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrightdigit%2Fcontributewordpress/lists"}