arunprakashg / wordpress_client Goto Github PK
View Code? Open in Web Editor NEWA powerful and easy-to-use WordPress REST API client for Dart & Flutter.
License: MIT License
A powerful and easy-to-use WordPress REST API client for Dart & Flutter.
License: MIT License
I'm trying to get posts from wordpress and i'm not getting response back. i'm running latest version of the library. Am i missing something? Sorry still learning flutter.
Future<ResponseContainer<List<Post?>?>> getPosts() async { WordpressClient client; client = new WordpressClient('https://{obfiscatedurl}/wp-json', 'wp/v2'); ResponseContainer<List<Post?>?> posts = await client.posts .list((builder) => builder.withPerPage(20).withPageNumber(1).build()); print(posts.value!.first!.id); return posts; }
Uncaught (in promise) Error: Instance of 'ClientNotReadyException'
at Object.throw_ [as throw] (errors.dart:288:49)
at wordpress_client_base.WordpressClient.new.getInterface (wordpress_client_base.dart:422:7)
at get posts [as posts] (wordpress_client_base.dart:160:31)
at blog_section.dart:69:39
at Generator.next ()
at runBody (async_patch.dart:84:54)
at Object._async [as async] (async_patch.dart:123:5)
at blog_section.dart:62:32
at ink_well._InkResponseState.new.handleTap (ink_well.dart:1154:21)
at tap.TapGestureRecognizer.new.invokeCallback (recognizer.dart:275:24)
at tap.TapGestureRecognizer.new.handleTapUp (tap.dart:654:11)
at [_checkUp] (tap.dart:311:5)
at tap.TapGestureRecognizer.new.handlePrimaryPointer (tap.dart:244:7)
at tap.TapGestureRecognizer.new.handleEvent (recognizer.dart:630:9)
at [_dispatch] (pointer_router.dart:98:12)
at pointer_router.dart:143:9
at LinkedMap.new.forEach (linked_hash_map.dart:21:13)
at [_dispatchEventToRoutes] (pointer_router.dart:141:17)
at pointer_router.PointerRouter.new.route (pointer_router.dart:127:7)
at binding$5.WidgetsFlutterBinding.new.handleEvent (binding.dart:465:19)
at binding$5.WidgetsFlutterBinding.new.dispatchEvent (binding.dart:445:14)
at binding$5.WidgetsFlutterBinding.new.dispatchEvent (binding.dart:331:11)
at [_handlePointerEventImmediately] (binding.dart:400:7)
at binding$5.WidgetsFlutterBinding.new.handlePointerEvent (binding.dart:363:5)
at [_flushPointerEventQueue] (binding.dart:320:7)
at [_handlePointerDataPacket] (binding.dart:293:9)
at Object.invoke1 (platform_dispatcher.dart:1251:13)
at _engine.EnginePlatformDispatcher.new.invokeOnPointerDataPacket (platform_dispatcher.dart:269:5)
at [_onPointerData] (pointer_binding.dart:168:39)
at pointer_binding.dart:791:20
at pointer_binding.dart:720:14
at loggedHandler (pointer_binding.dart:317:16)
at Object._checkAndCall (operations.dart:367:37)
at Object.dcall (operations.dart:372:39)
at ret (js_allow_interop_patch.dart:17:11)
Hello,
First, thanks a lot for the library :)
Running it on iOS/Mac/Android works totally fine, I have declared my baseUrl like so:
final baseUrl = Uri.parse('https://example.com/wp-json/wp/v2');
final client = WordpressClient(baseUrl: baseUrl);
But compiling on the web, I have 404 errors with links like:
GET https://example.com/media?page=1&per_page=100&order=desc 404 (Not Found)
GET https://example.com/categories?page=1&per_page=20&order=desc 404 (Not Found)
GET https://example.com/posts?page=1&per_page=100&order=desc 404 (Not Found)
The links are not example.com/wp-json/wp/v2... but example.com?
After creating my client, I log it with:
print("baseUrl: ${client.baseUrl} path: ${client.path} isReady: ${client.isReady}");
And I can see the correct data:
baseUrl: https://example.com/wp-json/wp/v2/ path: /wp-json/wp/v2/ isReady: true
Do you have any idea of what's going on?
Thanks :)
PS : The flutter web app is hosted directly on example.com, so maybe there's something going on with that?
This package no longer supports up-to-date dependencies, so can you please update it
client.media.create is not working
How can I update post's meta field?
UpdatePostRequest hasn't meta parameter.
I get an error returned like.
flutter: {"code": "rest_cannot_create_user", "message": "You do not have permissions to create new users.", "data":{"status":401}}
How can I fix this?
static void init(String username, String password) {
//init Wordpress API
client = WordpressClient.initialize(
"https://www.site.it/",
"wp-json/wp/v2",
bootstrapper: (bootstrapper) => bootstrapper
.withDebugMode(true)
.withDefaultAuthorization(BasicAuth(username, password))
.build(),
);
}
Future<WordpressResponse<User?>> signup(
String username, String email, String password) async {
return await client.users.create(
WordpressRequest(
requestData: CreateUserRequest(
username: username,
email: email,
password: password,
),
),
);
}
to the init method I pass username and password of a user with administrator role
Hi-
Trying to implement this on an app I'm building but even with a WordpressSuccessResponse() the data varaible is empty in wpResponse.data
`
void fetchArticles() async {
final baseUrl = Uri.parse('https://mydomain.com/wp-json/wp/v2');
final client = WordpressClient(
baseUrl: baseUrl,
bootstrapper: (bootstrapper) => bootstrapper
.withStatisticDelegate((baseUrl, requestCount) {
//print('$baseUrl -> $requestCount');
})
.withDebugMode(true)
.build(),
);
client.initialize();
final request = ListPostRequest(
page: 1,
perPage: 1,
order: Order.asc,
);
final wpResponse = await client.posts.list(request);
switch (wpResponse) {
case WordpressSuccessResponse():
final data = wpResponse.data; // List<Post>
break;
case WordpressFailureResponse():
final error = wpResponse.error; // WordpressError
break;
}
setState(() {});
}
`
With debug enabled, I can see the successful connection and even the WP data in the Response Text field of the response, but the wpResponse.data field remains empty.
Logs:
scratch_1.txt
Is this a bug or am I just implementing it incorrectly? Thanks for your help!
sorry, delete this issue.
This works fine without context being set to embed. The goal was to reduce the response size as I just needed Title, link, and Featured Image
Tested in the Android 13 Emulator.
The Client
WordpressClient.fromDioInstance(baseUrl: Uri.parse('https://thetailcompany.com/wp-json/wp/v2'), instance: initDio());
The final request url which works in a browser
https://thetailcompany.com/wp-json/wp/v2/posts?context=embed&page=1&per_page=10&order=desc
Request code
final ListPostRequest request = ListPostRequest(
page: 1,
perPage: 10,
order: Order.desc,
context: RequestContext.embed,
);
final WordpressResponse<List<Post>> wordpressPostResponse = await client.posts.list(request);
Exception name: type 'Null' is not a subtype of type 'bool'
Stacktrace
#0 new Post.fromJson (package:wordpress_client/src/responses/post_response.dart:73:15)
#1 WordpressClient._registerInternalInterfaces.<anonymous closure> (package:wordpress_client/src/wordpress_client_base.dart:367:31)
#2 MappedListIterable.elementAt (dart:_internal/iterable.dart:425:31)
#3 ListIterator.moveNext (dart:_internal/iterable.dart:354:26)
#4 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:27)
#5 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
#6 new List.of (dart:core-patch/array_patch.dart:39:18)
#7 ListIterable.toList (dart:_internal/iterable.dart:224:7)
#8 IRequestExecutor.list.<anonymous closure> (package:wordpress_client/src/request_executor_base.dart:325:72)
#9 WordpressRawResponse.map (package:wordpress_client/src/responses/wordpress_raw_response.dart:207:21)
#10 IRequestExecutor.list (package:wordpress_client/src/request_executor_base.dart:322:24)
<asynchronous suspension>
#11 _TailBlogState.getFeed (package:tail_app/Frontend/Widgets/tail_blog.dart:111:67)
<asynchronous suspension>
the Dio client
Dio initDio({skipSentry = false}) {
final Dio dio = Dio();
dio.httpClientAdapter = NativeAdapter();
dio.interceptors.add(
LogInterceptor(
requestBody: false,
requestHeader: false,
responseBody: false,
responseHeader: false,
request: false,
logPrint: (o) => dioLogger.finer(o.toString()),
),
);
if (!skipSentry) {
dio.addSentry(failedRequestStatusCodes: []);
}
return dio;
}
Hi, as mentioned in this issue #46 where it uses _fields
to decide which properties to get.
List<String>? fields
as param in the requests:ListPostRequest(
fields: ["id","categories"],
)
I think there is not conflict name, but maybe you want a convension for wordpress global parameters that start with _
.
We know that post.listRaw
and similar methods already exist, but you need to create the decoder.
It would be nice if there was a method that returned an instance of the model with everything nullable.
In this way the user avoids creating models for simple cases.
Use case:
I want to delete several posts from x categories
I'm only interested in the Id and categories, no other props because will be slowly and use more network data.
I would have to create a model with only this 2 props and the logic to decode..
If you already have a method that returns everything nullable, simply use the !
operator.
Before:
final rawResponse = await client.posts.listRaw(
ListPostRequest(
extra: {
'_fields': 'id,categories',
},
),
);
final response =
rawResponse.asResponse<List<WordpressPost>>(decoder: (data) {
final jsonList = data as List<dynamic>;
return jsonList.map((e) {
// Here we need to create a nullable model or
// a special model that have only this 2 fields
return NullablePost.fromJson(e as Map<String, Object?>);
}).toList();
});
final nullablePosts = response.asSuccess().data;
final id = nullablePosts.first.id!;
final categories = nullablePosts.first.categories!;
After
final response = await _wordpressClient.posts.listNullable(
ListPostRequest(
fields: ["id", "categories"]
),
);
final nullablePosts = response.asSuccess().data;
final id = nullablePosts.first.id!;
final categories = nullablePosts.first.categories!;
Well... the post.listNullable
and NullablePost
are the names that come to mind, maybe you have better prefix and suffix than nullable
in mind.
Thanks
Hi.
First of all, I personally thank you that created such a nice Wordpress library to implement APIs to Dart Native. I would like to ask you something. In your custom interface codes, you define PostCreateBuilder() class to request but inside the project, I can't import that class. It gives error which says PostCreateBuilder is not defined and does not suggest to add any library you wrote.
Can you fix that issue please?
Hi, there, in my case, the Rest API url of Wordpress is https://host.com/wp-json/wc/v3, but when we tried to call ListPostRequest , like the example, got error " https://host.com/posts?page=1&per_page=1&order=asc" , the path "/wp-json/wc/v3" was missed.
For example for posts
status:
Limit result set to posts assigned one or more statuses.
Default: publish
I can use more than 1 using this:
queryParameters: <String, dynamic>{
'status': 'publish,draft,future,pending,private',
},
Thanks
WordpressClient client = new WordpressClient('https://www.replaceme.com/', 'wp-json/wp/v2');
new is obsolete.
Links toJson() should return List and not Iterable
final response = await client.tags.list(ListTagRequest(perPage: 20));
or
final response = await client.tags.list(ListTagRequest(search: 'apple'));
In both cases above, the following error occurs.
Unhandled exception:
type 'int' is not a subtype of type 'String' of 'value'
#0 _LinkedHashMapMixin.[]= (dart:collection-patch/compact_hash.dart)
#1 MapExtensions.addIfNotNull (package:wordpress_client/src/utilities/extensions/map_extensions.dart:14:9)
#2 ListTagRequest.build (package:wordpress_client/src/requests/list/list_tag.dart:43:9)
#3 ListOperation.list (package:wordpress_client/src/operations/list.dart:8:37)
...
so I edit following two lines in package:wordpress_client/src/requests/list/list_tag.dart, then it works.
43: ..addIfNotNull('page', page.toString())
44: ..addIfNotNull('per_page', perPage.toString())
please, check it.
There are several cases in which it happens, I will show you 2
Case 1: for invalid port
try {
final client =
WordpressClient(baseUrl: Uri.parse('https://localhost:686868'))
..initialize();
final request = await client.posts.listRaw(
ListPostRequest(),
);
} catch (exception, stackTrace) {
print(stackTrace);
print(exception);
}
DioException [unknown]: null
Error: Invalid argument(s): Invalid port 686868
#0 DioMixin.fetch (package:dio/src/dio_mixin.dart:509:7)
<asynchronous suspension>
#1 InternalRequester.execute (package:wordpress_client/src/internal_requester.dart:212:22)
<asynchronous suspension>
Case 2: Port not available
try {
final client =
WordpressClient(baseUrl: Uri.parse('https://localhost:9999'))
..initialize();
final request = await client.posts.listRaw(
ListPostRequest(),
);
} catch (exception, stackTrace) {
print(stackTrace);
print(exception);
}
DioException [connection error]: The connection errored: The remote computer refused the network connection.
This indicates an error which most likely cannot be solved by the library.
Error: SocketException: The remote computer refused the network connection.
#0 DioMixin.fetch (package:dio/src/dio_mixin.dart:509:7)
<asynchronous suspension>
#1 InternalRequester.execute (package:wordpress_client/src/internal_requester.dart:212:22)
<asynchronous suspension>
I think is because you don't catch exceptions here, but I'm not sure when you map it.
wordpress_client/lib/src/internal_requester.dart
Lines 190 to 212 in 455d26c
Thanks
Hi first for your great package,
I have a problem extracting feature media URL, I tried in different ways:
posts[0].featuredImageUrl
and response.data[0]["wp:featuredmedia"]
but I get this error:
*** Request ***
uri: https://b2bboostify.co.uk/wp-json/wp/v2/posts?page=1&per_page=1&order=desc
method: GET
responseType: ResponseType.json
followRedirects: true
persistentConnection: true
connectTimeout: 0:01:00.000000
sendTimeout: 0:00:30.000000
receiveTimeout: 0:00:30.000000
receiveDataWhenStatusError: true
extra: {}
headers:
data:
null
<p>Morbi sagittis, sem quis lacinia faucibus, orci ipsum gravida tortor, vel interdum mi sapien ut justo. Nulla varius consequat magna, id molestie ipsum volutpat quis. Suspendisse consectetur fringilla luctus. Fusce id mi diam, non ornare orci. Pellentesque ipsum erat, facilisis ut venenatis eu, sodales vel dolor.</p>
<ul>
<li><strong>This is a unorder list</strong>. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, sem quis lacinia faucibus, orci ipsum gravida tortor, vel interdum mi sapien ut justo.</li>
<li>Nulla varius consequat magna, id molestie ipsum volutpat quis. Suspendisse consectetur fringilla luctus.</li>
<li>Fusce id mi diam, non ornare orci. Pellentesque ipsum erat, facilisis ut venenatis eu, sodales vel dolor.</li>
</ul>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, sem quis lacinia faucibus, orci ipsum gravida tortor, vel interdum mi sapien ut justo. Nulla varius consequat magna, id molestie ipsum volutpat quis. Suspendisse consectetur fringilla luctus. Fusce id mi diam, non ornare orci. Pellentesque ipsum erat, facilisis ut venenatis eu, sodales vel dolor.</p>
, protected: false}, excerpt: {rendered: <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sagittis, sem quis lacinia faucibus, orci ipsum gravida tortor, vel interdum mi sapien ut justo. Nulla varius consequat magna, id molestie ipsum volutpat quis. Suspendisse consectetur fringilla suctus. Pellentesque ipsum erat, facilisis ut venenatis eu, sodales vel dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit….</p>
, protected: false}, author: 1, featured_media: 8369, comment_status: open, ping_status: open, sticky: false, template: , format: standard, meta: {footnotes: }, categories: [2], tags: [], aioseo_notices: [], _links: {self: [{href: https://b2bboostify.co.uk/wp-json/wp/v2/posts/87}], collection: [{href: https://b2bboostify.co.uk/wp-json/wp/v2/posts}], about: [{href: https://b2bboostify.co.uk/wp-json/wp/v2/types/post}], author: [{embeddable: true, href: https://b2bboostify.co.uk/wp-json/wp/v2/users/1}], replies: [{embeddable: true, href: https://b2bboostify.co.uk/wp-json/wp/v2/comments?post=87}], version-history: [{count: 1, href: https://b2bboostify.co.uk/wp-json/wp/v2/posts/87/revisions}], predecessor-version: [{id: 8372, href: https://b2bboostify.co.uk/wp-json/wp/v2/posts/87/revisions/8372}], wp:featuredmedia: [{embeddable: true, href: https://b2bboostify.co.uk/wp-json/wp/v2/media/8369}], wp:attachment: [{href: https://b2bboostify.co.uk/wp-json/wp/v2/media?parent=87}], wp:term: [{taxonomy: category, embeddable: true, href: https://b2bboostify.co.uk/wp-json/wp/v2/categories?post=87}, {taxonomy: post_tag, embeddable: true, href: https://b2bboostify.co.uk/wp-json/wp/v2/tags?post=87}], curies: [{name: wp, href: https://api.w.org/{rel}, templated: true}]}}]
POSTS: 1
POST TITLE: {rendered: Satisfaction Lies in the Effort}
IMAGE POST: null
TITLE FORMATAT: Satisfaction Lies in the Effort
Please can you help me, thanks in advance!
In wordpress rest api if I add ?_embed at the end of the request, wordpress includes some other information to json at __embedded. Most notable is complete information about wp:featuredmedia including link to featured image (wp:featuredmedia[0].source_url). This bypasses the need to install separate plugins on host wordpress to include featured media url in json (which I am not allowed to the in some cases).
The
Im stuck here. Im unsure why :( Could you please extend your example folder with an working flutter example app that can just be started. I think this should help to start.
It should also be possible to pass it as a parameter in each request to make mocks based on the URL possible if the client is shared as a dependency.
I have an app where the user enters the url and consults information about the site.
You can also have multiple tabs open, so query multiple sites at same time with same client.
I pass the wordpress client as a dependency via provider or riverpod to each controller.
The idea is to be able to change the url in each request and also to be able to mock the response based on the url of the request for testing.
Thanks
``I'm having trouble getting a list of posts with status posts like "future". Looking at the logs, I believe it is due to a lack of authorization in the "client.posts.list" request.
Is there a way to add authorization at the request level?
Sorry if this has already been mapped out, but I haven't found a solution for this.
{"code":"rest_invalid_param","message":"Parâmetro(s) inválido(s): status","data":{"status":400,"params":{"status":"O status é proibido."},"details":{"status":{"code":"rest_forbidden_status","message":"O status é proibido.","data":{"status":401}}}}}
Thanks
Hi @ArunPrakashG ,
Thanks again for your great support, I have a big problem loading images from a WordPress website in a Flutter web app with Canvaskit renderer, in a release mode I get this error:
Access to fetch at 'https://b2bboostify.co.uk/wp-content/uploads/2023/10/two-young-happy-businesswomen-celebrating-project-success-office.jpg' from origin 'https://b2boostify.web.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I understand it's a very common problem, do you know a solution for this issue?
Thanks in advance!
Please help me to understand how can I control what the ListPostRequest()
returns. The documentation (https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_fields) allows to limit the response, but it seems there's no way in the plugin to specify what fields are returned. In the current state the request retrieves full post content which is not always requied. For example I would prefer to get only a list of titles, excerpts and URLs from the API. Is there a way to do that?
I had to import
import 'package:wordpress_client/requests.dart';
import 'package:wordpress_client/responses.dart';
import 'package:wordpress_client/wordpress_client.dart';
why?
How can I log into my app?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.