Fix addapartment error
August 19, 2025 · AI Conversations
—
## Option A — Stand‑alone route (no CMS page)
Use this if you just want a controller endpoint.
1) **Controller:** (extend `Controller`, not `ContentController`)
<?php
namespace AppController;
use SilverStripeControlController;
use SilverStripeControlHTTPRequest;
use SilverStripeSecuritySecurity;
class AppartmentController extends Controller
{
private static $allowed_actions = [
'addappartment'
];
private static $url_handlers = [
'addappartment' => 'addappartment',
];
protected function init()
{
parent::init();
if (!Security::getCurrentUser()) {
return $this->redirect('/login');
}
}
public function addappartment(HTTPRequest $request)
{
return $this->customise([
'Title' => 'Add Appartment'
])->renderWith(['Layout/AddAppartment', 'Page']);
}
}
> Note: action/method name in **lowercase** in both `allowed_actions` and the method itself. SilverStripe is forgiving, but keeping it lowercase avoids surprises.
2) **Route:** `app/_config/routes.yml`
---
Name: approutes
After: '#rootroutes'
---
SilverStripeControlDirector:
rules:
'appartment//$Action/$ID/$OtherID': 'AppControllerAppartmentController'
3) **Flush/build:** visit `/_flush` (or `?flush`) and, if needed, `/dev/build?flush`.
Then `/appartment/addappartment` will hit your controller.
—
## Option B — CMS page + PageController
Use this if you want a CMS page living at `/appartment` and actions under it.
1) **Create page type:**
// app/src/Page/AppartmentPage.php
namespace AppPage;
use Page;
class AppartmentPage extends Page
{
}
// app/src/Page/AppartmentPageController.php
namespace AppPage;
use PageController;
use SilverStripeControlHTTPRequest;
use SilverStripeSecuritySecurity;
class AppartmentPageController extends PageController
{
private static $allowed_actions = [
'addappartment'
];
public function addappartment(HTTPRequest $request)
{
if (!Security::getCurrentUser()) {
return $this->redirect('/login');
}
return $this->customise([
'Title' => 'Add Appartment'
])->renderWith(['Layout/AddAppartment', 'Page']);
}
}
2) **CMS:** run `/dev/build?flush`, create a new **Appartment Page** in the CMS with URL Segment `appartment`, publish it.
Now `/appartment/addappartment` will work.
—
## Common gotchas to check
– **Spelling/case:** Your URL is `addappartment` — keep the same lowercase name for the method and in `allowed_actions`.
– **Templates:** ensure `templates/Layout/AddAppartment.ss` exists (and `templates/Page.ss` or your site Page layout).
– **Extending the right base class:**
– Stand‑alone routing ⇒ extend `Controller` and add a `routes.yml`.
– CMS page routing ⇒ extend `PageController` and create a Page in CMS.
– **Flush caches:** always do `?flush` after adding routes/classes/templates.
If you tell me which option you prefer, I can drop in the exact file paths and a minimal `.ss` layout to render.
Error detail: Action 'addapartment' isn't available on class AppControllerAppartmentController.
> Action 'addapartment' isn't available on class AppControllerAppartmentController.
### Quick fix (support both spellings)
Drop this into your controller and flush:
<?php
namespace AppController;
use SilverStripeCMSControllersContentController;
use SilverStripeControlHTTPRequest;
use SilverStripeSecuritySecurity;
class AppartmentController extends ContentController
{
private static $allowed_actions = [
'addapartment',
'addappartment',
];
private static $url_handlers = [
// map both URLs to the same method
'addapartment' => 'addApartmentAction',
'addappartment' => 'addApartmentAction',
];
protected function init()
{
parent::init();
if (!Security::getCurrentUser()) {
return $this->redirect('/login');
}
}
// single handler for both URLs
public function addApartmentAction(HTTPRequest $request)
{
return $this->customise([
'Title' => 'Add Apartment'
])->renderWith(['Layout/AddAppartment', 'Page']);
}
}
### Also make sure
– Your route exists (e.g. in `app/_config/routes.yml`):
---
Name: approutes
After: '#rootroutes'
---
SilverStripeControlDirector:
rules:
'appartment//$Action/$ID/$OtherID': 'AppControllerAppartmentController'
– Template `templates/Layout/AddAppartment.ss` exists.
– **Flush caches**: visit `/?flush` (or `/dev/build?flush`).
Now these will both work:
– `/appartment/addapartment`
– `/appartment/addappartment`
this not working in ss template
Dot notation only drills down **one property at a time**.
✅ Correct ways:
### 1. Output each field separately
$CurrentUser.FirstName $CurrentUser.Surname
### 2. Use `FullName` (built into `Member`)
SilverStripe’s `Member` class already has a `getName()` method (alias `FullName` in templates):
$CurrentUser.Name
That will print *“John Doe”* directly.
### 3. Custom getter (if you really want FirstName+LastName)
In your controller or extension:
public function getFullDisplayName()
{
if ($user = Security::getCurrentUser()) {
return $user->FirstName . ' ' . $user->Surname;
}
return '';
}
Then in template:
$FullDisplayName
—
👉 For your case the simplest is:
$CurrentUser.FirstName $CurrentUser.Surname
or just
$CurrentUser.Name
Do you want me to show how to **always make `$CurrentUser` available in every template** (without manually passing from controller)?