在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):markhuot/craftql开源软件地址(OpenSource Url):https://github.com/markhuot/craftql开源编程语言(OpenSource Language):JavaScript 86.5%开源软件介绍(OpenSource Introduction):A drop-in GraphQL server for your Craft CMS implementation. With zero configuration, CraftQL allows you to access all of Craft's features through a familiar GraphQL interface. ExamplesOnce installed, you can test your installation with a simple Hello World, {
helloWorld
} If that worked, you can now query Craft CMS using almost the exact same syntax as your Twig templates. {
entries(section:[news], limit:5, search:"body:salty") {
...on News {
title
url
body
}
}
} CraftQL provides a top level query fetchNews { # The query, `query fetchNews` is completely optional
entries(section:[news]) { # Arguments match `craft.entries`
...on News { # GraphQL is strongly typed, so you must specify each Entry Type you want data from
id # A field to return
title # A field to return
body # A field to return
}
}
} Types are automatically created for every Entry Type in your install. If you have a section named query fetchNews {
entries(section:[news]) {
...on News { # Any fields on the News entry type
id
title
body
}
...on NewsPressRelease { # Any fields on the Press Release entry type
id
title
body
source
contactInfo
downloads {
title
url
}
}
}
} To modify content make sure your token has write access and then use the top level mutation createNewEntry($title:String, $body:String) {
upsertNews(
title:$title,
body:$body,
) {
id
url
}
} The above would be passed with variables such as, {
"title": "My first mutation!",
"body": "<p>Here's the body of my first mutation</p>",
} Matrix FieldsWorking with Matrix Fields are similar to working with Entry Types: if you have a Matrix Field with a handle of {
entries(section: [news]) {
... on News {
id
title
body { # Your Matrix Field
... on BodyText { # Block Type
__typename # Ensures the response has a field describing the type of block
blockHeading # Fields on Block Type, uses field handle
blockContent # Fields on Block Type, uses field handle
}
... on BodyImage { # Block Type
__typename # Ensures the response has a field describing the type of block
blockDescription # Fields on Block Type, uses field handle
image { # Fields on Block Type, uses field handle
id # Fields on image field on Block Type, uses field handles
}
}
}
}
}
} DatesAll Dates in CraftQL are output as {
entries {
dateCreated # outputs 1503368510
}
} Dates can be converted to a human friendly format with the {
entries {
dateCreated @date(as:"F j, Y") # outputs August 21, 2017
}
} RelationshipsRelated entries can be fetched in several ways, depending on your needs. Similar to {
entries(relatedTo:[{element:63}], section:comments) {
...on Comments {
id
author {
name
}
commentText
}
}
} Note, the The above approach, typically, requires separate requests for the source content and the related content. That equates to extra HTTP requests and added latency. If you're using the "connection" approach to CraftQL you can fetch relationships in a single request using the {
entriesConnection(id:63) {
edges {
node {
...on Post {
title
body
}
}
relatedEntries(section:comments) {
edges {
node {
...on Comment {
author {
name
}
commentText
}
}
}
}
}
}
} TransformsYou can ask CraftQL for image transforms by specifying an argument to any asset field. Note: for this to work the volume storing the image must have "public URLs" enabled in the volume settings otherwise CraftQL will return If you have defined named transforms within the Craft UI you can reference the transform by its handle, {
entries {
...on Post {
imageFieldHandle {
thumbnail: url(transform: thumb)
}
}
}
} You can also specify the exact crop by using the {
entries {
...on Post {
imageFieldHandle {
poster: url(crop: {width: 1280, height: 720, position: topLeft, quality: 50, format: jpg})
}
}
}
} DraftsDrafts are best fetched through an edge node on the {
entriesConnection(id:63) {
edges {
node { # the published node, as `craft.entries` would return
id
title
}
drafts { # an array of drafts
edges {
node { # the draft content
id
title
...on Post { # draft fields are still referenced by entry type, as usual
body
}
}
draftInfo { # the `draftInfo` field returns the meta data about the draft
draftId
name
notes
}
}
}
}
}
} Categories and TagsTaxonomy can be queried through the top level {
categories { # lists all categories, or use `tags` to get all tags
id
title
}
} For added functionality query categories and tags through their related {
categoriesConnection {
totalCount
edges {
node {
title # the category title
}
relatedEntries {
entries {
title # an entry title, that's related to this category
}
}
}
}
} UsersUsers can be queried via a top-level {
users {
id
name
email
}
} You can also mutate users via the mutation {
upsertUser(id:1, firstName:"Mark", lastName:"Huot") {
id
name # returns `Mark Huot` after the mutation
}
} Permissions can be set as well, but you must always pass the full list of permissions for the user. E.g., mutation {
upsertUser(id:1, permissions:["accessCp","editEntries:17","createEntries:17","deleteEntries:17"]) {
id
name # returns `Mark Huot` after the mutation
}
} SecurityCraftQL supports GraphQl field level permissions. By default a token will have no rights. You must click into the "Scopes" section to adjust what each token can do. Scopes allow you to configure which GraphQL fields and entry types are included in the schema. Third-party Field SupportTo add CraftQL support to your third-party field plugin you will need to listen to the Event::on(\my\custom\Field::class, 'craftQlGetFieldSchema', function (\markhuot\CraftQL\Events\GetFieldSchema $event) {
// the custom field is passed as the event sender
$field = $event->sender;
// the schema exists on a public property of the event
$event->schema
// you can add as many fields as you need to for your field. Typically you'll
// pass your field in, which will automatically set the name and description
// based on the Craft config.
->addStringField($field);
// the schema is a fluent builder and can be chained to set multiple properties
// of the custom field
$event->schema->addEnumField('customField')
->lists()
->description('This is a custom description for the field')
->values(['KEY' => 'Label', 'KEY2' => 'Another label']);
}); The above, when called for a Post entry type on the type CustomFieldEnum {
# Label
KEY
# Another label
KEY2
}
type Post {
# The field instructions are automatically included
excerpt: String
# This is a custom description for the field
customField: [CustomFieldEnum]
} If your custom field resolves an object you can expose that to CraftQL as well. For example, if you are implementing a custom field that exposes a map, with a latitude, longitute, and a zoom level, it may look like, Event::on(\craft\base\Field::class, 'craftQlGetFieldSchema', function ($event) {
$field = $event->sender;
$object = $event->schema->createObjectType('MapPoint')
->addStringField('lat')
->addStringField('lng')
->addStringField('zoom');
$event->schema->addField($field)->type($object);
}); RoadmapNo software is ever done. There's a lot still to do in order to make CraftQL feature complete. Some of the outstanding items include,
Requirements
InstallationIf you don't have Craft 3 installed yet, do that first: $ composer create-project craftcms/craft my-awesome-site -s beta Once you have a running version of Craft 3 you can install CraftQL with Composer: $ composer require markhuot/craftql:^1.0.0 Running the CLI serverCraftQL ships with a PHP-native web server. When running CraftQL through the provided web server the bootstrapping process will only happen during the initial start up. This has the potential to greatly speed up responses times since PHP will persist state between requests. In general, I have seen performance improvements of 5x (500ms to <100ms). Caution: this can also create unintended side effects since Craft is not natively built to run this way. Do not use this in production it could lead to memory leaks, server fires, and IT pager notifications :).
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论