Flutter开发:如何从WordPress API获取文章段落内图片并移除HTML标签
Hey there! Let's fix those two frustrating issues with your WordPress-Flutter app right away. I've got practical, code-ready solutions for both extracting inline images and cleaning up HTML tags.
1. Extract Inline Images from Post Content
The placeholder text you're seeing is actually raw HTML <img> tags from WordPress's API response. To pull out the actual image URLs and display them properly, we'll use the html package to parse the content.
First, add the package to your pubspec.yaml:
dependencies: flutter: sdk: flutter html: ^0.15.4 # Use the latest stable version if available
Then, create a helper function to extract all image URLs from the HTML content:
import 'package:html/parser.dart' as parser; List<String> extractInlineImages(String htmlContent) { final document = parser.parse(htmlContent); final imgElements = document.querySelectorAll('img'); // Filter out any empty URLs and return the list return imgElements .map((img) => img.attributes['src'] ?? '') .where((src) => src.isNotEmpty) .toList(); }
If you want to render images alongside text (not just extract URLs), use this helper to convert HTML content into a list of Flutter widgets (text blocks + images):
List<Widget> renderPostContent(String htmlContent) { final document = parser.parse(htmlContent); final contentWidgets = <Widget>[]; for (var element in document.body?.children ?? []) { // Handle paragraph text if (element.localName == 'p') { final text = element.text.trim(); if (text.isNotEmpty) { contentWidgets.add( Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text(text, style: const TextStyle(fontSize: 16)), ), ); } // Handle images inside paragraphs final imgsInParagraph = element.querySelectorAll('img'); for (var img in imgsInParagraph) { final src = img.attributes['src']; if (src != null) { contentWidgets.add( Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Image.network(src), ), ); } } } // Handle standalone images else if (element.localName == 'img') { final src = element.attributes['src']; if (src != null) { contentWidgets.add( Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Image.network(src), ), ); } } // Add more cases here for other tags (h2, lists, etc.) if needed } return contentWidgets; }
Use this in your PostDetails screen like so:
class PostDetails extends StatelessWidget { final Map<String, dynamic> data; const PostDetails({Key? key, required this.data}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(data['title']['rendered'])), body: SingleChildScrollView( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Featured image Image.network(data["_embedded"]["wp:featuredmedia"][0]["source_url"]), const SizedBox(height: 16), // Render parsed content (text + images) ...renderPostContent(data['content']['rendered']), ], ), ), ); } }
2. Remove All HTML Tags Cleanly
Your current replaceAll("<p>", "") approach only handles paragraph tags—any other tags (like <br>, <div>, or inline styles) will still show up. Again, the html package makes this trivial with a helper function:
String stripHtmlTags(String htmlContent) { final document = parser.parse(htmlContent); return document.body?.text ?? ''; }
Update your LatestPost widget's subtitle to use this function instead of manual replaces:
subtitle: Container( padding: const EdgeInsets.only(left: 5.0, right: 5.0, bottom: 25.0), child: Text( stripHtmlTags(snapshot.data![i]['content']['rendered']), maxLines: 4, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 16.0), ), ),
This will strip all HTML tags and leave you with clean, plain text.
Once you add the html package and implement these helpers, you'll see inline images render properly and your text will be free of messy HTML tags.
内容的提问来源于stack exchange,提问作者Bhaskar2510

