How can I create uneditable fields on CK Editor? - asp.net

In my app, admins can change form template and users should fill in the blanks in this form using CK Editor or other editors. But when I show form to user, they can remove some fields. I dont wanna this. How can I create "uneditable" fields on CK Editor or can you suggest another editors for that?
Thanks in advance..

Summary TL;DR
You can use the "widget" plugin system, it is designed for this sort of usage where parts of a template are editable, but others are not. It is simply a plugin that extends the widget system to create a non-editable block with editable fields inside (you get drag'n'drop support for free too).
The example simple-box widget is located here and is very informative of the general flow for widgets, you can see the sample here:
https://sdk.ckeditor.com/samples/simplebox.html
The Tutorial
The tutorial for creating that widget is here:
https://docs.ckeditor.com/ckeditor4/latest/guide/widget_sdk_tutorial_1.html
The important part for users being able to edit certain fields is in the section Adding Editable Parts:
https://docs.ckeditor.com/ckeditor4/latest/guide/widget_sdk_tutorial_1.html#adding-editable-parts
You can add editables by normal selectors, which makes it easy to have multiple editable fields.
editor.widgets.add( 'simplebox', { // Code defined before...
editables: {
title: {
selector: '.simplebox-title'
},
content: {
selector: '.simplebox-content'
}
} } );
Explanation and Another Example
And the explanation of widgets is here with another example, which is a captioned image:
https://docs.ckeditor.com/ckeditor4/latest/guide/dev_widgets.html
Commentary
The widget uses an "upcast" function to determine whether an element should be a widget in the current CKEditor instance. If you are creating separate systems for admin & users, both using CKEditor, you can have separate upcasts for admin vs user so that you can enter templates as an admin, then upcast it to a widget when a user is editing it so that they can only edit the "editables". If you enter them directly as HTML templates in a database or whatnot, then it is even easier since you can just always upcast in the widget plugin.
The relevant section about upcasting is here:
https://docs.ckeditor.com/ckeditor4/latest/guide/widget_sdk_tutorial_1.html#how-does-a-widget-become-a-widget
And it has a very simple syntax as well:
editor.widgets.add( 'simplebox', {
// Code defined above...
upcast: function( element ) {
return element.name == 'div' && element.hasClass( 'simplebox' );
}
} );

#Baki, editor content area is an open space where you can type and remove anything what makes deletion preventing pretty hard if not impossible. There is a large amount of cases to handle.
If you have form fields that you wish some to be editable and some not, please "go around". instead of trying to do this inside the editor, use the editor only for edible fields. Your form can be a standard non-editable HTML page where you have editable parts on which you can create the editor. Example of such a page could look like so:
<div class="container">
<h1><p>Hello </p><p contenteditable="true">[NAME]</p>,</h1>
<div class="text">
<p>I'm pleased to inform you the total sales has reached<p>
<p contenteditable="true">[AMMOUNT]</p>
<p>units...</p>
</div>
</div>
Working code would look like:https://jsfiddle.net/zqmLLjfh/3/

Related

Override item-list.html.twig & time.html.twig inside a view

I've created a view that outputs a <ul> with a <time> element in each <li>. I need to convert the HTML list to a select.
So I did 2 things:
Copied item-list.html.twig and changed <ul> to a <select>
Copied time.html.twig and changed <time> to <option>
Although this works I need those 2 templates to be scoped to my view named: 'vcon-selection-table'. I tried many things but nothing works:
views-view-table--vcon-selection-table--item-list.html
views-view-table--vcon-selection-table-item-list.html
views-view-table--vcon-selection-table.html--dataset-item-list
So the question is: What template name should I use to override the templates item-list.html.twig and time.html.twig inside my view?
Is the purpose of that view to only provide that <select> element and <option> elements? Then this really isn't the way to go. Don't build a form or form elements with Views.
You'd better provide a custom form or a custom item_list in a custom block. The block then can be placed where ever you need it. There are plenty of tutorials out there. Maybe take the following as a starting point: https://valuebound.com/resources/blog/creating-a-custom-form-in-a-block-in-two-steps-in-Drupal-8
Otherwise, if you really want to continue your road I think you have to simply preprocess the list and time fields to switch to a different template according your desired conditions. I strongly guess there is no option that a custom template for a field from a node in a view will automatically be taken into account by naming patterns. You have to add that template suggestion manually first.
Snippet to be placed in MYMODULE.module file or MYTHEME.theme file.
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function MYMODULE/MYTHEME_theme_suggestions_item_list_alter(array &$suggestions, array $variables) {
// Use \Drupal::routeMatch() to get the current view ID or some other indicator.
// Sample: Get the current view ID.
$view_id = \Drupal::routeMatch()->getRouteObject()->getDefault('view_id');
// Install Devel, Kint module, then uncomment the following line and flush caches to inspect the outcome.
// ksm($view_id);
// Add the template suggestion.
// Add your template now under /templates/item-list--VIEWID.html.twig
if (!empty($view_id)) {
$suggestions[] = 'item_list__' . $view_id;
}
}
Downside of this approach is that this would trigger all item_lists that live on that exact page/view to take this template. You could fine-grain your templating much better with a custom module and a custom item_list and/or form.
Alternatively you can also move the logic to the date field and a custom view mode and an extra template for that. Then at least it stays where it belongs to.
To enable Twig debugging and getting the built-in template suggestions printed as HTML comments follow this article: https://www.drupal.org/docs/8/theming/twig/debugging-twig-templates

Hide page sections based on user role in Visual Composer

I am trying to hide certain page sections based on user role in Visual Composer by adding Custom Content Shortcode in two text blocks. The first text block is at the top of the content I want to hide to all but admins and contains:
[is role=administrator]
The second text block, at the bottom of the content I want to hide, contains the closing tag,
[/is]
This is doing what it's supposed to and hiding the content, however, Visual Composer doesn't seem to like it, and VC shortcode winds up getting outputted to the page for admins, i.e. [/vc_column]. I can't get it to not display the VC shortcode. It's strange too that it only outputs the shortcode for admins.
If there is a different or better way to do what I'm trying to accomplish, I'm open to any solutions! I just want certain page sections to only be visible to admins.
You could use the header function to use Jquery to remove the elements via css class for each user.
Below is not a tested solution but can be a way to achieve what you wanted but not sure how to remove completely the output source code only hide it.
This can be added to the function file or built into a plugin.
function insert_header()
{
// Check what user role
global $current_user;
$user_roles = $current_user->roles;
$user_role = array_shift($user_roles);
//return $user_role;
// Check if the user has role
if($user_role == "editor")
{
// inject jQuery or css to remove the elements by class
}
}
add_action('wp_head','insert_header');

How to disable page's title in wp-admin from being edited?

I have a wp-network installed with users that can create pages in each site.
Each of those pages get a place in the primary menu, and only one user have permission to create all this menu.
I want to create a user only to be able to edit the content of the pages, but not the title.
How can I disable the title of the page to be edited from the admin menu for a specific user, or (far better) for a capability?
I thought only a possibility, that's editing admin css to hide the title textbox, but I have two problems:
I don't like to css-hide things.
I don't know where is the admin css.
I know php, but don't know how to add a css hide to an element for a capability.
You should definitely use CSS to hide the div#titlediv. You'll want the title to show in the markup so the form submission, validation, etc continues to operate smoothly.
Some elements you'll need to know to implement this solution:
current_user_can() is a boolean function that tests if the current logged in user has a capability or role.
You can add style in line via the admin_head action, or using wp_enqueue_style if you'd like to store it in a separate CSS file.
Here is a code snippet that will do the job, place it where you find fit, functions.php in your theme works. I'd put it inside a network activated plugin if you're using different themes in your network:
<?php
add_action('admin_head', 'maybe_modify_admin_css');
function maybe_modify_admin_css() {
if (current_user_can('specific_capability')) {
?>
<style>
div#titlediv {
display: none;
}
</style>
<?php
}
}
?>
I resolved the problem, just if someone comes here using a search engine, I post the solution.
Doing some research, I found the part of the code where the title textbox gets inserted, and I found a function to know if a user has a certain capability.
The file where the title textbox gets added is /wp-admin/edit-form-advanced.php. This is the line before the textbox
if ( post_type_supports($post_type, 'title') )
I changed it to this
if ( post_type_supports($post_type, 'title') and current_user_can('edit_title') )
That way, the textbox is only added when the user has the capability called "edit_title"
When this IF block ends few lines after, I added:
else echo "<h2>".esc_attr( htmlspecialchars( $post->post_title ) )."</h2>";
To see the page title but not to edit it, when the user hasn't got "edit_title" capability.
Then I had already installed a plugin to edit user capabilities and roles, wich help me to create a new capability (edit_title) and assign it to the role I want.

Creating a link field in a custom content type

I have several custom content types and in one specific one I need to offer two fields, one for the href for a link, and one for the text of a link this way I can build and style it with minimal user involvement of the HTML/CSS. I also have a custom node.tpl for this content type. My problem is that drupal throws divs around each field I create that aren't in my template file for this content type (node-custom.tpl) and I can't put the href for a link with divs around it inside google.co.uk</div>"> See my problem. Maybe I'm doing this all wrong so any other ideas are welcome.
Please note I'm trying to create this site with minimum involvement of HTML/CSS access for the user. I'm aware I could hand code the link in the field.
The easiest way to do this would be to use a preprocess function in your template.php file and build the link up manually:
function mytheme_preprocess_node(&$vars) {
$node = $vars['node'];
if ($node->type = 'my_type') {
$uri = $node->field_name_of_link_field[LANGUAGE_NONE][0]['value'];
$text = $node->field_name_of_display_text_field[LANGUAGE_NONE][0]['value'];
$vars['my_link'] = l($text, $uri); // Using Drupal's l() function to render a link
}
}
Then in your node template file you'll have access to the variable $my_link which you can output anywhere, and will contain the correct HTML for the link. Finally, go to the "Manage Display" page for your content type and set the display of the two fields you no longer need to output to 'Hidden'.
There are other ways so if that's no good let me know
EDIT
Just to add, I think the easiest way to do this would actually be to install the Link module and use the provided field type instead of the two other fields you're currently using.

Conditional link to node within views?

I have two content types, book and chapter. Each chapter node contains a node reference of the book to which it belongs. I have created a view which displays the title of each chapter for a given book. Within the view, the title field has been configured to link to its node.
All works well. I am now interested in updating the view to not display a link to a chapter's node when the chapter's body is empty. Thus this view would display a list of chapter titles for a book and link only to those chapters that have a body.
Can this be accomplished using out of the box Views functionality? If not, how would something like this be accomplished?
Thanks.
I'd use the Views Custom Field module to implement your custom logic. It allows you to grab the data fetched by Views and manipulate it at will with PHP. Very handy.
I'm answering my own question because my response to ceejayoz is poorly formatted.
What I did to accomplish this was to first download and enable views_customfield. Second, I placed Title and Body fields within the view, both excluded from display. Third, within a Customfield: PHP code field I placed the following code:
<?php
if (strlen(trim($data->node_revisions_body)) == 0) {
return $data->node_title;
} else {
return l($data->node_title, drupal_get_path_alias('node/' . $data->nid));
}
?>
There's also this clever workaround which allows you to achieve this very easily:
Add 2 title fields one with link and one with no link, and make both
them exclude from display.
Add body field,
In No result behavior put title with no link replacement token to
it.
In Rewrite results behavior put title with link replacement token to
it.
Tick hide if empty.
Source

Resources