Get url of document node

Is there any way to generate the absolute URL to a node from the Backend?
(Or its parent Page)

I want to write a small Webmention Client and need the URL of a given node from the
TYPO3\TYPO3CR\Domain\Model\Workspace -> afterNodePublishing Signal, so i can send it to the Webmention Server.

Being able to use \TYPO3\Neos\Service\LinkingService would be nice but i don’t know how to get the necessary ControllerContext (DI gives me some weird error about missing constructor arguments - i guess that means there is no ControllerContext yet?)

Is that possible within this context at all?


Hey Robotic-Brain,

could you share some more context where you need this URL? In a controller, ViewHelper, Plugin, …? There is, for example, the <neos:link.node> ViewHelper which does what you want.

All the best,

To be honest I don’t really know the context…
I setup a Signal Handler in the Package boot function for TYPO3\TYPO3CR\Domain\Model\Workspace::emitAfterNodePublishing
That calls a helper object, which filters the signal a bit and then calls my Webmention Service class via a property injected instance.

The only class i’m subclassing is TYPO3\Flow\Package\Package

I guess that means i’m in whichever context, the workspace is used in?

here the relevant code:


class Package extends BasePackage {
	public function boot(\TYPO3\Flow\Core\Bootstrap $bootstrap) {
		$dispatcher = $bootstrap->getSignalSlotDispatcher();
			'TYPO3\TYPO3CR\Domain\Model\Workspace', 'afterNodePublishing',
			'RoboticBrain\Webmention\Slot\SlotHandler', 'onNodePublished'


class SlotHandler {
	 * @var \RoboticBrain\Webmention\Service\Webmention
	 * @Flow\Inject
	protected $webmentionService;

	public function onNodePublished(NodeInterface $node, Workspace $targetWorkspace) {
		if ($targetWorkspace->getName() !== 'live') {


class Webmention {
	public function sendForNode(NodeInterface $node) {
		// i need the node URL here

I found this snippet:
Which helped a bit…
However now I get “@user-admin” appended to all my urls…
Is there no way to simulate a frontend request from the backend?


You need to make sure to adapt the context of the node to be a frontend context. easiest might be a to use a FlowQuery and the context operation to modify the workspace to live.

Other alternative would be to use the ContextFactory to create a live context and then use the NodeData object of this node and the NodeFactory to create a live node.

I’ve never used FlowQuery from PHP (I’m fresh to Neos) could you give me a small example how to use it please?

Meanwhile i managed to “brute force” my way to the right context (see below)
imho this is way too much code for something that should be as simple as reading a property… :frowning:

	 * @Flow\Inject
	 * @var \TYPO3\Neos\Service\LinkingService
	protected $linkingService;
	 * @Flow\Inject
	 * @var \TYPO3\TYPO3CR\Domain\Service\ContextFactoryInterface
	protected $contextFactory;
	 * @var \TYPO3\Flow\Mvc\Routing\UriBuilder
	protected $uriBuilder;
	 * @link
	 * @param \TYPO3\Flow\Configuration\ConfigurationManager $configurationManager
	public function injectUriBuilder(\TYPO3\Flow\Configuration\ConfigurationManager     $configurationManager) {
		$httpRequest = \TYPO3\Flow\Http\Request::createFromEnvironment();
		$request = new \TYPO3\Flow\Mvc\ActionRequest($httpRequest);
		$uriBuilder = new \TYPO3\Flow\Mvc\Routing\UriBuilder();
		$this->uriBuilder = $uriBuilder;
	protected function getUrlToNode(NodeInterface $node) {
		$contentContext = $this->contextFactory->create(array(
			'workspaceName' => 'live',
			'currentSite' => $node->getContext()->getCurrentSite()
		$liveNode = $contentContext->getNodeByIdentifier($node->getIdentifier());
		$uri = $this->linkingService->createNodeUri(
				new ControllerContext(
						new \TYPO3\Flow\Http\Response(),
						new \TYPO3\Flow\Mvc\Controller\Arguments(array()),

EDIT: I think i figured it out already:

$liveNode = (new FlowQuery(array($node)))->context(array('workspaceName' => 'live'))->get(0)

Is this correct?
This is much better, than the previous solution :smile:
Thank you!

1 Like

Yes, great that you figured it. :slight_smile:

IMHO, your getUrlToNode is missing out from core helper functions.

I would expect to be able to call a method like $node->getPublishedUri() to any instance of Neos\ContentRepository\Domain\Model\Node. If the node is just content, then the document that contains it would be loaded, etc, but currently you’d have to build a function like the above to get a universal solution.

Thanks a lot for sharing a solution, I had the same problem in signal-level functionality.

Updating for 2018:

  1. Replace TYPO3 with Neos
  2. Replace TYPO3CR with ContentRepository
  3. Get rid of ‘currentSite’ argument, getCurrentSite method does not exist.