Instantly share code, notes, and snippets.
Created
January 13, 2026 11:06
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save bhpayne/72e5c66577e10825c8ef2809cdedfef1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>WordPress XML Blog Viewer</title> | |
| <style> | |
| body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f4f4f9; } | |
| header { text-align: center; margin-bottom: 40px; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } | |
| #fileInput { margin: 20px 0; } | |
| .post { background: white; padding: 30px; margin-bottom: 30px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.05); } | |
| .post h2 { margin-top: 0; color: #2c3e50; } | |
| .post-meta { font-size: 0.9em; color: #7f8c8d; margin-bottom: 20px; border-bottom: 1px solid #eee; padding-bottom: 10px; } | |
| .post-content img { max-width: 100%; height: auto; } | |
| .post-content { word-wrap: break-word; } | |
| /* Loading spinner */ | |
| #status { font-weight: bold; margin: 10px 0; color: #2980b9; } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <h1>WordPress Post Viewer</h1> | |
| <p>Select your WordPress .xml export file to display your posts.</p> | |
| <input type="file" id="fileInput" accept=".xml"> | |
| <div id="status"></div> | |
| </header> | |
| <div id="posts-container"></div> | |
| <script> | |
| document.getElementById('fileInput').addEventListener('change', function(e) { | |
| const file = e.target.files[0]; | |
| if (!file) return; | |
| const status = document.getElementById('status'); | |
| const container = document.getElementById('posts-container'); | |
| status.textContent = "Loading file..."; | |
| container.innerHTML = ""; // Clear previous posts | |
| const reader = new FileReader(); | |
| reader.onload = function(e) { | |
| const xmlString = e.target.result; | |
| parseWordPressXML(xmlString); | |
| }; | |
| reader.readAsText(file); | |
| }); | |
| function parseWordPressXML(xmlString) { | |
| const parser = new DOMParser(); | |
| const xmlDoc = parser.parseFromString(xmlString, "text/xml"); | |
| const items = xmlDoc.querySelectorAll("item"); | |
| const container = document.getElementById('posts-container'); | |
| const status = document.getElementById('status'); | |
| let postCount = 0; | |
| items.forEach(item => { | |
| // 1. Filter: Only get items that are 'post' and are 'published' | |
| const postType = getElementValue(item, "wp:post_type"); | |
| const postStatus = getElementValue(item, "wp:status"); | |
| if (postType === "post" && postStatus === "publish") { | |
| postCount++; | |
| // 2. Extract Data | |
| const title = getElementValue(item, "title"); | |
| const link = getElementValue(item, "link"); | |
| const pubDate = getElementValue(item, "pubDate"); | |
| const creator = getElementValue(item, "dc:creator"); | |
| // WordPress content is stored in <content:encoded> | |
| const content = getElementValue(item, "content:encoded"); | |
| // 3. Create HTML | |
| const postEl = document.createElement('article'); | |
| postEl.className = 'post'; | |
| postEl.innerHTML = ` | |
| <h2>${title}</h2> | |
| <div class="post-meta"> | |
| Published on ${new Date(pubDate).toLocaleDateString()} by ${creator} | |
| | <a href="${link}" target="_blank">Original Link</a> | |
| </div> | |
| <div class="post-content">${content}</div> | |
| `; | |
| container.appendChild(postEl); | |
| } | |
| }); | |
| status.textContent = `Successfully loaded ${postCount} posts.`; | |
| if (postCount === 0) status.textContent = "No published posts found in this XML file."; | |
| } | |
| /** | |
| * Helper function to handle namespaced tags like <content:encoded> | |
| * which querySelector sometimes struggles with in XML mode. | |
| */ | |
| function getElementValue(parent, tagName) { | |
| let element = parent.getElementsByTagName(tagName)[0]; | |
| // Fallback for namespaced tags if the above fails | |
| if (!element && tagName.includes(':')) { | |
| const parts = tagName.split(':'); | |
| element = parent.getElementsByTagNameNS("*", parts[1])[0]; | |
| } | |
| return element ? element.textContent : ""; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment