how to get wordpress posts in your flutter application using wordpress rest api
Step 1: Add JSON Viewer extension in your chrome browser
Step 2: Visit your website url with /wp-json/wp/v2/posts/
eg( yourdomain.com/wp-json/wp/v2/posts)
Use your JSON Viewer extension to make json data readable
Step 3: Create your Flutter Application
flutter create yourproject_name
Step 4: Add Dependencies in your pubspec.yml
http: ^1.2.1
html: ^0.15.4
Step 5: past the following code in main.dart
import 'package:easyjob_af/postdetails.dart';
import 'package:easyjob_af/wordpressapi.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'WordPress API Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: HomePage(),
);
}
}
create wordpressapi.dart into lib dierctory to fetch all data from wordpress site
Note(Make sure to replace your site url in the following code)
import 'dart:convert';
import 'package:http/http.dart' as http;
class WordPressAPI {
static const String baseURL = 'https://yoursite.com/wp-json/wp/v2';
Future<List<Map<String, dynamic>>> getAllCategories() async {
final response = await http.get(Uri.parse('$baseURL/categories'));
if (response.statusCode == 200) {
List<dynamic> data = jsonDecode(response.body);
return List<Map<String, dynamic>>.from(data);
} else {
throw Exception('Failed to load categories');
}
}
Future<List<Map<String, dynamic>>> getAllPosts() async {
final response = await http.get(Uri.parse('$baseURL/posts?_embed'));
if (response.statusCode == 200) {
List<dynamic> data = jsonDecode(response.body);
return List<Map<String, dynamic>>.from(data);
} else {
throw Exception('Failed to load posts');
}
}
}
create home.dart in your lib directory to fetch all categories from your wordpress website and show them on dropdown
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final WordPressAPI api = WordPressAPI();
late Future<List<Map<String, dynamic>>> categories;
late Future<List<Map<String, dynamic>>> posts;
late List<Map<String, dynamic>> allCategories = [];
late String selectedCategory =
'All'; // Initialize selectedCategory with 'All'
@override
void initState() {
super.initState();
categories = api.getAllCategories();
posts = api.getAllPosts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('WordPress API Demo'),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FutureBuilder<List<Map<String, dynamic>>>(
future: categories,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
allCategories = snapshot.data!;
List<String> categoryNames = ['All'];
categoryNames
.addAll(allCategories.map((category) => category['name']));
// Check if selectedCategory is in categoryNames, if not, set it to 'All'
if (!categoryNames.contains(selectedCategory)) {
selectedCategory = 'All';
}
return DropdownButton<String>(
value: selectedCategory,
items: categoryNames.map((String categoryName) {
return DropdownMenuItem<String>(
value: categoryName,
child: Text(categoryName),
);
}).toList(),
onChanged: (String? value) {
setState(() {
selectedCategory = value ??
'All'; // Use null safety operator to avoid null value
});
},
);
}
},
),
Expanded(
child: FutureBuilder<List<Map<String, dynamic>>>(
future: posts,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List<Map<String, dynamic>> data = snapshot.data!;
if (selectedCategory != 'All') {
int categoryId = allCategories.firstWhere((category) =>
category['name'] == selectedCategory)['id'];
data = data.where((post) {
List<dynamic> categories = post['categories'];
return categories.contains(categoryId);
}).toList();
}
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(data[index]['title']['rendered']),
subtitle: Text(data[index]['excerpt']['rendered']),
leading: data[index]['featured_media'] != 0
? Image.network(
data[index]['_embedded']['wp:featuredmedia'][0]['source_url'],
width: 100,
height: 100,
fit: BoxFit.cover,
)
: null,
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PostDetailScreen(
postId: data[index]['id'],
),
),
);
},
);
},
);
}
},
),
),
],
),
);
}
}
create postdetails.dart in lib directory to fetch data by id in details with images
Note (Make sure to replace your site url in the following code)
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:html/parser.dart' as htmlParser;
import 'package:html/dom.dart' as dom;
class PostDetailScreen extends StatefulWidget {
final int postId;
const PostDetailScreen({Key? key, required this.postId}) : super(key: key);
@override
_PostDetailScreenState createState() => _PostDetailScreenState();
}
class _PostDetailScreenState extends State<PostDetailScreen> {
late Future<Map<String, dynamic>> post;
@override
void initState() {
super.initState();
post = fetchPost(widget.postId);
}
Future<Map<String, dynamic>> fetchPost(int postId) async {
final response = await http.get(
Uri.parse('https://yoursite.com/wp-json/wp/v2/posts/$postId?_embed'));
if (response.statusCode == 200) {
return jsonDecode(response.body);
} else {
throw Exception('Failed to load post');
}
}
Widget _buildContent(String htmlContent) {
dom.Document document = htmlParser.parse(htmlContent);
List<Widget> children = [];
for (var node in document.body!.nodes) {
if (node.nodeType == dom.Node.TEXT_NODE) {
children.add(Text(
node.text!,
style: TextStyle(fontSize: 16, color: Colors.black87),
));
} else if (node.nodeType == dom.Node.ELEMENT_NODE) {
var element = node as dom.Element;
if (element.localName == 'p') {
children.add(Container(
margin: EdgeInsets.symmetric(vertical: 8.0),
child: Text(
element.text,
style: TextStyle(fontSize: 16, color: Colors.black87),
),
));
} else if (element.localName == 'h1' || element.localName == 'h2') {
children.add(Container(
margin: EdgeInsets.symmetric(vertical: 12.0),
child: Text(
element.text,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
));
} else if (element.localName == 'img') {
String imageUrl = element.attributes['src'] ?? '';
if (imageUrl.isNotEmpty) {
children.add(Image.network(
imageUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
));
}
}
}
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: children,
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Post Detail'),
),
body: FutureBuilder<Map<String, dynamic>>(
future: post,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
} else {
Map<String, dynamic> postData = snapshot.data!;
return ListView(
children: [
if (postData['_embedded'] != null &&
postData['_embedded']['wp:featuredmedia'] != null)
Image.network(
postData['_embedded']['wp:featuredmedia'][0]['source_url'],
width: MediaQuery.of(context).size.width,
height: 200,
fit: BoxFit.cover,
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
postData['title']['rendered'],
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: _buildContent(postData['content']['rendered']),
),
],
);
}
},
),
);
}
}
Screenshots
Masha Allah… very impressive website for beginners. please keep sharing stuff with us thank you.