વર્ડપ્રેસ ડેટા રેકોર્ડ્સ મેળવવા

આ પાઠમાં તમે વર્ડપ્રેસ ડેટા મેળવવાનું શીખશો. આપણે વર્ડપ્રેસ પેજની એક ન્યુનતમ અને ફિલ્ટર કરી શકાય તેવી સૂચિ તૈયાર કરીશું:

પગલું ૧: યુઝર ઇન્ટરફેસનું રૂપરેખા તૈયાર કરો

ચાલો પેજોની સૂચિ દર્શાવવા માટે એક ન્યૂનતમ React કોમ્પોનેન્ટ બનાવવાથી શરૂઆત કરીએ:

function MyFirstApp() {
    const pages = [{ id: 'mock', title: 'Sample page' }]
    return <PagesList pages={ pages }/>;
}
 
function PagesList( { pages } ) {
    return (
        <ul>
            { pages?.map( page => (
                <li key={ page.id }>
                    { page.title }
                </li>
            ) ) }
        </ul>
    );
}

નોંધ લો કે આ કોમ્પોનેન્ટ હજુ સુધી કોઈ પણ ડેટા લાવતું નથી, માત્ર હાર્ડકોડ કરેલી પેજોની સૂચિ દર્શાવે છે. જ્યારે તમે પેજને રિફ્રેશ કરો, ત્યારે તમારે નીચે બતાવેલ જેવું પરિણામ દેખાવું જોઈએ:


પગલું ૨: સૂચિ વાસ્તવિક ડેટાથી ભરવો

હાર્ડકોડ કરેલું નમૂનાઓ પેજ ખાસ ઉપયોગી નથી. આપણે તમારા અસલ વર્ડપ્રેસ પેજ્સ બતાવવા છે, એટલે ચાલો વર્ડપ્રેસ REST API માંથી પેજોની સાચી સૂચિ લાવીએ.

આપણે શરૂઆત કરીએ તે પહેલાં, પ્રથમ ખાતરી કરીએ કે લાવવા માટે આપણે ખરેખરમાં કેટલાક પેજ્સ છે. WPAdmin માં સાઇડબાર મેનૂથી “Pages” પર જાઓ અને જુઓ કે ત્યાં ઓછામાં ઓછા ચાર કે પાંચ પેજ્સ દેખાય છે કે નહીં:

જો ત્યાં પેજિસ દેખાતા ન હોય, તો આગળ વધો અને થોડા પેજ બનાવો – તમે ઉપરના સ્ક્રીનશોટમાં દર્શાવ્યા છે એવા જ શીર્ષકોનો ઉપયોગમાં લઈ શકો છો. ખાતરી કરો કે તમે તે પબ્લિશ કરો, ફક્ત સેવ નહિ કરો.

હવે જ્યારે આપણે પાસે ડેટા તૈયાર છે, તો ચાલો હવે કોડમાં ઊંડા જઈએ. આપણે @wordpress/core-data પેકેજનો ઉપયોગ કરીશું, જે વર્ડપ્રેસ કોર API સાથે કામ કરવા માટે રિઝોલ્વર્સ, સિલેક્ટર્સ અને ક્રિયાઓ પૂરાં પાડે છે. @wordpress/core-data @wordpress/data પેકેજના આધારે બનાવાયું છે.

પેજોની સૂચિ મેળવવા માટે, આપણે getEntityRecords સિલેક્ટરનો ઉપયોગ કરીશું. સારાંશરૂપે કહીએ તો, તે યોગ્ય API રિક્વેસ્ટ કરશે, પરિણામને વિનંતી કરશે અને જરૂરિયાત મુજબ રેકોર્ડોની સૂચિ પાછી આપશે. આ રીતે તેનો ઉપયોગ થાય છે:

wp.data.select( 'core' ).getEntityRecords( 'postType', 'page' )

જો તમે નીચે આપેલો કોડ સ્નિપેટ તમારા બ્રાઉઝરના ડેવલપર ટૂલ્સમાં ચલાવશો, તો તે null પાછું આપે છે. કેમ? કારણ કે getEntityRecords રિઝોલ્વર પેજો માટે રિક્વેસ્ટ ત્યારે જ કરે છે જ્યારે સિલેક્ટર પ્રથમવાર ચલાવવામાં આવે. જો તમે થોડી વાર રાહ જુઓ અને ફરીથી ચલાવો, તો તે બધી પેજોની સૂચિ પાછી આપે છે.

પ્રતિબિંબ

આ કોર્સમાં આપેલા કોડ સ્નિપેટ્સ અજમાવવા માટે તમારા બ્રાઉઝરની ડેવલપર ટૂલ્સનો ઉપયોગ કરો. જાણકારી સાથે ક્રિયા કરીને વધુ શીખશો.

તે જ રીતે, MyFirstApp કમ્પોનન્ટને ડેટા ઉપલબ્ધ થયા પછી સિલેક્ટરને ફરીથી ચલાવવાની જરૂર પડે છે. આ જ કામ useSelect હૂક કરે છે:

import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
 
function MyFirstApp() {
    const pages = useSelect(
        select =>
            select( coreDataStore ).getEntityRecords( 'postType', 'page' ),
        []
    );
    // ...
}

ધ્યાનમાં લો કે આપણે index.js ફાઈલની અંદર import સ્ટેટમેન્ટનો ઉપયોગ કર્યો છે. આ પ્લગઇન ને wp_enqueue_script દ્વારા જરૂરી ડિપેન્ડન્સીઝ આપમેળે લોડ કરવાની સુવિધા આપે છે. coreDataStore ના કોઈપણ સંદર્ભો તે જ wp.data સંદર્ભમાં રૂપાંતરિત થાય છે જે આપણે બ્રાઉઝરના ડેવલપર ટૂલ્સમાં ઉપયોગ કરીએ છીએ.

useSelect બે આર્ગ્યુમેન્ટ લે છે: એક કોલબેક અને ડિપેન્ડન્સીઝ. સામાન્ય રીતે, જ્યારે ડિપેન્ડન્સીઝ અથવા અંતર્ગત ડેટા સ્ટોર બદલાય છે ત્યારે તે કોલબેકને ફરીથી ચલાવે છે. તમે ડેટા મોડ્યુલ ડોક્યુમેન્ટેશન માં useSelect વિશે વધુ શીખી શકો છો.

આ બધું એકસાથે મેળવીને, આપણને નીચેનું કોડ મળે છે:

import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
 
function MyFirstApp() {
    const pages = useSelect(
        select =>
            select( coreDataStore ).getEntityRecords( 'postType', 'page' ),
        []
    );
    return <PagesList pages={ pages }/>;
}
 
function PagesList( { pages } ) {
    return (
        <ul>
            { pages?.map( page => (
                <li key={ page.id }>
                    { decodeEntities( page.title.rendered ) }
                </li>
            ) ) }
        </ul>
    )
}

નોંધ કરો કે પોસ્ટ ટાઇટલમાં &aacute; જેવી HTML એન્ટિટીઝ હોઈ શકે છે, તેથી આપણે તેમને તેઓ જે પ્રતીકોને દર્શાવે છે જેમ કે á, તેમ બદલવા માટે decodeEntities ફંક્શનનો ઉપયોગ કરવાની જરૂર છે.

પેજ રિફ્રેશ કરતા તમે આવું કંઈક લિસ્ટ જોઈ શકો છો:

પગલું ૩: સૂચિને ટેબલમાં ફેરવો

function PagesList( { pages } ) {
    return (
        <table className="wp-list-table widefat fixed striped table-view-list">
            <thead>
                <tr>
                    <th>Title</th>
                </tr>
            </thead>
            <tbody>
                { pages?.map( page => (
                    <tr key={ page.id }>
                        <td>{ decodeEntities( page.title.rendered ) }</td>
                    </tr>
                ) ) }
            </tbody>
        </table>
    );
}

હમણાં માટે પેજોની સૂચિ ટૂંકી છે; તેમ છતાં, તે મોટી થાય છે તેમ તેને હેન્ડલ કરવી વધુ મુશ્કેલ બને છે. વર્ડપ્રેસ એડમિન્સ સામાન્ય રીતે આ સમસ્યાનું ઉકેલ લાવવા માટે સર્ચ બોક્સ ઉમેરે છે – ચાલો આપણે પણ એવું જ કરીએ!

ચાલો શોધ ફીલ્ડ ઉમેરવાથી શરૂઆત કરીએ:

import { SearchControl } from '@wordpress/components';
import { useState, render } from '@wordpress/element';
 
function MyFirstApp() {
    const [searchTerm, setSearchTerm] = useState( '' );
    // ...
    return (
        <div>
            <SearchControl
                onChange={ setSearchTerm }
                value={ searchTerm }
            />
            {/* ... */ }
        </div>
    )
}

ધ્યાન આપો કે આપણે input ટૅગનો ઉપયોગ કરવાનો બદલે SearchControl કોમ્પોનેન્ટનો ઉપયોગ કર્યો છે. તે આવું દેખાય છે:

પ્રતિબિંબ

વર્ડપ્રેસ કમ્પોનેન્ટ્સ યૂઝર ઈન્ટરફેસ તૈયાર કરવાનું અત્યંત સરળ બનાવે છે. આ પુનઃવપરાશયોગ્ય બિલ્ડિંગ બ્લૉક્સ સામાન્ય સમસ્યાઓનું સમાધાન કરે છે અને આખા વર્ડપ્રેસ એડમિન સાથે સુમેળમાં રહે છે.

ફીલ્ડ શરૂઆતમાં ખાલી હોય છે, અને તેની સામગ્રી searchTerm સ્ટેટ વેલ્યૂમાં સંગ્રહાય છે. જો તમે useState હૂકથી પરિચિત નથી, તો તમે React ના ડોક્યુમેન્ટશન માં વધુ જાણકારી મેળવી શકો છો.

હવે આપણે ફક્ત તે પેજીસ માટે વિનંતી કરી શકીયે છીએ જે searchTerm ને મેળ ખાતા હોય. WordPress API ડોક્યુમેન્ટશન તપાસ્યા બાદ, આપણે જોઈ શકાય છે કે /wp/v2/pages એન્ડપોઇન્ટ search ક્વેરી પેરામીટર સ્વીકારે છે અને તેને એવા પરિણામોને મર્યાદિત કરવા માટે ઉપયોગ કરે છે જે ચોક્કસ શબ્દ સાથે મેળ ખાતા હોય. પણ આપણે તેનો ઉપયોગ કેવી રીતે કરી શકીએ? આપણે નીચે આપેલા પ્રમાણે getEntityRecords ને ત્રીજા આર્ગ્યુમેંટ તરીકે કસ્ટમ ક્વેરી પેરામિટર્સ આપી શકીએ છીએ:

wp.data.select( 'core' ).getEntityRecords( 'postType', 'page', { search: 'home' })

આ સ્નિપેટને તમારા બ્રાઉઝરના ડેવ ટૂલ્સમાં ચલાવવાથી /wp/v2/pages ના બદલે /wp/v2/pages?search=home માટે રિક્વેસ્ટ ટ્રિગર થશે.

ચાલો હવે આપણા useSelect કોલમાં આને પ્રતિબિંબિત કરીએ નીચે મુજબ:

import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
 
function MyFirstApp() {
    // ...
    const { pages } = useSelect( select => {
        const query = {};
        if ( searchTerm ) {
            query.search = searchTerm;
        }
        return {
            pages: select( coreDataStore ).getEntityRecords( 'postType', 'page', query )
        }
    }, [searchTerm] );
 
    // ...
}

હવે જ્યારે searchTerm આપવામાં આવે છે ત્યારે તેનો ઉપયોગ શોધ ક્વેરી પેરામીટર તરીકે થાય છે. ધ્યાન આપો કે searchTerm ને useSelect ના dependencies લિસ્ટમાં પણ ઉમેરવામાં આવ્યું છે જેથી જ્યારે તે બદલાય ત્યારે getEntityRecords ફરીથી ચલાવવામાં આવે.

અંતે, જ્યારે આપણે બધું એકસાથે જોડીએ છીએ ત્યારે MyFirstApp કેમ દેખાય છે તે અહીં છે:

import { SearchControl } from '@wordpress/components';
import { useState, render } from '@wordpress/element';
import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
 
function MyFirstApp() {
    const [searchTerm, setSearchTerm] = useState( '' );
    const pages = useSelect( select => {
        const query = {};
        if ( searchTerm ) {
            query.search = searchTerm;
        }
        return select( coreDataStore ).getEntityRecords( 'postType', 'page', query );
    }, [searchTerm] );
 
    return (
        <div>
            <SearchControl
                onChange={ setSearchTerm }
                value={ searchTerm }
            />
            <PagesList pages={ pages }/>
        </div>
    )
}

તે પૂર્ણ થયું! હવે આપણે પરિણામોને ફિલ્ટર કરી શકીએ છીએ.

API સીધા બોલાવવાને બદલે core-data નો ઉપયોગ કરવો

ચાલો થોડું વિરામ લઈએ અને વિચારીએ કે જો આપણે બીજો વિકલ્પ અપનાવ્યો હોત — જેમ કે સીધા API સાથે કામ કરવું — તો તેના ઘટકો શું હોઈ શકે? કલ્પના કરો કે આપણે સીધા API રિક્વેસ્ટ મોકલ્યા હોત:

import { apiFetch } from '@wordpress/api-fetch';
function MyFirstApp() {
    // ...
    const [pages, setPages] = useState( [] );
    useEffect( () => {
        const url = '/wp-json/wp/v2/pages?search=' + searchTerm;
        apiFetch( { url } )
            .then( setPages )
    }, [searchTerm] );
    // ...
}

core-data સિવાય કામ કરતા હોય તો અહીં આપણે બે મુશ્કેલીઓનો સામનો કરવો પડતો.

સૌપ્રથમ, અનુક્રમણ વિમુખ અપડેટ્સ (out-of-order updates) ની સમસ્યા. જો તમે “About” માટે સર્ચ કરો તો A, Ab, Abo, Abou અને About માટે પાંચ API રિક્વેસ્ટ મોકલાય. આ તમામ રિક્વેસ્ટ જે ક્રમમાં મોકલાય છે તે જ ક્રમમાં પૂરી ન પણ થઈ શકે. શક્ય છે કે search=A ની રિસ્પોન્સ search=About પછી આવે અને ફલિત રૂપે ખોટા ડેટા બતાવાય. Gutenberg નું ડેટા મૅનેજમેન્ટ પડદા પાછળ આ અસિંક્રોનસ પ્રક્રિયાને સમસ્યાને સંભાળે છે. useSelect સૌથી છેલ્લી રિક્વેસ્ટ કૉલ ને યાદ રાખે છે અને આપણને અપેક્ષિત ડેટા જ પરત આપે છે.

બીજું, દરેક કીસ્ટ્રોક એક API રિક્વેસ્ટને ટ્રિગર કરે છે. જો તમે About ટાઈપ કરો, પછી ડિલીટ કરો અને ફરીથી ટાઈપ કરો, તો કુલ 10 API રિક્વેસ્ટ મોકલાય ભલે જો એ જ ડેટાનો પુનઃઉપયોગ શક્ય હોય તો પણ. Gutenberg નું ડેટા સિસ્ટમ getEntityRecords() દ્વારા API રિક્વેસ્ટની રિસ્પોન્સને કેશ કરે છે અને ત્યારબાદના કૉલ્સ માટે એ જ ડેટાનો પુનઃઉપયોગ કરે છે. આ ખૂબ જ મહત્વપૂર્ણ છે જ્યારે અન્ય કોમ્પોનન્ટ્સ પણ એ જ એન્ટિટી રેકોર્ડ્સ પર આધાર રાખે છે.

એકંદરે, core-data માં બનેલ યૂટિલિટીઓ સામાન્ય મુશ્કેલીઓ ઉકેલવા માટે બનાવવામાં આવી છે જેથી તમે તમારી એપ્લિકેશન પર ધ્યાન આપી શકો.

પગલું ૫: લોડિંગ સૂચક ઉમેરો

અમારી સર્ચ સુવિધામાં એક સમસ્યા છે. આપણને ખાતરી નથી થઈ શકતી કે શું શોધ હજુ ચાલુ છે કે માત્ર કોઈ પરિણામ મળ્યાં નથી:

“લોડ થઈ રહ્યું છે…” અથવા “કોઈ પરિણામ નથી” જેવા સંદેશો આ વાત સ્પષ્ટ બનાવી શકે. ચાલો હવે એ ઉમેરીએ! સૌપ્રથમ, PagesList ને વર્તમાન સ્થિતિ વિશે માહિતી હોવી જોઈએ.

import { SearchControl, Spinner } from '@wordpress/components';
function PagesList( { hasResolved, pages } ) {
    if ( !hasResolved ) {
        return <Spinner/>
    }
    if ( !pages?.length ) {
        return <div>No results</div>
    }
    // ...
}
 
function MyFirstApp() {
    // ...
 
    return (
        <div>
            // ...
            <PagesList hasResolved={ hasResolved } pages={ pages }/>
        </div>
    )
}

ધ્યાન આપો કે, કસ્ટમ લોડિંગ ઇન્ડિકેટર બનાવવાના બદલે, આપણે Spinner કોમ્પોનેન્ટનો ઉપયોગ કર્યો છે.

હવે પણ આપણે જાણવું જરૂરી છે કે pages સિલેક્ટરે ડેટા લાવવાનું કાર્ય પૂર્ણ કર્યું છે કે નહીં. આપણે એ જાણી શકીએ છીએ hasFinishedResolution સિલેક્ટર નો ઉપયોગ કરીને.

wp.data.select('core').hasFinishedResolution( 'getEntityRecords', [ 'postType', 'page', { search: 'home' } ] )

આમાં તમે જે સિલેક્ટર નો ઉપયોગ કરો છો તેનું નામ અને બિલકુલ એ જ આર્ગ્યુમેન્ટ આપવાની જરૂર હોય છે જે તમે સિલેક્ટર માટે પાસ કરેલા હોય. જો ડેટા પહેલાથી લોડ થઈ ગયેલો હોય તો આ true આપશે, નહિતર false. હવે ચાલો આને useSelect માં ઉમેરીએ:

import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
 
function MyFirstApp() {
    // ...
    const { pages, hasResolved } = useSelect( select => {
        // ...
        return {
            pages: select( coreDataStore ).getEntityRecords( 'postType', 'page', query ),
            hasResolved:
                select( coreDataStore).hasFinishedResolution( 'getEntityRecords', ['postType', 'page', query] ),
        }
    }, [searchTerm] );
 
    // ...
}

હવે એક છેલ્લી સમસ્યા છે — ટાઈપોમાં ભૂલ થવી સરળ છે, જેના કારણે getEntityRecords અને hasFinishedResolution માટે અલગ આર્ગ્યુમેન્ટ આપી શકાય છે. બંને માટે આર્ગ્યુમેન્ટ બિલકુલ એકસરખા હોવા ખુબ જ જરૂરી છે. આ જોખમને દૂર કરવા માટે આપણે આર્ગ્યુમેન્ટ ને એક વેરિએબલમાં સ્ટોર કરી લઈએ:

import { useSelect } from '@wordpress/data';
import { store as coreDataStore } from '@wordpress/core-data';
function MyFirstApp() {
    // ...
    const { pages, hasResolved } = useSelect( select => {
        // ...
        const selectorArgs = [ 'postType', 'page', query ];
        return {
            pages: select( coreDataStore ).getEntityRecords( ...selectorArgs ),
            hasResolved:
                select( coreDataStore ).hasFinishedResolution( 'getEntityRecords', selectorArgs ),
        }
    }, [searchTerm] );
 
    // ...
}

શાનદાર! હવે બધું તૈયાર છે.

બધી વસ્તુઓને એકસાથે જોડો

બધા ભાગો હવે પોતાની જગ્યાએ છે, શાનદાર! આ રહી આપણી એપ્લિકેશનની સંપૂર્ણ JavaScript કોડ:

import { SearchControl, Spinner } from "@wordpress/components";
import { useState, render } from "@wordpress/element";
import { useSelect } from "@wordpress/data";
import { store as coreDataStore } from "@wordpress/core-data";
import { decodeEntities } from "@wordpress/html-entities";
 
function MyFirstApp() {
    const [ searchTerm, setSearchTerm ] = useState( '' );
    const { pages, hasResolved } = useSelect(
        ( select ) => {
            const query = {};
            if ( searchTerm ) {
                query.search = searchTerm;
            }
            const selectorArgs = [ 'postType', 'page', query ];
            return {
                pages: select( coreDataStore ).getEntityRecords(
                    ...selectorArgs
                ),
                hasResolved: select( coreDataStore ).hasFinishedResolution(
                    'getEntityRecords',
                    selectorArgs
                ),
            };
        },
        [ searchTerm ]
    );
 
    return (
        <div>
            <SearchControl onChange={ setSearchTerm } value={ searchTerm } />
            <PagesList hasResolved={ hasResolved } pages={ pages } />
        </div>
    );
}
 
function PagesList( { hasResolved, pages } ) {
    if ( ! hasResolved ) {
        return <Spinner />;
    }
    if ( ! pages?.length ) {
        return <div>No results</div>;
    }
 
    return (
        <table className="wp-list-table widefat fixed striped table-view-list">
            <thead>
                <tr>
                    <td>Title</td>
                </tr>
            </thead>
            <tbody>
                { pages?.map( ( page ) => (
                    <tr key={ page.id }>
                        <td>{ decodeEntities( page.title.rendered ) }</td>
                    </tr>
                ) ) }
            </tbody>
        </table>
    );
}
 
window.addEventListener(
    'load',
    function () {
        render(
            <MyFirstApp />,
            document.querySelector( '#my-first-gutenberg-app' )
        );
    },
    false
);

હવે ફક્ત પેજને રિફ્રેશ કરો અને નવા સ્ટેટસ ઇન્ડિકેટરને માણો.

Suggestions

Found a typo, grammar error or outdated screenshot? Contact us.