diff --git a/Classes/Backend/BackendJsCss.php b/Classes/Backend/BackendJsCss.php
new file mode 100644
index 0000000..eb501a1
--- /dev/null
+++ b/Classes/Backend/BackendJsCss.php
@@ -0,0 +1,31 @@
+getMajorVersion();
+ $ref->addCssFile('EXT:simplereference/Resources/Public/Backend/Css/styles.css');
+ if ($typo3Version === 10) {
+ $ref->addJsFooterFile('EXT:simplereference/Resources/Public/JavaScript/Main.v10.js');
+ }
+ if ($typo3Version === 11) {
+ $ref->addJsFooterFile('EXT:simplereference/Resources/Public/JavaScript/Main.v11.js');
+ }
+
+ $ref->addInlineLanguageLabelFile('EXT:simplereference/Resources/Private/Language/locallang_modal.xlf');
+ }
+ }
+}
diff --git a/Classes/Backend/Helper.php b/Classes/Backend/Helper.php
new file mode 100644
index 0000000..86ee661
--- /dev/null
+++ b/Classes/Backend/Helper.php
@@ -0,0 +1,203 @@
+getParsedBody():
+ *
+ * Add new reference on top of a normal colPos
+ * [addPanelId] = colpos-1-page-50-62c20b4d2e903078051133 // insert panel HTML Id
+ * [addColpos] => 1 // colPos
+ * [addPageUid] => 50 // page uid
+ * [addLanguageuid] => 0 // sys_language_uid
+ *
+ * Add new reference on top of a container element
+ * [addPanelId] = colpos-201-page-50-62c20b4d2e903078051133 // insert panel HTML Id
+ * [addColpos] => 283-201
+ * [addPageUid] => 50 // page uid
+ * [addLanguageuid] => 0
+ *
+ * Add a new reference below existing content element 'addUid' : contentElementUid
+ * [addPanelId] = colpos-201-page-50-62c20b4d2e903078051133 // insert panel HTML Id
+ * [addTable] => tt_content
+ * [addUid] => 281
+ * [addPageUid] => 50 // page uid
+ * [addLanguageuid] => 0
+ *
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
+ * @throws RouteNotFoundException
+ */
+ public function getData(ServerRequestInterface $request): ResponseInterface
+ {
+ $data = ['info' => 'null'];
+ $beUser = $this->getBackendUser();
+
+ // no backend user? return...
+ if (!is_object($beUser)) {
+ return new JsonResponse($data);
+ }
+
+ // the incoming get or post
+ $parsedBody = $request->getParsedBody();
+ $references = $this->getReferences($request);
+
+ // early return if we have nothing to add
+ if (!count($references)) {
+ return new JsonResponse($data);
+ }
+ $data['references'] = $references;
+
+
+ if (isset($parsedBody['addReference'])) {
+
+ $records = implode(',', $references);
+ $newUid = (microtime(true) * 10000);
+ $infoArray = GeneralUtility::intExplode('-',$parsedBody['addPanelId'],true);
+
+ if (isset($parsedBody['addTable'])) {
+ $pid = '-' . $parsedBody['addUid'];
+ } else {
+ $pid = $parsedBody['addPageUid'];
+ }
+
+ $data['data'] = [
+ 'tt_content' => [
+ 'NEW' . $newUid => [
+ 'CType' => 'shortcut',
+ 'header' => 'Reference',
+ //'header_layout' => '100',
+ 'colPos' => (int)$infoArray[1], //end($colPosArray),
+ 'sys_language_uid' => (int)$parsedBody['addLanguageuid'],
+ 'pid' => (int)$pid,
+ 'records' => $records,
+ ],
+ ],
+ ];
+
+ // add EXT:container parent
+ if (isset($parsedBody['addTable'])) {
+ $currentRecord = $this->getRecordByUid((int)$parsedBody['addUid']);
+ if (array_key_exists('tx_container_parent', $currentRecord)) {
+ $data['data']['tt_content']['NEW' . $newUid]['tx_container_parent'] = $currentRecord['tx_container_parent'];
+ }
+ }
+
+ // or override if we are on top of a EXT:container colPos
+ if (isset($parsedBody['addColpos'])) {
+ $colPosArray = GeneralUtility::intExplode('-', $parsedBody['addColpos'], true);
+ if (count($colPosArray) === 2) {
+ $data['data']['tt_content']['NEW' . $newUid]['tx_container_parent'] = $colPosArray[0];
+ }
+ }
+
+ // create redirect uri
+ $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
+ $route = 'web_layout';
+ $parameters = [
+ 'id' => $parsedBody['addPageUid'],
+ 't' => time(),
+ ];
+ $referenceType = '';
+ $data['redirect'] = $uriBuilder->buildUriFromRoute($route, $parameters, $referenceType) . '#';
+
+ // update info
+ $data['info'] = 'success';
+ }
+
+ return new JsonResponse($data);
+ }
+
+ /**
+ * @param ServerRequestInterface $request
+ * @return array
+ */
+ private function getReferences(ServerRequestInterface $request): array
+ {
+ $clipBoard = GeneralUtility::makeInstance(Clipboard::class);
+ $clipBoard->initializeClipboard($request);
+ // yes, normal pad can contain only one record, but why not prepare for other pads, too
+ $clipBoardNormal = $clipBoard->clipData['normal'];
+
+ $references = [];
+ if (isset($clipBoardNormal['el']) && count($clipBoardNormal['el'])) {
+ foreach ($clipBoardNormal['el'] as $key => $val) {
+ $tableAndUid = explode('|', $key);
+ if ($tableAndUid[0] === 'tt_content') {
+ $referenceCe = $this->getRecordByUid((int)$tableAndUid[1]);
+ if ($referenceCe) {
+ // we don't want Matroschka shortcuts
+ if ($referenceCe['CType'] === 'shortcut') {
+ $references[] = $referenceCe['records'];
+ } else {
+ $references[] = $tableAndUid[0] . '_' . $tableAndUid[1];
+ }
+ }
+ }
+ }
+ }
+
+ return $references;
+ }
+
+ /**
+ * Get the record where the reference
+ *
+ * @param int $uid
+ * @return array
+ * @throws DBALException
+ */
+ protected function getRecordByUid(int $uid = 0): array
+ {
+ $data = [];
+
+ if ($uid) {
+ $table = 'tt_content';
+ $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+ ->getQueryBuilderForTable($table);
+ // we need hidden ... records, too
+ $queryBuilder->getRestrictions()
+ ->removeAll()
+ ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
+ $data = $queryBuilder
+ ->select('*')
+ ->from($table)
+ ->where('uid = :theUid')
+ ->setParameter('theUid', $uid)
+ ->execute()
+ ->fetch();
+ }
+
+ return $data;
+ }
+
+
+ /**
+ * Returns the current BE user.
+ *
+ * @return BackendUserAuthentication
+ */
+ protected function getBackendUser(): BackendUserAuthentication
+ {
+ return $GLOBALS['BE_USER'];
+ }
+}
diff --git a/Classes/Backend/Preview/ShortcutPreviewRenderer.php b/Classes/Backend/Preview/ShortcutPreviewRenderer.php
new file mode 100644
index 0000000..4fc73aa
--- /dev/null
+++ b/Classes/Backend/Preview/ShortcutPreviewRenderer.php
@@ -0,0 +1,24 @@
+' . $content . '';
+ }
+}
diff --git a/Configuration/Backend/AjaxRoutes.php b/Configuration/Backend/AjaxRoutes.php
new file mode 100644
index 0000000..a6ca65b
--- /dev/null
+++ b/Configuration/Backend/AjaxRoutes.php
@@ -0,0 +1,7 @@
+ [
+ 'path' => '/simplereference/get-data',
+ 'target' => \Ressourcenmangel\Simplereference\Backend\Helper::class . '::getData',
+ ]
+];
diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php
new file mode 100644
index 0000000..029ee77
--- /dev/null
+++ b/Configuration/TCA/Overrides/tt_content.php
@@ -0,0 +1,12 @@
+isFeatureEnabled('fluidBasedPageModule');
+ if (false === $fluidBasedPageModule) {
+ // implement Standard Preview renderer if you need it for older TYPO3 Versions,
+ // or use Hook in ext_localconf.php;
+ // $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']
+ } else {
+ $GLOBALS['TCA']['tt_content']['types']['shortcut']['previewRenderer'] = \Ressourcenmangel\Simplereference\Backend\Preview\ShortcutPreviewRenderer::class;
+ }
+});
diff --git a/Resources/Private/Language/de.locallang_modal.xlf b/Resources/Private/Language/de.locallang_modal.xlf
new file mode 100644
index 0000000..f28feee
--- /dev/null
+++ b/Resources/Private/Language/de.locallang_modal.xlf
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Referenz einfügen
+
+
+ Soll eine Referenz an dieser Position eingefügt werden?
+
+
+ Abbrechen
+
+
+ Einfügen
+
+
+
+
diff --git a/Resources/Private/Language/locallang_modal.xlf b/Resources/Private/Language/locallang_modal.xlf
new file mode 100644
index 0000000..33af762
--- /dev/null
+++ b/Resources/Private/Language/locallang_modal.xlf
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ Paste Reference
+
+
+ Do you want to paste a reference to this position?
+
+
+ Cancel
+
+
+ Paste
+
+
+
+
diff --git a/Resources/Public/Backend/Css/styles.css b/Resources/Public/Backend/Css/styles.css
new file mode 100644
index 0000000..c4055eb
--- /dev/null
+++ b/Resources/Public/Backend/Css/styles.css
@@ -0,0 +1,6 @@
+.simplereference-shortcut {
+ display: block;
+ padding: 10px;
+ margin: 5px 0 10px;
+ background-color: rgba(80, 160, 255, 0.25);
+}
\ No newline at end of file
diff --git a/Resources/Public/Icons/Extension.svg b/Resources/Public/Icons/Extension.svg
new file mode 100644
index 0000000..79bc11c
--- /dev/null
+++ b/Resources/Public/Icons/Extension.svg
@@ -0,0 +1,15 @@
+
+
diff --git a/Resources/Public/Icons/simplereference_paste.svg b/Resources/Public/Icons/simplereference_paste.svg
new file mode 100644
index 0000000..3b4997c
--- /dev/null
+++ b/Resources/Public/Icons/simplereference_paste.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/Resources/Public/JavaScript/Main.v10.js b/Resources/Public/JavaScript/Main.v10.js
new file mode 100644
index 0000000..f2d94cd
--- /dev/null
+++ b/Resources/Public/JavaScript/Main.v10.js
@@ -0,0 +1,173 @@
+(function () {
+ // CSS query selector of parent elements with needed data attributes
+ const _classWrapperColumns = '.t3js-page-column, .t3js-page-ce';
+ // CSS query selector of the panel where to insert the add reference button
+ const _classWrapperAddElement = '.t3js-page-new-ce';
+ // CSS query selector which triggers the insert via delegate -> click
+ const _clicker = '[data-add-reference="1"]';
+ // First container with page uid
+ const _page_infos = document.querySelector('[data-page]');
+ // The function object
+ const SIMPLE_REFERENCE = {
+ /**
+ * The needed initial functions, called at the end of this function object
+ * See last lines here
+ */
+ documentReady: function () {
+ SIMPLE_REFERENCE.initialRequest({}, false);
+ SIMPLE_REFERENCE.initializeButtonClick();
+ },
+ /**
+ * Add the paste reference button to desired div containers...
+ */
+ addReferenceButtons: function () {
+ const _contentColumns = document.querySelectorAll(_classWrapperColumns);
+
+ if (_contentColumns.length) {
+ for (let _contentElement of _contentColumns) {
+ const _panelAddElement = _contentElement.querySelectorAll(':scope > .t3js-page-ce > ' + _classWrapperAddElement + ',:scope > ' + _classWrapperAddElement);
+ if (_panelAddElement.length) {
+ for (let _panel of _panelAddElement) {
+ if (!_panel.querySelector('[data-add-reference="1"]')) {
+ const button = SIMPLE_REFERENCE.helper.buttonHtml(_contentElement,_panel);
+ //_panel.style.background= "blue";
+ _panel.insertAdjacentHTML('beforeend', button);
+ }
+ }
+ }
+ }
+ }
+ },
+ /**
+ * Simple delegate click function
+ */
+ initializeButtonClick: function () {
+ document.addEventListener('click', function (event) {
+ const isClicker = event.target.matches
+ ? event.target.matches(_clicker)
+ : event.target.msMatchesSelector(_clicker);
+
+ if (isClicker && event.target.dataset) {
+ event.preventDefault();
+ SIMPLE_REFERENCE.initialRequest(event.target.dataset, event.target);
+ }
+ }, false);
+ },
+ /**
+ * The initial request to detect if elements are on the clipboard
+ * @param {object} request A valid object
+ * @param {object} el A valid object
+ */
+ initialRequest: function (request, el) {
+ require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
+ new AjaxRequest(TYPO3.settings.ajaxUrls.simplereference_get_data)
+ .post(request)
+ .then(
+ async function (response) {
+ const data = await response.resolve();
+ if (typeof data === "object" && data !== null && "references" in data) {
+ SIMPLE_REFERENCE.addReferenceButtons();
+ if ("data" in data) {
+ //SIMPLE_REFERENCE.insertReference(data);
+ SIMPLE_REFERENCE.openModal(data);
+ }
+ }
+ }
+ );
+ });
+ },
+ /**
+ * Calls record_process route
+ * @param {object} request A valid object with data and optional redirectt
+ */
+ insertReference: function (request) {
+ require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
+ new AjaxRequest(TYPO3.settings.ajaxUrls.record_process)
+ .post(request)
+ .then(
+ async function (response) {
+ const response_data = await response.resolve();
+ if (typeof response_data === "object" && "redirect" in response_data) {
+ location.href = response_data.redirect;
+ //document.getElementById("#element-tt_content-288").scrollIntoView();
+ }
+ }
+ );
+ });
+ },
+ /**
+ * Creates the paste or cancel modal
+ * @param {object} data A valid object with data and optional redirectt
+ */
+ openModal: function (data) {
+ require(["TYPO3/CMS/Backend/Modal"], function(Modal) {
+ const _modalTitle = (TYPO3.lang["simplereference.modal.title"] || "Create Reference"), // + ': "' + this.itemOnClipboardTitle + '"',
+ _modalText = TYPO3.lang["simplereference.modal.text"] || "Do you want to paste a reference to this position?",
+ _modalButtons = [{
+ text: TYPO3.lang["simplereference.modal.button.cancel"] || "Cancel",
+ active: true,
+ btnClass: "btn-default",
+ trigger: function () {
+ Modal.currentModal.trigger("modal-dismiss")
+ }
+ }, {
+ text: TYPO3.lang["simplereference.modal.button.paste"] || "Paste",
+ btnClass: "btn-warning",
+ trigger: function () {
+ Modal.currentModal.trigger("modal-dismiss");
+ SIMPLE_REFERENCE.insertReference(data);
+ }
+ }];
+ Modal.show(_modalTitle, _modalText, 1, _modalButtons)
+ });
+ },
+ helper: {
+ /**
+ * Creates the paste or cancel modal
+ * To get the page uid you can use here maybe a split on _panel.id, too
+ * @param {HTMLElement} _contentElement The parent content element or column
+ * @param {HTMLElement} _panel The panel where the button is added
+ */
+ buttonHtml: function (_contentElement,_panel) {
+
+ if (!_page_infos) {
+ return '';
+ }
+ return '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+ },
+ objToString: function (obj) {
+ let str = '';
+ for (const [p, val] of Object.entries(obj)) {
+ str += ` data-add-${p}="${val}" `;
+ }
+ return str;
+ }
+ }
+ }
+ // do it
+ SIMPLE_REFERENCE.documentReady();
+})();
diff --git a/Resources/Public/JavaScript/Main.v11.js b/Resources/Public/JavaScript/Main.v11.js
new file mode 100644
index 0000000..89ff70f
--- /dev/null
+++ b/Resources/Public/JavaScript/Main.v11.js
@@ -0,0 +1,177 @@
+(function () {
+ // CSS query selector of parent elements with needed data attributes
+ const _classWrapperColumns = '.t3js-page-column, .t3js-page-ce';
+ // CSS query selector of the panel where to insert the add reference button
+ const _classWrapperAddElement = '.t3js-page-new-ce';
+ // CSS query selector which triggers the insert via delegate -> click
+ const _clicker = '[data-add-reference="1"]';
+ // First container with page uid
+ const _page_infos = document.querySelector('[data-page]');
+ // The function object
+ const SIMPLE_REFERENCE = {
+ /**
+ * The needed initial functions, called at the end of this function object
+ * See last lines here
+ */
+ documentReady: function () {
+ SIMPLE_REFERENCE.initialRequest({}, false);
+ SIMPLE_REFERENCE.initializeButtonClick();
+ },
+ /**
+ * Add the paste reference button to desired div containers...
+ */
+ addReferenceButtons: function () {
+ const _contentColumns = document.querySelectorAll(_classWrapperColumns);
+
+ if (_contentColumns.length) {
+ for (let _contentElement of _contentColumns) {
+ const _panelAddElement = _contentElement.querySelectorAll(':scope > .t3js-page-ce > ' + _classWrapperAddElement + ',:scope > ' + _classWrapperAddElement);
+ if (_panelAddElement.length) {
+ for (let _panel of _panelAddElement) {
+ if (!_panel.querySelector('[data-add-reference="1"]')) {
+ const button = SIMPLE_REFERENCE.helper.buttonHtml(_contentElement, _panel);
+ //_panel.style.background= "blue";
+ _panel.insertAdjacentHTML('beforeend', button);
+ }
+ }
+ }
+ }
+ }
+ },
+ /**
+ * Simple delegate click function
+ */
+ initializeButtonClick: function () {
+ document.addEventListener('click', function (event) {
+ const isClicker = event.target.matches
+ ? event.target.matches(_clicker)
+ : event.target.msMatchesSelector(_clicker);
+
+ if (isClicker && event.target.dataset) {
+ event.preventDefault();
+ SIMPLE_REFERENCE.initialRequest(event.target.dataset, event.target);
+ }
+ }, false);
+ },
+ /**
+ * The initial request to detect if elements are on the clipboard
+ * @param {object} request A valid object
+ * @param {object} el A valid object
+ */
+ initialRequest: function (request, el) {
+ require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
+ new AjaxRequest(TYPO3.settings.ajaxUrls.simplereference_get_data)
+ .post(request)
+ .then(
+ async function (response) {
+ const data = await response.resolve();
+ if (typeof data === "object" && data !== null && "references" in data) {
+ SIMPLE_REFERENCE.addReferenceButtons();
+ if ("data" in data) {
+ //SIMPLE_REFERENCE.insertReference(data);
+ SIMPLE_REFERENCE.openModal(data);
+ }
+ }
+ }
+ );
+ });
+ },
+ /**
+ * Calls record_process route
+ * @param {object} request A valid object with data and optional redirectt
+ */
+ insertReference: function (request) {
+ require(['TYPO3/CMS/Core/Ajax/AjaxRequest'], function (AjaxRequest) {
+ new AjaxRequest(TYPO3.settings.ajaxUrls.record_process)
+ .post(request)
+ .then(
+ async function (response) {
+ const response_data = await response.resolve();
+ if (typeof response_data === "object" && "redirect" in response_data) {
+ location.href = response_data.redirect;
+ //document.getElementById("#element-tt_content-288").scrollIntoView();
+ }
+ }
+ );
+ });
+ },
+ /**
+ * Creates the paste or cancel modal
+ * @param {object} data A valid object with data and optional redirectt
+ */
+ openModal: function (data) {
+ require(['TYPO3/CMS/Backend/Modal',
+ 'TYPO3/CMS/Backend/Element/IconElement',
+ "TYPO3/CMS/Backend/Severity",
+ "TYPO3/CMS/Backend/Enum/Severity"], function (Modal, Icon, Css, CssEnum) {
+
+ const _modalTitle = (TYPO3.lang["simplereference.modal.title"] || "Create Reference"), // + ': "' + this.itemOnClipboardTitle + '"',
+ _modalText = TYPO3.lang["simplereference.modal.text"] || "Do you want to paste a reference to this position?",
+ _modalButtons = [{
+ text: TYPO3.lang["simplereference.modal.button.cancel"] || "Cancel",
+ active: !0,
+ btnClass: "btn-default",
+ trigger: function () {
+ Modal.currentModal.trigger("modal-dismiss")
+ }
+ }, {
+ text: TYPO3.lang["simplereference.modal.button.paste"] || "Paste",
+ btnClass: "btn-" + Css.getCssClass(CssEnum.SeverityEnum.warning),
+ trigger: function () {
+ Modal.currentModal.trigger("modal-dismiss");
+ SIMPLE_REFERENCE.insertReference(data);
+ }
+ }];
+ Modal.show(_modalTitle, _modalText, CssEnum.SeverityEnum.warning, _modalButtons)
+ });
+ },
+ helper: {
+ /**
+ * Creates the paste or cancel modal
+ * To get the page uid you can use here maybe a split on _panel.id, too
+ * @param {HTMLElement} _contentElement The parent content element or column
+ * @param {HTMLElement} _panel The panel where the button is added
+ */
+ buttonHtml: function (_contentElement,_panel) {
+
+ if (!_page_infos) {
+ return '';
+ }
+ return '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+ },
+ objToString: function (obj) {
+ let str = '';
+ for (const [p, val] of Object.entries(obj)) {
+ str += ` data-add-${p}="${val}" `;
+ }
+ return str;
+ }
+ }
+ }
+ // do it
+ SIMPLE_REFERENCE.documentReady();
+})();
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..a7f3179
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,50 @@
+{
+ "name": "ressourcenmangel/simplereference",
+ "type": "typo3-cms-extension",
+ "description": "Add paste reference button next to paste copy button",
+ "authors": [
+ {
+ "name": "Matthias Kappenberg",
+ "email": "matthias.kappenberg@ressourcenmangel.de",
+ "role": "Developer"
+ }
+ ],
+ "license": "GPL-2.0-or-later",
+ "require": {
+ "typo3/cms-core": "^10.4 || ^11.5"
+ },
+ "require-dev": {
+ "typo3/testing-framework": "^6.8"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "autoload": {
+ "psr-4": {
+ "Ressourcenmangel\\Simplereference\\": "Classes"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Ressourcenmangel\\Simplereference\\Tests\\": "Tests"
+ }
+ },
+ "replace": {
+ "typo3-ter/simplereference": "self.version"
+ },
+ "config": {
+ "vendor-dir": ".Build/vendor",
+ "bin-dir": ".Build/bin"
+ },
+ "scripts": {
+ "post-autoload-dump": [
+ "TYPO3\\TestingFramework\\Composer\\ExtensionTestEnvironment::prepare"
+ ]
+ },
+ "extra": {
+ "typo3/cms": {
+ "cms-package-dir": "{$vendor-dir}/typo3/cms",
+ "web-dir": ".Build/public",
+ "extension-key": "simplereference"
+ }
+ }
+}
diff --git a/ext_emconf.php b/ext_emconf.php
new file mode 100644
index 0000000..2166b63
--- /dev/null
+++ b/ext_emconf.php
@@ -0,0 +1,36 @@
+ 'Simple Reference',
+ 'description' => 'Create a simple reference element.',
+ 'category' => 'plugin',
+ 'constraints' =>
+ [
+ 'depends' =>
+ [
+ 'typo3' => '10.4.16-11.5.99',
+ ],
+ 'suggests' =>
+ [],
+ 'conflicts' =>
+ [
+ 'gridelements' => '*',
+ ],
+ ],
+ 'autoload' =>
+ [
+ 'psr-4' =>
+ [
+ 'Ressourcenmangel\\Simplereference\\' => 'Classes',
+ ],
+ ],
+ 'state' => 'stable',
+ 'uploadfolder' => false,
+ 'clearCacheOnLoad' => 1,
+ 'author' => 'Matthias Kappenberg',
+ 'author_email' => 'matthias.kappenberg@ressourcenmangel.de',
+ 'author_company' => 'Ressourcenmangel',
+ 'version' => '1.0.0',
+ 'clearcacheonload' => true,
+];
+
diff --git a/ext_localconf.php b/ext_localconf.php
new file mode 100644
index 0000000..a580195
--- /dev/null
+++ b/ext_localconf.php
@@ -0,0 +1,11 @@
+addJsCss';
+ }
+);
+
+