Aleksi44 / wagtailsvg

Wagtail + SVG
https://pypi.org/project/wagtailsvg/
GNU General Public License v3.0
35 stars 26 forks source link

SvgChooserBlock field to graphql #16

Open warcivil opened 2 years ago

warcivil commented 2 years ago

is there any way to add the SvgChooserBlock field to graphql?

Aleksi44 commented 2 years ago

Hi @warcivil

I've never tried it but I think it's possible.

Can you give me more context? Libraries used for this? Attempts and code you tried?

warcivil commented 2 years ago

I use a wagtail and a wagtail grapple, I create a block and specify for example image=Svg ChooserBlock() actually this is all if you need additional information, write thank you!

kbayliss commented 2 years ago

Hey @warcivil ,

Official SVG support is coming to Wagtail soon (it should be in version five), though you can use the below with wagtail-grapple and wagtailsvg.

(note: this example is for wagtail>=3, though if you adjust the import paths and change WAGTAILADMIN_BASE_URL for BASE_URL then it'll work for wagtail<3 too)

In graphene_fields.py:

import graphene
from django.conf import settings
from grapple.types import collections, tags

class SVGFieldObjectType(graphene.ObjectType):
    title = graphene.String(required=True)
    filename = graphene.String(required=True)
    url = graphene.String(required=True)
    url_path = graphene.String(required=True)
    tags = graphene.List(tags.TagObjectType)
    collection = graphene.Field(
        collections.CollectionObjectType, required=True
    )

    def resolve_tags(self, info, **kwargs):
        return self.tags.all()

    def resolve_url(self, info, **kwargs):
        # URL path including domain name
        if self.url[0] == "/":
            return f"{settings.WAGTAILADMIN_BASE_URL}{self.url}"
        return self.url

    def resolve_url_path(self, info, **kwargs):
        # URL path excluding domain
        return self.url

In blocks.py

from grapple.helpers import register_streamfield_block
from grapple.models import GraphQLField
from wagtailsvg.blocks import SvgChooserBlock

from your_project import graphene_fields

@register_streamfield_block
class YourBlock():
    svg = SvgChooserBlock(label="SVG")

    graphql_fields = [
        GraphQLField(
            field_name="svg",
            field_type=graphene_fields.SVGFieldObjectType,
            required=True,
        ),
    ]

In queries.py:

import graphene
from grapple.types.structures import QuerySetList
from grapple.utils import resolve_queryset
from wagtailsvg.models import Svg

from your_project import graphene_fields

class SVGQuery:
    svg = graphene.Field(
        graphene_fields.SVGFieldObjectType,
        id=graphene.ID(),
    )

    svgs = QuerySetList(
        graphene.NonNull(graphene_fields.SVGFieldObjectType),
        enable_search=True,
        required=True,
        collection=graphene.Argument(
            graphene.ID, description="Filter by collection ID"
        ),
    )

    def resolve_svg(self, info, id, **kwargs):
        try:
            return Svg.objects.filter(
                collection__view_restrictions__isnull=True
            ).get(pk=id)
        except BaseException:
            return None

    def resolve_svgs(self, info, **kwargs):
        qs = Svg.objects.filter(collection__view_restrictions__isnull=True)
        return resolve_queryset(qs, info, **kwargs)

In wagtail_hooks.py:

from wagtail import hooks

from your_project import queries

@hooks.register("register_schema_query")
def register_extra_schema_queries(query_mixins):
    query_mixins += [
        queries.SVGQuery,
    ]