I have added new input fields to the page properties (below the categories):
TCA/Overrides/pages.php
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'pages',
'--palette--;My palette label;eventdetails',
'1', // List of specific types to add the field list to. (If empty, all type entries are affected)
'after:categories' // Insert fields before (default) or after one, or replace a field
);
// Add the new palette:
$GLOBALS['TCA']['pages']['palettes']['eventdetails'] = array(
'showitem' => 'event_location,event_organizer,event_additional_info'
);
The tabulator label "Category" from LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_category.tabs.category is now no longer suitable (I would prefer "Event properties") . Is it possible to overrite sys_category.tabs.category somehow?
UPDATE:
Sorry that I misunderstood.
You can overwrite backend labels with your own xlf files.
ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:core/Resources/Private/Language/locallang_tca.xlf'][] = 'EXT:your_extension/Resources/Private/Language/yourtranslationfile.xlf';
Resources/Private/Language/yourtranslationfile.xlf
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<xliff version="1.0">
<file source-language="en" datatype="plaintext" original="messages" date="2019-11-11T17:23:27Z" product-name="your_extension">
<header/>
<body>
<trans-unit id="sys_category.tabs.category">
<source>Event properties</source>
</trans-unit>
</body>
</file>
</xliff>
See translation handling in TYPO3 doc
Original answer (add a custom tab to page properties):
You can just add "--div--;Your tab label" to this.
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
'pages',
'--div--; My new tab, --palette--;My palette label;eventdetails',
'1',
'after:categories'
);
You don't need (or better you should not) override the categories tab. Actually, this tab won't be displayed, if there are no fields in it (restrict access to categories by access management).
Related
I'm using Tinymce 5.9.1 with template plugin.
I made a new template like this code with special css code :
templates: [
{title: 'green-box', description: 'box tiny green', content: '<div class="tiny-green-box"> Content </div><div class="p-1"></div></br>'},],
It works when edit content in one line. when i want to put multiple line there is a problem.
Tinymce duplicates template for every new line.
for example if i type line1 and press ENTER it will create new div and result will be something like this :
you can see in html code it repeates many time :
putting content inside an extra <p></p> tag can solve this problem.
final code must be something like this :
templates: [
{
title: 'green-box',
description: 'box tiny green',
content: '<div class="tiny-green-box"><p> Content </p></div><div class="p-1"></div></br>'
}
,],
The result HTML code will be like this :
<div class="tiny-green-box">
<p>line 1</p>
<p>line 2</p>
<p>line 3</p>
<p>line 4</p>
</div>
In an extension, I would basically like to do what the core does when you click the button "Add media by URL" on an existing textmedia element.
I tried to look in the source code but did not find any convenient API function I could use. Perhaps I could use DataHandler for this?
What the core does is create a textfile (e.g. .youtube) which contains the video id. It then creates a record for this file in sys_file and a file reference (sys_file_reference) between the record in tt_content and the file record in sys_file.
I am using the latest TYPO3 8.
I don't have a complete solution, but I recently had to do something similar:
Create a file from the Video URL and create the corresponding sys_file record:
The class OnlineMediaController::createAction does what you are looking for. Specifically, the function OnlineMediaHelperRegistry::transformUrlToFile will transform the video URL to a file (creating it if necessary).
To use the existing action, you can use the Ajax Route online_media_create.
Or, you can use the existing action to model your own code.
Create a relation between existing records in sys_file and tt_content:
See Creating a file reference (TYPO3 documentation)
Sample code: (Most of the code taken from Creating a file reference)
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Backend\Utility\BackendUtility;
...
protected function addMediaByUrl($url, $uid)
{
$targetFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
$file = OnlineMediaHelperRegistry::getInstance()->transformUrlToFile(
$url,
$targetFolder
);
$contentElement = BackendUtility::getRecord('tt_content', $uid);
$newId = 'NEW1234';
$data = array();
$data['sys_file_reference'][$newId] = [
'table_local' => 'sys_file',
'uid_local' => $file->getUid(),
'tablenames' => 'tt_content',
'uid_foreign' => $contentElement['uid'],
'fieldname' => 'assets',
'pid' => $contentElement['pid']
];
$data['tt_content'][$contentElement['uid']] = [
'assets' => $newId
];
// Get an instance of the DataHandler and process the data
/** #var DataHandler $dataHandler */
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start($data, array());
$dataHandler->process_datamap();
// Error or success reporting
if (count($dataHandler->errorLog) === 0) {
// Handle success
} else {
// Handle error
}
}
Maybe you look here for good examples
YoutubeVideo, Vimeo, Video-Files, More Informations you can find at the vhs Docs
Or you could do something like this:
<flux:form id="youtubevideo" label="YouTubeVideo" description="Einbetten eines
YouTube Videos als iframe">
<flux:form.option name="optionsettings">
<flux:form.option.group value="Content" />
<flux:form.option.icon
value="EXT:extension_key/Resources/Public/Icons/Content/YouTubeVideo.svg" />
</flux:form.option>
<flux:field.input name="settings.videoid" label="YouTube Video ID. Entnehmen
Sie die ID aus der YouTube URL. Beispiel: https://www.youtube.com/watch?
v=UX12345678 Die ID ist UX12345678" />
<flux:field.select name="settings.videoformat" label="Video Format"
maxItems="1" multiple="0" default="YouTubeVideo--normal" items="{YouTubeVideo--
normal: 'Normal (4:3)', YouTubeVideo--widescreen: 'Widescreen (16:9)'}"/>
<flux:field.checkbox name="settings.gridPull" label="Bleed Outside (Randlos
glücklich)" default="0" />
</flux:form>
...
<div class="YouTubeVideo {settings.videoformat}">
<iframe width="640" height="480" src="//www.youtube-
nocookie.com/embed/{settings.videoid}?rel=0&showinfo=0" allowfullscreen>
</iframe>
</div>
Finally found the solution:
The key is to set the correct "allowed extensions": add "youtube" or "vimeo".
This will automatically add the missing "Add media by URL" button.
Example using Flux Inline FAL:
<f:section name="Configuration">
<flux:form id="myCustomVideoContentElement">
<flux:field.inline.fal name="settings.records" label="video"
multiple="false" minItems="1" maxItems="1"
allowedExtensions="mp4,mkv,youtube,vimeo"
/>
</flux:form>
</f:section>
(Typo3 9.5)
I have a requirement: I need to add descriptive texts for Radio Buttons as shown below.
It's currently not possible to add such a description under the text of sap.m.RadioButton. However (same as this answer), you can achieve similar behavior, look, and feel in the following combination:
Use sap.m.List with
mode="SingleSelectLeft"
backgroundDesign="Transparent"
showSeparators="None"
In its items aggregation, use a subclass of ListItemBase that supports description / info. Use CustomListItem if nothing suites.
sap.ui.getCore().attachInit(() => sap.ui.require([
"sap/m/List",
"sap/m/StandardListItem", // or ObjectListItem, CustomListItem, etc..
], (List, StandardListItem) => new List({
mode: "SingleSelectLeft", // displays radio buttons.
showSeparators: "None", // between items
backgroundDesign: "Transparent",
includeItemInSelection: true,
width: "19rem",
}).addItem(new StandardListItem({
title: "Others",
description: "3rd Party Vendor Lis",
})).placeAt("content")));
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.core, sap.m"
data-sap-ui-preload="async"
data-sap-ui-theme="sap_belize"
data-sap-ui-xx-waitForTheme="true"
></script><body class="sapUiBody sapUiSizeCompact" id="content"></body>
I am working on an application using admin-on-rest framework. For editing an entry on a Resource we provide XXXEdit, XXXShow, XXXCreate props to it. My requirement is that when I click on an Edit button in List view on any entry I should get a Dialog box with the parameters in XXXEdit instead of going to a new page. I tried doing this by using a Dialog in XXXEdit component
<Edit title={<RoleTitle />} {...props}>
<SimpleForm>
<Dialog
title="Dialog With Actions"
actions={actions}
modal={false}
open={true}
>
<TextInput source="id" />
<TextInput source="name" validate={required} />
.
.//some more fields
</Dialog>
</SimpleForm>
</Edit>
I get errors like The TextInput component wasn't called within a redux-form
If I use a DisabledInput then I get an error cannot read value of undefined
How do I go on with this?
I do not think you can use Simpleform for this. You will need to create a custom Form using Redux-Form. Look at the bottom answer that documents the final answer.
This might help you
How to richly style AOR Edit page
Instead of creating a page. You are creating a component that connects to the Redux state and displays as a dialog box.
I tried to resolve this using HOC and react-router.
I created a button using AOR button and provided a containerElement
containerElement={
<Link
key={record.id}
to={{
...{
pathname: `${basePath}/${encodeURIComponent(record.id)}`
},
...{ state: { modal: true } }
}}
/>
}
I created a route like this where DialogRoleEdit is an AOR edit component wrapped with a dialog HOC below .
<Route
exact
path="/roles/:id"
render={routeProps => {
return !!(
routeProps.location.state && routeProps.location.state.modal
) ? (
<Restricted authClient={authClient} location={routeProps.location}>
<div>
<RoleList resource={"roles"} {...routeProps} />
<DialogRoleEdit resource={"roles"} {...routeProps} />
</div>
</Restricted>
) : (
<Restricted authClient={authClient} location={routeProps.location}>
<RoleEdit resource={"roles"} {...routeProps} />
</Restricted>
);
}}
/>
Finally an HOC
handleClose = () => {
this.props.history.goBack();
};
render() {
const actions = [
<FlatButton label="Cancel" primary={true} onClick={this.handleClose} />
];
return (
<Dialog>
<WrappedComponent/>
</Dialog>
)
}
We need to provide edit prop for this resource in App.js
edit={DialogUserEdit}
I've been struggling for about 5 hours trying to understand why Shrine is blocking my uploads. I either get errors like "Shrine: Invalid file", or "Expected Array but got string" in strong params. If there aren't errors, the images aren't actually saved.
require "image_processing/mini_magick"
class ImageUploader < Shrine
include ImageProcessing::MiniMagick
plugin :activerecord
plugin :backgrounding
plugin :cached_attachment_data
plugin :determine_mime_type
plugin :delete_raw
plugin :direct_upload
plugin :logging, logger: Rails.logger
plugin :processing
plugin :remove_attachment
plugin :store_dimensions
plugin :validation_helpers
plugin :versions
Attacher.validate do
validate_max_size 2.megabytes, message: 'is too large (max is 2 MB)'
validate_mime_type_inclusion ['image/jpg', 'image/jpeg', 'image/png', 'image/gif']
end
def process(io, context)
case context[:phase]
when :store
thumb = resize_to_limit!(io.download, 200, 200)
{ original: io, thumb: thumb }
end
end
end
class Image < ActiveRecord::Base
include ImageUploader[:image]
belongs_to :imageable, polymorphic: true
end
class Product < ApplicationRecord
has_many :images, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :images, allow_destroy: true
...
# Strong Params:
def product_params
params.require(:product).permit(
:name, :brand_id, :category_id, :price, :compare_price, :description,
images_attributes: { image: [] },
product_properties_attributes: [:id, :property_id, :value]
)
...
And my view:
<%= f.fields_for :images do |image_form| %>
<%= image_form.file_field :image, multiple: true %>
<% end %>
According to everything I've read on the docs or from gorails, this should work. Do I need to restructure the images_attributes hash? I also tried using direct_uploads, but struggled to get the presigned_url to work with S3.
Refile makes this really easy, so I'll probably run crying back to that.
Is there something I'm obviously doing wrong?
According to the fields_for documentation, the provided block will be called for each image in the project.images collection. So if your product currently doesn't have any images, the block won't be called (according to the docs).
For nested attributes to work, you need to forward the following parameters when creating the Product:
product[images_attributes][0][image] = <file object or data hash>
product[images_attributes][1][image] = <file object or data hash>
product[images_attributes][2][image] = <file object or data hash>
...
If you look at the "Multiple Files" Shrine guide, it's recommended that you just have a single file field which accepts multiple files:
<input type="file" name="file" multiple>
And then setup direct uploads for this field using Uppy, dynamically generating the image field for each uploaded file populated with the uploaded file data hash:
<input type="hidden" name="product[images_attributes][0][image]" value='{"id":"...","storage":"cache","metadata":{...}}'>
<input type="hidden" name="product[images_attributes][1][image]" value='{"id":"...","storage":"cache","metadata":{...}}'>
....
Alternatively you can just let users attach multiple files, which are all submitted to the app, and then destructure them in the controller:
class ProductsController < ApplicationController
def create
images_attributes = params["files"].map { |file| {image: file} }
Product.create(product_params.merge(images_attributes: images_attributes))
end
end
In that case you have to make sure your HTML form has the enctype="multipart/form-data" attribute set (otherwise only the files' filenames will get submitted, not files themselves).