# Custom Extension

The VibeBP framework uses Bulma for its internal styling so we recommend re-using Bulma components to keep your CSS and scripts size to a minimum

Here's a sample extenstion which you can use to develop your custom features in the WPLMS / VibeBP framework.

{% file src="/files/-MObWLQHVMSHsWKSZZek" %}
Vibe Boilterplate
{% endfile %}

Link to boilerplate with node modules : [Download](https://drive.google.com/file/d/1tdtox2fQ2QHzMw7a3S2UK6Yoch9PHFkD/view?usp=sharing)

Now, install this plugin and activate the addon.

![Add to menu](/files/-MObWVOZmOOYexlCfYEF)

2\. Refresh BuddyPress navigation from WP admin - Vibebp - Settings - BuddyPress

![this is the boiler plate addon](/files/-MObWcvRcAGZDj0AgKNm)

Now you can start building the extension.

1.. open the Vibe boilerplate plugin folder  in the terminal or vscode&#x20;

2\. Now move to folder assets/boilerplate , if you open package.json there are 2 commands.&#x20;

3\. To initialise the react project, run&#x20;

```
Initialise : npm install
```

3\. Start development mode.

```
Development mode : npm run dev
```

understanding projkect strucutre

![project structure](/files/-MObXZAwEzm1kzu0IrWe)

A sample API call looks like :

```
const APICall = () =>{
    setisLoading(true);
    
		//Args is arguments from state
		//Your endpoint as defined in the class.api.php
		
		fetch(`${window.vibeboilerplate.api.url}/ENDPOINT`, {
			method: 'post',
			body: JSON.stringify({ ...args , token: select('vibebp').getToken() })
		}).then((res) => res.json())
			.then((data) => {
				setisLoading(false);
				if (data.status) {
				  //Do struff
				}
			}
		})
	}
```

The handler in includes/class.api.php

the rest API init we define the API call

```
private function __construct(){

		add_action('rest_api_init',array($this,'register_api_endpoints'));
	}


	function register_api_endpoints(){

		register_rest_route( VIBE_BOILERPLATE_API_NAMESPACE, '/endpoint', array(
            array(
                'methods'             =>  'POST',
                'callback'            =>  array( $this, 'get_endpoint' ),
                'permission_callback' => array( $this, 'user_permissions_check' ),
            ),
        ));
    }

```

and its handler.

```
function get_endpoint(){

        $request = json_decode($request->get_body(),true);
        //do all the processing here, $this->user is the user object
        $return = array(
            'status'=>1,
            'user'=>$this->user
        );
        return new WP_REST_Response($return, 200);
    }
```

the permissions to validate the request is handled by VibeBP as this logged in area. It will also initialise a class object and assign the user value in the form as described below :

```
function user_permissions_check($request){
        
        $body = json_decode($request->get_body(),true);

        if(!empty($body['token'])){
            global $wpdb;
            //This filter expands the token and captures the user_id

            $this->user = apply_filters('vibebp_api_get_user_from_token','',$body['token']);

            /*
                $this->user = array(
                        'id' => $user->data->ID,
                        'username'=>$user->data->user_login,
                        'slug'=>$user->data->user_nicename,
                        'email'=>$user->data->user_email,
                        'avatar'=> (function_exists('bp_core_fetch_avatar')?bp_core_fetch_avatar(array(
                                        'item_id' => $user->data->ID,
                                        'object'  => 'user',
                                        'type'=>'full',
                                        'html'    => false
                                    )):get_avatar($user->data->user_email,240)),
                        'displayname'=>$user->data->display_name,
                        'roles'=> $user->roles,
                        'caps'=> apply_filters('vibebp_user_caps',$user->allcaps),
                        'profile_link'=>vibebp_get_profile_link($user->data->user_nicename)
                    ),
            */
            if(!empty($this->user)){
                return true;
            }
        }

        return false;
    }
```

so the subsequent functions in a successful REST API call have the object $this->user as the validated user object passed from **Vibebp** to API call.

### Video

{% embed url="<https://www.youtube.com/watch?v=IFfyUQy4kdA>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.wplms.io/developer-guide/custom-extension.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
