🚀 Generuj i optymalizuj wyróżniony obraz posta za pomocą AI, z nowym Gato GraphQL v2
Z przyjemnością ogłaszamy, że Gato GraphQL v2.0 zostało wydane!
Dzięki tej nowej wersji i rozszerzeniom PRO możesz używać generatywnej AI do tworzenia wyróżnionych obrazów dla postów, które nie mają miniatury.
Poniżej znajdują się najważniejsze zmiany dodane w v2.0 (aby zobaczyć wszystkie zmiany, przejdź do informacji o wydaniu na GitHub).
Dodano mutację createMediaItem
Mutacja createMediaItem umożliwia przesyłanie plików do Biblioteki multimediów. Oferuje 2 sposoby dostarczenia pliku źródłowego:
- Przez URL
- Bezpośrednio z jego zawartości
Wykonanie tego zapytania:
mutation CreateMediaItems {
fromURL: createMediaItem(input: {
from: {
url: {
source: "https://gatographql.com/assets/GatoGraphQL-logo.png"
}
}
caption: "Gato GraphQL logo"
altText: "This is the Gato GraphQL logo"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
...MediaItemData
}
}
directlyByContents: createMediaItem(input: {
from: {
contents: {
body: """
<html>
<body>
Hello world!
</body>
</html>
"""
filename: "hello-world.html"
}
}
title: "Hello world!"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
...MediaItemData
}
}
}
fragment MediaItemData on Media {
altText
caption
mimeType
slug
src
title
}...wyprodukuje:
{
"data": {
"fromURL": {
"mediaItemID": 1380,
"status": "SUCCESS",
"errors": null,
"mediaItem": {
"altText": "This is the Gato GraphQL logo",
"caption": "Gato GraphQL logo",
"mimeType": "image/png",
"slug": "gatographql-logo-png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"title": "GatoGraphQL-logo.png"
}
},
"directlyByContents": {
"mediaItemID": 1381,
"status": "SUCCESS",
"errors": null,
"mediaItem": {
"altText": "",
"caption": "",
"mimeType": "text/html",
"slug": "hello-world-html",
"src": "https://mysite.com/wp-content/uploads/hello-world.html",
"title": "Hello world!"
}
}
}
}Dodano pola myMediaItemCount, myMediaItems i myMediaItem
Zalogowani użytkownicy mogą teraz pobierać wszystkie swoje pliki multimedialne.
Wykonanie tego zapytania:
query GetMediaItems {
me {
slug
}
myMediaItemCount
myMediaItems(pagination: {
limit: 3
}) {
...MediaItemData
}
myMediaItem(by: { id: 1380 }) {
...MediaItemData
}
}
fragment MediaItemData on Media {
id
mimeType
src
author {
slug
}
}...wyprodukuje:
{
"data": {
"me": {
"slug": "admin"
},
"myMediaItemCount": 2,
"myMediaItems": [
{
"id": 1380,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"author": {
"slug": "admin"
}
},
{
"id": 1365,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/browser.png",
"author": {
"slug": "admin"
}
}
],
"myMediaItem": {
"id": 1380,
"mimeType": "image/png",
"src": "https://mysite.com/wp-content/uploads/GatoGraphQL-logo.png",
"author": {
"slug": "admin"
}
}
}
}Dodano predefiniowane utrwalone zapytanie "Generate a post's featured image using AI and optimize it"
(Ta funkcjonalność wymaga rozszerzeń PRO.)
Nowe predefiniowane utrwalone zapytanie z tytułem "Generate a post's featured image using AI and optimize it" zostało dodane.
Używa generatywnej AI do tworzenia obrazów dla postów bez wyróżnionego obrazu, korzystając z tytułu posta jako promptu. Możemy wybrać spośród następujących dostawców usług:
Zapytanie najpierw sprawdza, czy post ma wyróżniony obraz. Jeśli nie ma, tworzy go, wywołując usługę generatywnej AI. Musimy podać odpowiedni klucz API dla wybranej usługi.
Ponieważ obrazy generatywnej AI nie są zoptymalizowane dla sieci (obrazy OpenAI mogą ważyć nawet 3 MB!), zapytanie wysyła również nowo wygenerowany obraz do TinyPNG, aby go skompresować. Musimy podać klucz API do korzystania z tej usługi.
Na koniec zapytanie tworzy nowy element multimedialny z obrazem (używając tytułu posta jako nazwy pliku dla załącznika, obciętego do 20 znaków) i ustawia go jako wyróżniony obraz posta.
Oto zapytanie GraphQL:
query InitializeVariables(
$openAIAPIKey: String
$stableDiffusionAPIKey: String
$tinyPngAPIKey: String
)
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
isFeaturedImageMissing: _echo(value: false)
@export(as: "isFeaturedImageMissing")
@remove
generatedImageURL: _echo(value: null)
@export(as: "generatedImageURL")
@remove
isImageGenerated: _echo(value: false)
@export(as: "isImageGenerated")
@remove
mimeType: _echo(value: null)
@export(as: "mimeType")
@remove
isMediaItemCreated: _echo(value: false)
@export(as: "isMediaItemCreated")
@remove
useOpenAI: _notEmpty(value: $openAIAPIKey)
@export(as: "useOpenAI")
@remove
useStableDiffusion: _notEmpty(value: $stableDiffusionAPIKey)
@export(as: "useStableDiffusion")
@remove
useTinyPng: _notEmpty(value: $tinyPngAPIKey)
@export(as: "useTinyPng")
@remove
}
query ExportPostData(
$postId: ID!
)
@depends(on: "InitializeVariables")
{
post(by: { id: $postId }) {
hasFeaturedImage
isFeaturedImageMissing: hasFeaturedImage
@boolOpposite
@export(as: "isFeaturedImageMissing")
title
@export(as: "postTitle")
mediaItemFilename: rawTitle
@default(value: "untitled", condition: IS_EMPTY)
@strLowerCase
@strSubstr(offset: 0, length: 20)
@export(as: "filename")
@remove
}
}
query MaybeGenerateImageUsingOpenAI(
$openAIAPIKey: String
$imageSize: String! = "1024x1024" # 256x256, 512x512, or 1024x1024 pixels
)
@depends(on: "ExportPostData")
@include(if: $isFeaturedImageMissing)
@include(if: $useOpenAI)
{
openAIResponse: _sendJSONObjectItemHTTPRequest(input: {
url: "https://api.openai.com/v1/images/generations",
method: POST,
options: {
auth: {
password: $openAIAPIKey
},
json: {
prompt: $postTitle,
size: $imageSize,
n: 1,
response_format: "url",
}
}
})
@underJSONObjectProperty(by: { key: "data" })
@underArrayItem(index: 0)
@underJSONObjectProperty(by: { key: "url" })
@export(as: "generatedImageURL")
openAPIImageCaption: _sprintf(
string: "Image created by DALL-E using prompt: '%s'",
values: [$postTitle]
)
@export(as: "imageCaption")
openAIMediaItemFilename: _sprintf(
string: "%s.png",
values: [$filename]
)
@export(as: "filename")
}
query MaybeGenerateImageUsingStableDiffusion(
$stableDiffusionAPIKey: String
$width: Int! = 1024
$height: Int! = 1024
)
@depends(on: "ExportPostData")
@include(if: $isFeaturedImageMissing)
@include(if: $useStableDiffusion)
{
stableDiffusionResponse: _sendJSONObjectItemHTTPRequest(input: {
url: "https://stablediffusionapi.com/api/v3/text2img",
method: POST,
options: {
json: {
key: $stableDiffusionAPIKey
prompt: $postTitle,
width: $width
height: $height
samples: 1
}
}
})
@underJSONObjectProperty(by: { key: "output" })
@underArrayItem(index: 0)
@export(as: "generatedImageURL")
stableDiffusionImageCaption: _sprintf(
string: "Image created by Stable Diffusion using prompt: '%s'",
values: [$postTitle]
)
@export(as: "imageCaption")
stableDiffusionMediaItemFilename: _sprintf(
string: "%s.png",
values: [$filename]
)
@export(as: "filename")
}
query CheckIsImageGenerated
@depends(on: [
"MaybeGenerateImageUsingOpenAI",
"MaybeGenerateImageUsingStableDiffusion"
])
@include(if: $isFeaturedImageMissing)
{
isImageGenerated: _notEmpty(value: $generatedImageURL)
@export(as: "isImageGenerated")
}
query MaybeCompressGeneratedImage(
$tinyPngAPIKey: String
)
@depends(on: "CheckIsImageGenerated")
@include(if: $isImageGenerated)
@include(if: $useTinyPng)
{
compressedImageResponse: _sendHTTPRequest(input: {
url: "https://api.tinify.com/shrink",
method: POST,
options: {
auth: {
password: $tinyPngAPIKey
},
headers: [
{
name: "Content-Type",
value: "application/json"
}
],
json: {
source: {
url: $generatedImageURL
}
}
}
}) {
body
@remove
bodyJSONObject: _strDecodeJSONObject(string: $__body)
mimeType: _objectProperty(
object: $__bodyJSONObject
by: { path: "output.type" }
)
@export(as: "mimeType")
generatedImageURL: header(name: "Location")
@export(as: "generatedImageURL")
}
}
mutation CreateMediaItemFromGeneratedImage
@depends(on: "MaybeCompressGeneratedImage")
@include(if: $isImageGenerated)
{
createMediaItem(input: {
from: {
url: {
source: $generatedImageURL
filename: $filename
}
}
title: $postTitle
caption: $imageCaption
altText: $postTitle
mimeType: $mimeType
}) {
mediaItemID
@export(as: "mediaItemID")
isMediaItemCreated: _notNull(value: $__mediaItemID)
@export(as: "isMediaItemCreated")
@remove
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
altText
caption
mimeType
slug
src
title
}
}
}
mutation SetMediaItemAsPostFeaturedImage(
$postId: ID!
)
@depends(on: "CreateMediaItemFromGeneratedImage")
@include(if: $isMediaItemCreated)
{
setFeaturedImageOnCustomPost(input: {
customPostID: $postId
mediaItemBy: { id: $mediaItemID }
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
customPost {
__typename
...on CustomPost {
featuredImage {
id
altText
caption
mimeType
slug
src
title
}
}
}
}
}[PRO] Dodano pole _dataMatrixOutputAsCSV w rozszerzeniu Helper Function Collection
(Ta funkcjonalność została dodana do rozszerzeń PRO.)
Pole _dataMatrixOutputAsCSV zostało dodane do rozszerzenia Helper Function Collection (i wszystkich pakietów zawierających to rozszerzenie).
To pole przyjmuje macierz danych i produkuje ciąg CSV. Na przykład to zapytanie:
csv: _dataMatrixOutputAsCSV(
fields:
["Name", "Surname", "Year"]
data: [
["John", "Smith", 2003],
["Pedro", "Gonzales", 2012],
["Manuel", "Perez", 2008],
["Jose", "Pereyra", 1999],
["Jacinto", "Bloomberg", 1998],
["Jun-E", "Song", 1983],
["Juan David", "Santamaria", 1943],
["Luis Miguel", null, 1966],
]
)...wyprodukuje:
{
"data": {
"csv": "Name,Surname,Year\nJohn,Smith,2003\nPedro,Gonzales,2012\nManuel,Perez,2008\nJose,Pereyra,1999\nJacinto,Bloomberg,1998\nJun-E,Song,1983\nJuan David,Santamaria,1943\nLuis Miguel,,1966\n"
}
}Ta funkcjonalność pozwala nam eksportować dane z naszej witryny WordPress do Google Sheets lub innych narzędzi.
Na przykład to zapytanie pobierze dane 100 postów i utworzy plik CSV, który zostanie przesłany do Biblioteki multimediów, z kolumnami ID, Title, Slug, Author name, Published date, URL i Content:
query ExportPostData(
$limit: Int! = 100,
$offset: Int! = 0
) {
posts(
pagination: { limit: $limit, offset: $offset },
sort: { by: ID, order: ASC }
) {
id @export(as: "postIds", type: LIST)
title @export(as: "postTitles", type: LIST)
slug @export(as: "postSlugs", type: LIST)
author {
name @export(as: "postAuthorNames", type: LIST)
}
dateStr(format: "d/m/Y") @export(as: "postPublishedDates", type: LIST)
url @export(as: "postUrls", type: LIST)
content @export(as: "postContents", type: LIST)
}
}
query CreateDataMatrix
@depends(on: "ExportPostData")
{
csvDataMatrix: _echo(value: $postIds)
@underEachArrayItem(
passIndexOnwardsAs: "key"
passValueOnwardsAs: "postId"
affectDirectivesUnderPos: [1, 2, 3, 4, 5, 6, 7]
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postTitles,
position: $key,
},
passOnwardsAs: "postTitle"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postSlugs,
position: $key,
},
passOnwardsAs: "postSlug"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postAuthorNames,
position: $key,
},
passOnwardsAs: "postAuthorName"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postPublishedDates,
position: $key,
},
passOnwardsAs: "postPublishedDate"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postUrls,
position: $key,
},
passOnwardsAs: "postUrl"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $postContents,
position: $key,
},
passOnwardsAs: "postContent"
)
@applyField(
name: "_echo",
arguments: {
value: [
$postId,
$postTitle,
$postSlug,
$postAuthorName,
$postPublishedDate,
$postUrl,
$postContent
]
},
setResultInResponse: true
)
@export(as: "csvDataMatrix")
}
query OutputCSV
@depends(on: "CreateDataMatrix")
{
csvString: _dataMatrixOutputAsCSV(
fields: [
"ID",
"Title",
"Slug",
"Author name",
"Published date",
"URL",
"Content",
]
data: $csvDataMatrix
)
@export(as: "csvString")
}
mutation CreateMediaItem
@depends(on: "OutputCSV")
{
createMediaItem(input: {
from: {
contents: {
body: $csvString
filename: "posts.csv"
}
}
title: "Post data as CSV"
}) {
mediaItemID
status
errors {
__typename
...on ErrorPayload {
message
}
}
mediaItem {
mimeType
slug
src
title
}
}
}Przygotowanie do v3.0
Mamy nadzieję, że spodoba ci się nowe funkcje w tej najnowszej wersji.
Czy jest jakaś nowa funkcja, którą chciałbyś, aby Gato GraphQL miało w przyszłości? Wyślij nam wiadomość i daj nam znać.
Ciesz się!