Your HTML input field is currently set to empty so the page shows your field as empty is the correct behavior.
<input type="text" name="favorite_color" id="favorite_color" title="Favorite Color" value="" class="input-text" type="text" />
Take a look at vendor/magento/module-customer/view/frontend/templates/form/edit.phtml
to know how Magento populate data into customer attribute fields (Firstname, Lastname, Dob, Taxvat, Gender):
Let's get Taxvat for example:
<?php $_taxvat = $block->getLayout()->createBlock(\Magento\Customer\Block\Widget\Taxvat::class) ?>
<?= $_taxvat->setTaxvat($block->getCustomer()->getTaxvat())->toHtml() ?>
In this code, Magento declares $_taxvat
= creates Magento\Customer\Block\Widget\Taxvat
block.
Then passing Taxvat
to that block.
Finally, it renders HTML content for Taxvat by toHtml()
method.
Back to your code, you are referring to form.additional.info
container, it will put your custom attribute field (Favorite Color) after Change Password
field which I think is not a good place.
Your custom attribute (Favorite Color) should be put after Gender
field or somewhere related. To achieve that, override vendor/magento/module-customer/view/frontend/templates/form/edit.phtml
You can't get custom customer attribute values from Magento\Customer\Api\Data\CustomerInterface
like Magento default customer attributes (Firstname, Lastname, Dob, Taxvat, Gender,...) so you have to implement another approach to show your custom customer attribute to frontend. That is create a new child block inside customer_edit
block and declare a ViewModel that is responsible for passing your custom customer attribute value to your phtml
template.
Based on your information, I've written a full step-by-step including a Data patch for creating a new custom customer attribute, displaying and manipulating the custom customer attribute on the Customer Account Information page. Take a look at my code, you can display and manipulate your custom customer attributes on other pages.
Assume the Vendor name is TuVan
and the module name is Customer
.
Step 1: Create registration.php:
File path: app/code/TuVan/Customer/registration.php
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'TuVan_Customer', __DIR__);
Step 2: Create module.xml:
File path: app/code/TuVan/Customer/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="TuVan_Customer">
<sequence>
<module name="Magento_Customer"/>
</sequence>
</module>
</config>
Step 3: Create AddFavoriteColorAttribute.php:
File path: app/code/TuVan/Customer/Setup/Patch/Data/AddFavoriteColorAttribute.php
<?php
namespace TuVan\Customer\Setup\Patch\Data;
use Magento\Customer\Api\CustomerMetadataInterface;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
class AddFavoriteColorAttribute implements DataPatchInterface
{
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;
/**
* @var CustomerSetupFactory
*/
private $customerSetupFactory;
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
CustomerSetupFactory $customerSetupFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->customerSetupFactory = $customerSetupFactory;
}
/**
* @inheritdoc
*/
public function apply()
{
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$favoriteColorAttributeCode = 'favorite_color';
$customerSetup->addAttribute(
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER ,
$favoriteColorAttributeCode, [
'label' => 'Favorite Color',
'type' => 'varchar',
'input' => 'text',
'required' => false,
'visible' => true,
'user_defined' => true,
'position' => 999,
'system' => false,
]);
$customerSetup->addAttributeToSet(
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER,
null,
$favoriteColorAttributeCode
);
$favoriteColorAttribute = $customerSetup->getEavConfig()->getAttribute(
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
$favoriteColorAttributeCode
);
$favoriteColorAttribute->addData([
'used_in_forms' => [
'customer_account_create',
'customer_account_edit',
'checkout_register',
'adminhtml_customer',
'adminhtml_checkout'
]
]);
$favoriteColorAttribute->save();
}
public static function getDependencies()
{
return [];
}
public function getAliases()
{
return [];
}
}
Step 4: Create customer_account_edit.xml:
File path: app/code/TuVan/Customer/view/frontend/layout/customer_account_edit.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="customer_edit">
<action method="setTemplate">
<argument name="template" xsi:type="string">TuVan_Customer::form/edit.phtml</argument>
</action>
<block class="Magento\Framework\View\Element\Template" name="customer_favorite_color" template="TuVan_Customer::form/customer_account_edit_favorite_color.phtml">
<arguments>
<argument name="view_model" xsi:type="object">TuVan\Customer\ViewModel\FavoriteColor</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
Step 6: Create FavoriteColor.php:
File path: app/code/TuVan/Customer/ViewModel/FavoriteColor.php
<?php
namespace Magetu\Catalog\ViewModel;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Session;
use Magento\Framework\View\Element\Block\ArgumentInterface;
/**
* Favorite Color view model
*/
class FavoriteColor implements ArgumentInterface
{
/**
* @var CustomerRepositoryInterface
*/
private $customerRepository;
/**
* @var Session
*/
private $customerSession;
public function __construct(
Session $customerSession,
CustomerRepositoryInterface $customerRepository
) {
$this->customerSession = $customerSession;
$this->customerRepository = $customerRepository;
}
public function getFavoriteColor()
{
$customerId = $this->customerSession->getCustomerId();
$customer = $this->customerRepository->getById($customerId);
return $customer->getCustomAttribute('favorite_color')
? $customer->getCustomAttribute('favorite_color')->getValue() : '';
}
}
Step 7: Create customer_account_edit_additional_info.phtml:
File path: app/code/TuVan/Customer/view/frontend/templates/form/customer_account_edit_favorite_color.phtml
<?php
/** @var \Magento\Framework\View\Element\Template $block */
/** @var \Magento\Framework\Escaper $escaper */
/** @var \Magetu\Catalog\ViewModel\FavoriteColor $viewModel */
$viewModel = $block->getViewModel();
?>
<div class="field favorite-color">
<label for="favorite_color" class="label">
<span>
<?= $escaper->escapeHtml(__('Favorite Color')) ?>
</span>
</label>
<div class="control">
<?php
$validationClass = $escaper->escapeHtmlAttr(
$this->helper(\Magento\Customer\Helper\Address::class)
->getAttributeValidationClass('favorite_color')
)
?>
<input type="text"
name="favorite_color"
id="favorite_color"
value="<?= $escaper->escapeHtmlAttr($viewModel->getFavoriteColor()) ?>"
title="<?= $escaper->escapeHtmlAttr(__('Favorite Color')) ?>"
class="input-text <?= $validationClass ?: '' ?>"
>
</div>
</div>
Step 8: Install the module: bin/magento setup:upgrade
Step 9: Compile code: bin/magento setup:di:compile
Step 10: Deploy static content: bin/magento setup:static-content:deploy -f
You are done.
Btw, I have some recommendations for you:
- I see you have a duplicate
type
attribute for input
element. I recommend using a PhpStorm/VisualStudio/NetBeans/...IDE to work with Magento 2, they are professional IDEs that help you a lot when developing Magento or large PHP projects (of course, they also support highlight code and errors, so you can detect some errors like duplicate HTML attributes...).
If you use PhpStorm, Magento has Magento PhpStorm plugin (free) for PhpStorm, which is very helpful for Magento Developer to develop Magento 2: https://plugins.jetbrains.com/plugin/8024-magento-phpstorm
2.
- In PHTML templates, we should escape content whenever possible.
Using $escaper->escape{suffix}() for that instead of $block->escape{suffix}() which is deprecated to prevent XSS attack.
For instance: use $escaper->escapeHtml()
for that instead of $block->escapeHtml()
.
https://developer.adobe.com/commerce/php/development/security/cross-site-scripting/#phtml-templates