Gutenberg Block Current Year

User
wp gautenberg block react show year
Assistant
To create a custom Gutenberg block in WordPress that displays the current year using React, you'll need to follow these steps. This example assumes you are using the Sage 10 theme with a setup that includes Webpack and React for your Gutenberg blocks.

### Step 1: Register Your Block

In your `resources/assets/scripts` folder (or wherever you keep your JavaScript files), create a new file for your block, e.g., `current-year-block.js`.

### Step 2: Add Block Code

Here’s a basic example of how to create a block that displays the current year:

import { registerBlockType } from '@wordpress/blocks';
import { useEffect, useState } from '@wordpress/element';

registerBlockType('your-namespace/current-year', {
    title: 'Current Year',
    category: 'widgets',
    icon: 'calendar-alt',
    edit: () => {
        const [year, setYear] = useState(new Date().getFullYear());

        useEffect(() => {
            const updateYear = () => {
                setYear(new Date().getFullYear());
            };

            // Optional: You can add an interval if you want it to update every year.
            const interval = setInterval(updateYear, 1000 * 60 * 60 * 24 * 365);

            return () => clearInterval(interval);
        }, []);

        return <div>{year}</div>;
    },
    save: () => {
        return <div>{new Date().getFullYear()}</div>;
    },
});

### Step 3: Enqueue Your Block Script

In your theme's `functions.php`, enqueue your block script using the following code:

function my_block_assets() {
    wp_enqueue_script(
        'current-year-block',
        get_theme_file_uri('resources/assets/scripts/current-year-block.js'),
        array('wp-blocks', 'wp-element'),
        filemtime(get_theme_file_path('resources/assets/scripts/current-year-block.js'))
    );
}
add_action('enqueue_block_editor_assets', 'my_block_assets');

### Step 4: Build Your Assets

Make sure your assets are built. If you’re using Sage 10, run the following command to build your assets:

yarn build

### Step 5: Test Your Block

1. Go to your WordPress admin dashboard.
2. Navigate to a post or page and add your "Current Year" block from the block inserter.
3. You should see the current year displayed.

### Notes

– The `edit` function uses React's `useEffect` and `useState` to keep the displayed year updated. The `setInterval` function is included as an example but isn't strictly necessary since the year doesn't change every second.
– Ensure your namespace in `registerBlockType` is unique to prevent conflicts with other blocks.

With this setup, you should have a functioning Gutenberg block that displays the current year! Let me know if you need any more assistance.

User
/**
* Retrieves the translation of text.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-i18n/
*/
import { __ } from '@wordpress/i18n';
import { useEffect, useState } from 'react';
/**
* React hook that is used to mark the block wrapper element.
* It provides all the necessary props like the class name.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/packages/packages-block-editor/#useblockprops
*/
import { useBlockProps } from '@wordpress/block-editor';

/**
* Lets webpack process CSS, SASS or SCSS files referenced in JavaScript files.
* Those files can contain any CSS code that gets applied to the editor.
*
* @see https://www.npmjs.com/package/@wordpress/scripts#using-css
*/
import './editor.scss';

/**
* The edit function describes the structure of your block in the context of the
* editor. This represents what the editor will render when the block is used.
*
* @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-edit-save/#edit
*
* @return {Element} Element to render.
*/
export default function Edit() {
return (

{ __(
'Copyright Date Block – hello from the editor!-2',
'copyright-date-block'
) }

);
}

Assistant
Your code snippet shows the structure for the `Edit` component of a custom Gutenberg block, which currently renders a paragraph with a translation string. To modify this block to display the current year instead of the static text, you can incorporate the React hooks and logic I previously provided. Here’s how you can adapt your `Edit` function to show the current year:

### Updated `Edit` Function

import { __ } from '@wordpress/i18n';
import { useEffect, useState } from 'react';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export default function Edit() {
	const [year, setYear] = useState(new Date().getFullYear());

	useEffect(() => {
		const updateYear = () => {
			setYear(new Date().getFullYear());
		};

		// This will update the year if needed, though it's not strictly necessary for a year display
		const interval = setInterval(updateYear, 1000 * 60 * 60 * 24 * 365);

		return () => clearInterval(interval);
	}, []);

	return (
		<p { ...useBlockProps() }>
			{ __( 'Copyright © ', 'copyright-date-block' ) }
			{ year }
		</p>
	);
}

### Breakdown of Changes

1. **State Initialization**: The `useState` hook initializes the `year` state with the current year.
2. **Effect Hook**: The `useEffect` hook is used to keep the year updated if needed (you may not need this for just a year display).
3. **Rendering the Year**: The returned JSX now includes the current year alongside a copyright message. The `__(…)` function is used for translation.

### Complete Block Example

Make sure you also have the `save` function set up to keep the block content consistent on the front end. You can do this similarly:

import { __ } from '@wordpress/i18n';
import { useEffect, useState } from 'react';
import { useBlockProps } from '@wordpress/block-editor';
import './editor.scss';

export function Edit() {
	const [year, setYear] = useState(new Date().getFullYear());

	useEffect(() => {
		const updateYear = () => {
			setYear(new Date().getFullYear());
		};

		const interval = setInterval(updateYear, 1000 * 60 * 60 * 24 * 365);
		return () => clearInterval(interval);
	}, []);

	return (
		<p { ...useBlockProps() }>
			{ __( 'Copyright © ', 'copyright-date-block' ) }
			{ year }
		</p>
	);
}

export function Save() {
	const currentYear = new Date().getFullYear();

	return (
		<p>
			{ __( 'Copyright © ', 'copyright-date-block' ) }
			{ currentYear }
		</p>
	);
}

### Summary

With this setup, your Gutenberg block will now display the current year dynamically in the editor and save the current year to the front-end content. You can further customize the block's styles and functionality as needed. If you have any other questions or need additional features, feel free to ask!

User
view.js
Assistant
The `view.js` file can be used to handle the front-end rendering of your custom Gutenberg block. When WordPress renders a block on the front end, it doesn’t necessarily use the React components directly, so this file is helpful if you need any custom JavaScript for front-end interactions.

For your block that displays the current year, you may not need extensive JavaScript since the `save` function in the block already outputs the current year. However, if you want to make sure the year updates dynamically every time the page loads, here’s how you could set up `view.js`:

### `view.js` – Dynamically Display Current Year on Front End

// Ensure this code only runs on the front end where this block is used
document.addEventListener('DOMContentLoaded', () => {
	const elements = document.querySelectorAll('.wp-block-your-namespace-current-year');

	elements.forEach(element => {
		// Set the content to the current year
		const currentYear = new Date().getFullYear();
		element.textContent = `© ${currentYear}`;
	});
});

### Explanation

1. **Event Listener**: `DOMContentLoaded` ensures the script runs after the DOM is fully loaded.
2. **Query the Block Elements**: It selects all instances of your block using a class selector. Replace `your-namespace-current-year` with the actual class or block name used in your block’s front-end rendering.
3. **Update Content**: It dynamically sets the year to the current year.

### Enqueue `view.js` in `functions.php`

Make sure to enqueue `view.js` only on the front end by adding it to your theme's `functions.php`:

function enqueue_current_year_block_script() {
	if ( ! is_admin() ) {
		wp_enqueue_script(
			'current-year-block-view',
			get_theme_file_uri('resources/assets/scripts/view.js'),
			array(),
			filemtime(get_theme_file_path('resources/assets/scripts/view.js')),
			true
		);
	}
}
add_action('wp_enqueue_scripts', 'enqueue_current_year_block_script');

This will ensure `view.js` is only loaded on the front end, helping reduce load on the editor page. Now your custom Gutenberg block will dynamically display the current year on the front end as well!

User
on front end still showing render.php
Assistant
User's custom Gutenberg block on the front end is still displaying content from `render.php`.
Assistant
It sounds like your block is registered as a **dynamic block** if it’s still referencing `render.php`. Dynamic blocks rely on PHP to generate their output, so `view.js` won’t override `render.php`. Here’s how to handle it if you want to control the year display dynamically:

1. **Modify `render.php`** to output a container that `view.js` can update.
2. Ensure `render.php` uses the current year as a default fallback.

### Step 1: Update `render.php`

In your `render.php` file, wrap the output with a container, and add a placeholder for the year. Here’s an example:

<?php
// Dynamic block content for Current Year
$year = date('Y');
?>
<p class="wp-block-your-namespace-current-year">© <?php echo esc_html( $year ); ?></p>

This code provides a default year value that `view.js` will target.

### Step 2: Ensure `view.js` Updates the Year

With the previous `view.js` setup, this JavaScript will update the year whenever the page loads. Since `render.php` is used as the initial structure, it will show the current year as a fallback even if `view.js` doesn’t load immediately.

### Alternative: Remove PHP Dependency for Static Year Display

If you don’t want `render.php` to control the front-end display, remove it and update the block registration in PHP so it’s not a dynamic block. To make it a static block, remove the `render_callback` in your block’s registration in PHP:

register_block_type('your-namespace/current-year', array(
    'editor_script' => 'your-block-editor-script',
    'editor_style' => 'your-block-editor-style',
    'style' => 'your-block-frontend-style',
));

With this change, the content will be saved directly in the post content rather than relying on `render.php`, making it possible to control with JavaScript or directly within `view.js`. Let me know if you’d like more guidance with either approach!

User
fectch post and display in render.php
Assistant
To fetch and display a post or multiple posts in `render.php` for a dynamic Gutenberg block, you can use WordPress’s `WP_Query` or helper functions to retrieve posts and output them within the block.

### Step 1: Set Up `render.php` to Fetch and Display Posts

Here’s an example of how to fetch the latest post and display its title and excerpt:

<?php
// Fetch the latest post
$args = array(
    'post_type'      => 'post',
    'posts_per_page' => 1,
);
$query = new WP_Query( $args );

if ( $query->have_posts() ) :
    while ( $query->have_posts() ) : $query->the_post(); ?>
        <div class="wp-block-your-namespace-latest-post">
            <h2><?php the_title(); ?></h2>
            <div><?php the_excerpt(); ?></div>
            <a href="<?php the_permalink(); ?>"><?php _e( 'Read more', 'your-text-domain' ); ?></a>
        </div>
    <?php endwhile;
    wp_reset_postdata();
else : ?>
    <p><?php _e( 'No posts found.', 'your-text-domain' ); ?></p>
<?php endif; ?>

This code snippet:

1. **Defines Query Arguments**: Sets `post_type` to `post` and `posts_per_page` to `1` to fetch only the latest post.
2. **Runs the Loop**: Checks if there are any posts matching the query, then outputs the post title, excerpt, and a "Read more" link to the full post.
3. **Resets the Post Data**: Ensures the global `$post` variable is reset after the custom query.

### Step 2: Register the Block with `render_callback`

In your block registration, specify `render.php` as the callback for generating the front-end content dynamically:

register_block_type('your-namespace/latest-post', array(
    'render_callback' => 'your_namespace_render_latest_post_block',
    'editor_script'   => 'your-block-editor-script',
    'editor_style'    => 'your-block-editor-style',
    'style'           => 'your-block-frontend-style',
));

function your_namespace_render_latest_post_block() {
    ob_start();
    include plugin_dir_path( __FILE__ ) . 'render.php';
    return ob_get_clean();
}

Replace `plugin_dir_path( __FILE__ ) . 'render.php'` with the correct path if `render.php` is located in a theme directory instead.

### Step 3: Customize Post Display (Optional)

To show multiple posts, adjust `posts_per_page` in `$args`:

'posts_per_page' => 3,

Now, this block will dynamically fetch and display posts based on the PHP logic in `render.php`. This approach is helpful if you need the content to be updated automatically when new posts are added. Let me know if you need any further customization!

User
fetch from external api in edit.js
Assistant
To fetch data from an external API in your Gutenberg block’s `edit.js` file, you can use JavaScript's `fetch` API along with React’s hooks to handle the data and update the block editor in real time.

Here’s how you can set it up:

### Step 1: Create the `edit.js` File with Fetch Logic

In your block’s `edit.js` file, use `useEffect` to fetch data when the component mounts and `useState` to store the data.

import { __ } from '@wordpress/i18n';
import { useBlockProps } from '@wordpress/block-editor';
import { useEffect, useState } from 'react';
import './editor.scss';

export default function Edit() {
	const blockProps = useBlockProps();
	const [data, setData] = useState(null);
	const [loading, setLoading] = useState(true);

	useEffect(() => {
		// Replace with your external API URL
		const apiUrl = 'https://api.example.com/data';

		// Fetch data from the API
		fetch(apiUrl)
			.then(response => response.json())
			.then(data => {
				setData(data);
				setLoading(false);
			})
			.catch(error => {
				console.error('Error fetching data:', error);
				setLoading(false);
			});
	}, []);

	if (loading) {
		return <p {...blockProps}>{__('Loading...', 'your-text-domain')}</p>;
	}

	if (!data) {
		return <p {...blockProps}>{__('No data available', 'your-text-domain')}</p>;
	}

	return (
		<div {...blockProps}>
			<h3>{__('Fetched Data:', 'your-text-domain')}</h3>
			{/* Display data as needed. This example assumes the data is an object */}
			<pre>{JSON.stringify(data, null, 2)}</pre>
		</div>
	);
}

### Explanation

1. **State Management**: `data` holds the fetched data, and `loading` manages the loading state.
2. **Fetch Data on Mount**: The `useEffect` hook fetches data from the external API when the component mounts.
3. **Error Handling**: If the fetch request fails, it logs an error and stops the loading state.
4. **Display Logic**: While loading, it shows a "Loading…" message. Once the data is fetched, it displays the data.

### Step 2: Handle the Data (Customize as Needed)

Replace the `apiUrl` with the URL of your external API. Update the display logic within the `return` statement based on the structure of the API data.

### Example of Displaying Specific Data Fields

If the fetched data has specific fields, such as `title` and `description`, adjust the rendering:

return (
	<div {...blockProps}>
		<h3>{__('Fetched Data:', 'your-text-domain')}</h3>
		<p>{data.title}</p>
		<p>{data.description}</p>
	</div>
);

### Step 3: Ensure CORS Compliance

If you encounter any CORS issues, ensure the external API allows requests from your WordPress domain by configuring CORS headers on the API side or by using a proxy.

With this setup, your Gutenberg block’s editor will display data fetched from an external API! Let me know if you need further customization.

User
how display in front end
Assistant
To display data from an external API on the front end, you can modify the block so that it fetches and displays this data dynamically. Since Gutenberg blocks are rendered on both the editor and front end, you’ll need a way to handle fetching data in `save.js` (or `render.php` if using PHP).

Here are two approaches:

### Approach 1: JavaScript Fetch in `view.js` (Recommended)

This approach uses `view.js` to fetch data on the front end when the page loads.

1. **Add a `view.js` file** in your block directory.

// view.js
   document.addEventListener('DOMContentLoaded', () => {
       const apiUrl = 'https://api.example.com/data';
       
       fetch(apiUrl)
           .then(response => response.json())
           .then(data => {
               // Find the block container and populate it with the data
               const elements = document.querySelectorAll('.wp-block-your-namespace-your-block-name');
               elements.forEach(element => {
                   element.innerHTML = `
                       <h3>Fetched Data:</h3>
                       <p>${data.title}</p>
                       <p>${data.description}</p>
                   `;
               });
           })
           .catch(error => {
               console.error('Error fetching data:', error);
           });
   });

Replace `apiUrl` with the actual URL of the external API, and update `data.title` and `data.description` based on the structure of the API response.

2. **Enqueue `view.js` in `functions.php`** so it loads only on the front end.

function enqueue_block_view_script() {
       if ( ! is_admin() ) {
           wp_enqueue_script(
               'your-block-view-script',
               get_theme_file_uri('/path-to-your/view.js'),
               array(),
               filemtime(get_theme_file_path('/path-to-your/view.js')),
               true
           );
       }
   }
   add_action('wp_enqueue_scripts', 'enqueue_block_view_script');

3. **Register the Block as Static**

Ensure the block is not using a `render_callback` to avoid PHP rendering conflicts. You can handle all rendering in the `view.js` script.

### Approach 2: Dynamic PHP Rendering (if needed)

If you need server-side rendering, register the block as a dynamic block with `render.php` and fetch the data server-side.

1. **Update `render.php` to Fetch API Data**

Use `wp_remote_get` to fetch data from the external API. Here’s a basic example:

<?php
   function fetch_api_data() {
       $response = wp_remote_get('https://api.example.com/data');
       if (is_wp_error($response)) {
           return '<p>Error fetching data.</p>';
       }
   
       $data = json_decode(wp_remote_retrieve_body($response), true);
       if (! $data) {
           return '<p>No data available.</p>';
       }
   
       // Customize the output
       return sprintf(
           '<div class="wp-block-your-namespace-your-block-name">
               <h3>Fetched Data:</h3>
               <p>%s</p>
               <p>%s</p>
           </div>',
           esc_html($data['title']),
           esc_html($data['description'])
       );
   }
   
   function render_dynamic_block() {
       return fetch_api_data();
   }

2. **Register the Block with `render_callback`**

In your `init` function, set `render_callback` to use the PHP function above:

register_block_type('your-namespace/your-block-name', array(
       'render_callback' => 'render_dynamic_block',
   ));

With either approach, you’ll have a block that dynamically fetches and displays external data on the front end. The JavaScript method (`view.js`) is more responsive, while the PHP method (`render.php`) can be useful for server-rendered content. Let me know which approach works best, or if you'd like more help!

User
export default function Edit( { attributes, setAttributes } ) {
const { showStartingYear, startingYear } = attributes;
const currentYear = new Date().getFullYear().toString();

return (

setAttributes( {
showStartingYear: ! showStartingYear,
} )
}
/>
{ showStartingYear && (

setAttributes( { startingYear: value } )
}
/>
) }

© { currentYear }

);
}
what is !!

Assistant
The `!!` is a common JavaScript trick to coerce a value to a boolean. It converts any truthy or falsy value into either `true` or `false`. Here’s how it works:

1. **Single `!` Negates a Value**: For example, `!showStartingYear` would turn any truthy value into `false` and any falsy value into `true`.
2. **Double `!!` Reverts to Boolean**: By adding a second `!`, it turns any value into `true` or `false` based on its truthiness.

So, in the line:

checked={ !!showStartingYear }

– `!!showStartingYear` will be `true` if `showStartingYear` has a truthy value (like `true`, `1`, or a non-empty string).
– `!!showStartingYear` will be `false` if `showStartingYear` is falsy (like `false`, `0`, `null`, `undefined`, or an empty string).

This ensures `checked` receives a boolean, as required by the `ToggleControl`.

User
showStartingYear: ! showStartingYear,
Assistant
In this line:

showStartingYear: !showStartingYear,

`!showStartingYear` toggles the value of `showStartingYear` to the opposite of what it currently is:

– If `showStartingYear` is `true`, `!showStartingYear` will evaluate to `false`.
– If `showStartingYear` is `false`, `!showStartingYear` will evaluate to `true`.

This line is used within the `onChange` handler for `ToggleControl` to flip the value of `showStartingYear` each time the toggle is clicked, allowing users to enable or disable the "starting year" option interactively.

Leave a Comment

Your email address will not be published. Required fields are marked *