Gutenberg Block block.json created with ACF not visible in the page editor - advanced-custom-fields

I tried to create a Gutenberg block with ACF like described here (https://www.billerickson.net/building-acf-blocks-with-block-json/#create-a-block-json-file)
My block.json:
{
"name" : "quick-links",
"title" : "Quick Links",
"apiVersion" : 2,
"icon" : "admin-users",
"mode" : "auto",
"acf": {
"mode": "preview",
"renderTemplate": "quick-links.php"
},
"align" : "full",
"keywords" : [ "Quick-Links", "Links" ]
}
My plugin to register the block:
<?php
/**
* Plugin Name: Gutenberg Block
* Description: Blocks to display photo/video galleries, quicklinks, downloads, ...
* Version: 1.0
*/
add_action( 'init', 'register_acf_blocks', 5 );
function register_acf_blocks() {
register_block_type( __DIR__ . '/blocks/quick-links/block.json' );
}
the quick-links.php just outputs a string.
But the block isn't visible in the page editor. No PHP or JS Errors.
Can anyone see a problem?

There could be a few potential issues with your ACF block registration. In your block.json, the namespace of your block name is missing, which could cause the block registration to fail.
Update namespace with your unique block name:
block.json
{
"name": "namespace/quick-links",
...
}
The function name register_acf_blocks() is potentially not a unique function name. The issue could be your function is overwritting an existing function of the same name. Update your block registration function name to be more unique.
If your block is still not rendering or loading, confirm the path to your block.json is correct. Add some debugging info to your block registration function to find out if the block is being registered:
<?php
function register_acf_blocks_namespace_quick_link() {
$status = register_block_type( __DIR__ . '/blocks/quick-links/' ); // block.json not needed
// If register_block_type cannot register the block, it returns false
if(!status){
error_log('block.json not found');
}
}
add_action( 'init', 'register_acf_blocks_namespace_quick_link', 5 );
Hopefully one or more of the above steps should help resolve your issue..

Related

How to omit "index" entry from an autogenerated Docusaurus V2 sidebar

At work we have a basic Docusaurus v2 page for user documentation, and I can't share it for privacy reasons. Suffice it to say it has a sidebar which is autogenerated, where the top level contains a number of folders as categories and each category only contains .md files.
At the top level (the level of the categories) there is an empty index.md file that only exists so that the page will load. The autogenerated sidebar includes an index entry that points to a blank page. I would like to hide/get rid of this entry.
I have looked at this github discussion on something similar, but I haven't been able to make the solutions work. The sidebar.js file has the following simple contents:
module.exports = {
docs: [
{
type: 'autogenerated',
dirName: '.'
},
],
};
I have tried adding an exclude: ['path\to\index\file'] line, but this results in the error "exclude" is not allowed.
What is the proper way of hiding this index entry from the sidebar? Alternatively, is there a way to set up the site so that the index.md file is not needed at all?
I have the same setup:
/folder1
/file
/folder2
/file
index
And I wand to autogenerate the sidebar with two categories only:
folder1
folder2
Moreover, I wanted to click on the navbar and see index.
I was able to do so by:
Create a custom sidebar
function skipIndex(items) {
return items.filter(({ type, id }) => {
return type !== 'doc' || id !== 'index';
});
}
module.exports = async function sidebarItemsGenerator({ defaultSidebarItemsGenerator, ...args }) {
const sidebarItems = await defaultSidebarItemsGenerator(args);
return skipIndex(sidebarItems);
}
Then in the docusaurus.config.js
presets: [
[
'classic',
({
// https://docusaurus.io/docs/api/plugins/#docusaurus/plugin-content-docs#configuration
docs: {
sidebarItemsGenerator: require('./sidebar.js'),
},
And finally in the index.md file I must add this metadata, otherwise when I reach the index page, the sidebar disappears because the page is not included:
---
displayed_sidebar: docsSidebar
---

How do I call `grabFixture()` method from within `ApiTester instance in Yii2?

I am building an API in Yii2 2.0.14 and running tests with Codeception. Examples in the tutorial* show that I can call fixtures like so:
$profile = $I->grabFixture('profiles', 'user1');
However this doesn't seem to be available in my test class here:
<?php
namespace frontend\tests\api;
use frontend\tests\ApiTester;
class DemoCest
{
public function _fixtures()
{
return [
'users' => [
'class' => UserFixture::className(),
// fixture data located in tests/_data/user.php
'dataFile' => codecept_data_dir() . 'user.php'
],
];
}
public function demo(ApiTester $I)
{
$users = $I->grabFixture('users');
$I->wantTo('perform actions and see result');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPOST('/user/test', ['name' => 'davert', 'email' => 'davert#codeception.com']);
$I->seeResponseCodeIs(\Codeception\Util\HttpCode::OK); // 200
$I->seeResponseIsJson();
$I->seeResponseContainsJson(['message' => 'test OK']);
}
}
I have seen that you need to add fixtures to frontend/tests/api-suite.yml but Codeception is throwing an exception when I do that
PHP Notice: Undefined index: tests in
/var/www/vendor/codeception/base/src/Codeception/Command/Run.php on
line 389
I am completely lost.
actor: ApiTester
modules:
enabled:
- Yii2:
part: [orm, email, fixtures]
- \frontend\tests\Helper\Api
- REST:
url: http://securedata.test/api/v1
depends: PhpBrowser
part: Json
Can anyone lead me in the right direction?
tutorial - http://www.yiiframework.com/doc-2.0/guide-test-fixtures.html
Add to your suite configuration, you haven't defined the tests path in the codeception.yml under paths.
If you look into the line the error points to it will take you to the line inside the matchSingleTest function
in your case
list(, $suite, $test) = $this->matchTestFromFilename($suite, $config['paths']['tests']);
in which it gives tests as undefined index for the $config['paths'] array, which if you backtrack parses the codeception.yml to the $config,
You are using an older version of Yii 2.0.14 which may have the missing section from the execute() see this ISSUE
So add tests directory as . and make sure your codeception.yml is in the /tests root.
see the following
paths:
tests: .

Yii2 use runAction() within beforeAction method

I have a MainController which extends Controller. All my app's controllers extend from MainController which includes various methods and properties which need to be accessible from any Controller.
Within my MainController is beforeAction, which does several things:
Checks for redirects held in the database and performs them if the URL matches one in the DB.
Generates <head> data for each controller
Gets the language and country the user is looking at based on cookie and slug of the URL. (i.e. http://example.com/netherlands).
Will render a generic page from a template if URL matches one from the database's pages table.
It's the last that I am struggling with. In my MainController I have this:
/**
* Before action, check all $this->before_actions satisfy. If no head_data provided, try and fill in some basics
*/
public function beforeAction( $action )
{
// Run parent method first
if (!parent::beforeAction($action))
return false;
// Check redirects
$this->checkRedirects();
if( $this->checkPages() )
{
// If not error page, loop through before methods
if( $action->id !== 'error' )
{
// Loop through actions to peform and do them
foreach ( $this->before_actions as $before_method )
$this->$before_method();
}
return true;
}
}
Where $this->checkPages() contains the following:
/**
* Check for pages
*/
public function checkPages()
{
// Attempt to find page for this request
$page = Page::find()->where( [ 'permalink' => trim( str_replace( getBaseUrl() , "", getCurrentUrl() ), "/" ) ] )->one();
// If found, load it instead
if( !empty( $page ) )
return Yii::$app->runAction( "pages/show", [ 'id' => $page->id ] );
// Else, return
return true;
}
The issue I am having is that if I go to http://example.com/story, because there is no StoryController, the returns a 404 error although the action does run and the view "views/story/show" is output.
How can I prevent this?
EDIT:
To add, the log shows that it first says:
"Unable to resolve the request 'story/index'".
But then additional logs show:
"Route to run: pages/show" ... "Running action: app\controllers\PagesController::actionShow()"
..
Rendering view file: /Users/stefandunn/Documents/Local Machine Development/views/pages/show.php
So I am guessing it's the first log result causing the 404 status
Add one last route that can catch any pattern and redirect to custom action.
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
//...
'<any:.*>' => 'site/index'
],
],

Yii2 Behaviors / Scenarios Modify Attribute

I have a model "Product" that I would like to modify or "mutate" one of its attributes for, but only in specific instances.
I store attribute, price as an integer. So $1.99 gets stored as 199.
I would like to incorporate this with the activeForm in such a way that when getting the price it converts to "1.99" in the field (visually). But when I submit the form, before validation, it modifies the price from "1.99" to "199".
I'm assuming this will require Behaviors, and specifically attaching a behavior to the model before creating the active form. However, I'm still confused on how to set this up. I see there is an AttributeBehavior class or I can make my own Behavior class, but I've been having trouble figuring out implementation in this case.
The situation:
foreach ($store_item->storeProducts as $i=>$product) {
?>
<tr>
<td>
<?= $form->field($product, '['.$i.']price')->label(false); ?>
</td>
</tr>
<?php
$i++;
}
?>
Here is a scenario where I check for empty attribute and assign value before saving. Note owner returns the Model so that you can access model attributes and functions that are public. Let me know if I can explain anything further
public function behaviors()
{
return [
[
'class' => AttributeBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => 'yourAttrib',
],
'value' => function ($event) {
$code = "N/A";
if(!empty($this->owner->yourAttrib))
{
$code = $this->owner->yourAttrib; //here change your attribute accordingly
}
return $code;
},
],
//other behaviors
];
}
You could simply use a getter/setter, e.g. :
public function getRealPrice()
{
return $this->price/100;
}
public function setRealPrice($value)
{
$this->price = $value*100;
}
And don't forget to :
add realPrice in your model's rules,
use realPrice in your form (instead of price).

fullCalendar className to multiple eventSources

I am trying to setup my fullCalendar event sources.
instead of pulling all of my events through 1 source, I would like to use multiple sources (ie: google, and local json)
Here is what I have so far (In short):
eventSources:
[
//CA HOLIDAYS
$.fullCalendar.gcalFeed('http://www.google.com/calendar/feeds/en.canadian%23holiday%40group.v.calendar.google.com/public/basic', { className: 'holiday' }),
//General events
'events.php?a=getAllCalendarEvents'
],
The problem that I am having is, I can get the gCalFeed to have a className, but not exactly sure how to get my other source to have a className...
Any ideas would be greatly appreciated.
the only other way is to individually set a 'className' property for each one of your events objects.
it would be nice to set a source's className as one high-level property. please feel free to request this feature (http://arshaw.com/fullcalendar/support/)
You could try adding className to the whole eventSource
eventSources:
[
//CA HOLIDAYS
$.fullCalendar.gcalFeed('http://www.google.com/calendar/feeds/en.canadian%23holiday%40group.v.calendar.google.com/public/basic', { className: 'holiday' }),
//General events
{
events: 'events.php?a=getAllCalendarEvents',
className: 'GeneralEvents'
}
],