Change the friendly URL of a web content in Liferay - liferay-6

I am currently using an article display page to display my web content in Liferay 6.2. I'm trying to figure out how to edit the path of my friendly URL after the /-/.
Current URL: siteName/-/articleName
Desired URL: siteName/-/topicSection/articleName

You are talking about the attribute JournalArticle.urlTitle. The problem is, that there is no UI in Liferay, which lets you change that attribute (at least not out of the box).
You've got two options:
If you just want to change an existing article, you can change that attribute in the database (I'd guess that the additional / is no problem):
UPDATE JournalArticle
SET urlTitle = 'topicSection/articleName'
WHERE urlTitle = 'articleName'
If you want to offer an UI for editing that attribute, you could write a hook.
Here a short summary how to write such a hook:
Add this lines to your liferay-hook.xml:
<portal-properties>portal.properties</portal-properties>
<language-properties>Language.properties</language-properties>
<custom-jsp-dir>/WEB-INF/custom_jsps</custom-jsp-dir>
Create a file portal.properties in the Java source directory and add this line:
journal.article.form.update = urlTitle
Create a file Language.properties in the Java source directory and add this line:
urlTitle = Friendly URL
Add a file WEB-INF/custom_jsps/html/portlet/journal/article/urlTitle.jsp into the web content folder:
<%# include file="/html/portlet/journal/init.jsp" %>
<% JournalArticle article = (JournalArticle)request.getAttribute(WebKeys.JOURNAL_ARTICLE); %>
<aui:model-context bean="<%= article %>" model="<%= JournalArticle.class %>" />
<h3>Friendly URL</h3>
<aui:input name="urlTitle" />

Related

Rails 5.2.0 - scaffold `form_with` includes `local: true` by default

When I scaffold a Rails 5.2.0 app, my scaffolded forms are always generated with the local: true option included in form_with.
rails g scaffold Article title:string
Generated scaffold form
<%= form_with(model: article, local: true) do |form| %>
<% if article.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% article.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
Generated HTML
<form action="/articles/1" accept-charset="UTF-8" method="post">
Note the lack of data-remote attribute
Documentation
I thought the default for form_with in Rails 5.1.2+ was to use remote AJAX / xhr requests with data-remote attributes? In other words, NOT include the local: true option.
See: http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_with
By default form_with attaches the data-remote attribute submitting the form via an XMLHTTPRequest in the background if an Unobtrusive JavaScript driver, like rails-ujs, is used. See the :local option for more.
Note - rails-ujsgem was moved into Rails itself in 5.2.0 - https://github.com/rails/rails-ujs. So it looks like I should not need to add anything to the gemfile to enable the default form_with behavior.
Troubleshooting
I do use a .railsrc and a rails template file to customize my rails new scaffolds. However, I have tried disabling & removing both files and still get same results from new scaffolded apps.
To give a more complete answer based on my comment, here's how to add a template to customize the form partial generated by Rails when using the scaffold generator. I'm assuming here that you're using ERB, but the procedure is similar if you're using something like slim-rails to customize your view generators.
Create a file in your Rails project: lib/templates/erb/scaffold/_form.html.erb.tt
For this new file's content, a good place to start from is the content in the existing template. You can use gem which rails to locate the file that defines Rails in your current environment (with a result like /home/<user>/.rvm/gems/ruby-2.5.0#<gemset>/gems/railties-5.2.0/lib/rails.rb), and from there you can find the form template in railties-5.2.0/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt. Copy the contents of that file into your new generator template.
Try making some changes to the new template file, and then run the rails scaffold generator (rails g scaffold foo ...). You should see your changes reflected in the _form.html.erb file created by the generator.
Bear in mind that this template is 'doubly nested' ERB, meaning that it is processed with ERB a first time to produce a view partial, and then processed again every time your Rails app serves a request with it. That said, it's usually not too mind-melting to make a simple change, such as removing local: true from your new template
In depth info on customizing Rails generators is available at RailsGuides.
Think I found answer - and it's simple :) - the Rails scaffold templates for 5.2.0 explicitly include the local: true option.
5.2.0 Template for forms
<%%= form_with(model: <%= model_resource_name %>, local: true) do |form| %>
So I guess they wanted local: true as the default template for scaffolds. Probably for simplicity?
To find the scaffold generator templates
Thanks to this post for helping find the source: Override Rails scaffold generator
Find where your gems live with gem enviornment command
I use rbenv, so mine are at ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems
cd into that file and look for railties-5.2.0
search in rails/generators/scaffold/templates, or just search for local: true
here's the path: ~/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/railties-5.2.0/lib/rails/generators/erb/scaffold/templates/_form.html.erb.tt

Joomla 3 redirect after wrong login try

Iam using the login module of Joomla. Login and Logout redirects to the pages which are set in the modul settings.
My problem is the status, where a user tries to login with wrong user credentials. In this case, the user will be redirected to component/users/?view=login page. In my case, this page is not in use and also not designed like the rest of the pages. Therefore I would like to redirect the user, after a wrong login, to the previous page.
Does anybody have a clue, how to solve that?
thx
You will need to modify users controller. But to keep it "update proof" you cannot modify the core code, thats why we will make an override:
Go to the components/com_users/controllers/ and duplicate a file called user.php, you can call a new file user2.php
Open user2.php file and rename controller class to UsersControllerUser2
Create a template override of your login module (to make it update proof also), create a templates/YOUR_TEMPLATE/html/mod_login folder and copy modules/mod_login/tmpl/default.php file there.
Open file created in step 3 and change login module task from <input type="hidden" name="task" value="user.login" /> to <input type="hidden" name="task" value="user2.login" />
Open user2.php file once again, and modify this part of code (around lines 77-82):
$app->redirect(JRoute::_('index.php?option=com_users&view=login',
false));
Change $app->redirect route to whatever you want :)
The best way to do this is with a template override for the mod_login module. This link details the specifics of how to do that.
http://docs.joomla.org/Layout_Overrides_in_Joomla
Basically, you copy the file located at /modules/mod_login/tmpl/default_login.php to /templates/{YOUR_TEMPLATE}/html/mod_login and this is what Joomla will use to render any mod_login modules as long as you keep the file name the same.
At line 116 you will see this line of code:
<input type="hidden" name="return" value="<?php echo $return; ?>" />
You now have full programmatic control of what the return value should be. I usually pass the base64 encoded return param in the URL, which I in turn parse and insert as the value of the return hidden input in my module template override
A side note, you should never alter core files or place custom files along side core files for a variety a reason, the primary being any subsequent Joomla update could wipe out your changes breaking your website.
In Joomla 3.6.1 in order to stay in the same page after a wrong login, you have to change a line in /components/com_users/controllers/user.php
Find:
if (true !== $app->login($credentials, $options))
{
// Login failed !
// Clear user name, password and secret key before sending the login form back to the user.
$data['remember'] = (int) $options['remember'];
$data['username'] = '';
$data['password'] = '';
$data['secretkey'] = '';
$app->setUserState('users.login.form.data', $data);
$app->redirect(JRoute::_('index.php?option=com_users&view=login', false));
and just comment the last line:
// $app->redirect(JRoute::_('index.php?option=com_users&view=login', false));
That's all.
di3sel great override, still working on 2019, in your step 3 you could add:
Create a template override of your login module (to make it update proof also), create a templates/YOUR_TEMPLATE/html/mod_login folder and copy modules/mod_login/tmpl/default.php file there with a different name like altlogin.php
In the admin area open yout mod_login, in the advanced tab you'll find "Presentation", and select the view you created in step 3 "altlogin" from your template.
Thanks.

app_offline.htm file does not work

I have been battling with this for ages now but I just can not get it to work.
Every blog/site I have been too says there is nothing you need to do in IIS but this cannot be correct as there are multiple website configurations such as Application, virtual directory, simple php/asp websites, vitual.
Can someone please explain to me what the setup needs to look like in IIS7.
I have:
Checked the file spelling: app_offline.htm
Made sure the file was at least 512 bytes (saw this on a random site)
Made sure it is in fact in the root of the application/website
Checked that I can browse directly to the file
Made sure the application pool framework was set to v2.0 or v4.0
Made sure the above application pool was assigned to my website
Tried this in a new website in IIS where the app_offline.htm was the only file in the root.
I have multiple websites set up that I have tested with, namely:
MVC3 Web Application
PHP Simple Website
Classic ASP Simple Website
Webforms Website
Webforms Application
Virtual folders in the above sites
Applications within the above sites
All of the above are working, and placing the app_offline.htm does absolutely nothing.
Please can someone provide some clarity.
I recently had the same issue with the app_offline file and the real problem I had was that windows was set to hide known file extensions. So when the file app_offline.htm was created I thought that the name was correct, but windows was hiding the extension .txt.
Create a web.config file with following content
<?xml version="1.0"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
Hope that helps.
I was also struggling a little bit with this issue.
Along with the fore-mentioned criteria in the other answers. It turns out that the file type MUST be specified specifically .htm NOT .html.
I had the same issue, and although I couldn't solve it, I found a reasonable workaround. I added the same file, but named "appoffline.htm" to the root directory and leave it there permanently.
When I need to take application offline, I use the IIS HTTP Redirection setting for the website to redirect all incoming requests to appoffline.htm (make sure to tick "Redirect all requests to exact destination").
So I never did find a solution to this problem but I did find an alternative to what I was trying to achieve.
Basically, I wanted to show a specific "offline" page per app which would show when the site was offline. Here is what I did...
I created a website I called "_offline" in IIS. I then added a generic "catch all" binding for Port: 80 and left the host name blank. You may need to disable your current default website before this binding will be accepted.
Create an index.html page and put whatever content in there you want to show and shove it as the default page for "_offline". I'll include a bit of script below that works pretty well.
Now you can test by turning off your website, you should see your new index page. If you can't turn off the website, add a binding in your hosts file to anything like "testdomain.com" and point that to your server. Entering that in your browser should then show your offline page.
Just bare in mind, this page will show any time your IIS can not find an active website at the address coming in. Depending on your setup, this may or may not be acceptable in which case you should not use this method.
Now for my index page. I put some javascript in to determine which site the user is trying to reach, then reveal a portion of the html. I also have a countdown that runs and tries to refresh the page every 10 seconds.
Anyway, not the ideal result, but it works.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width = device-width">
<title>Under Maintenance</title>
</head>
<style>
body{
color:#014795;
}
.container{
max-width:650px;
margin:auto;
font-size:18px;
font-family:Arial, Helvetica, sans-serif;
padding:20pt;
text-align:center
}
#logo img {
max-width:100%;
}
a {
color: inherit;
text-decoration: none;
}
a:hover {
color: inherit;
text-decoration: none;
}
</style>
<body>
<table class="container">
<tr>
<td>
<span id="logo"></span>
<p>This site is currently under maintenance and will be available shortly.</p>
<p>We apologize for any inconvenience caused.</p>
<table style="text-align:left;margin:auto;">
<tr><td>Telephone:</td><td>+27 11 11 1111</td></tr>
<tr><td>Fax:</td><td>+27 11 111 2222</td></tr>
<tr><td>Email:</td><td>support#fubar.com</td></tr>
</table>
<p>We will automatically try to reconnect you in <span id="timeleft"></span> seconds</p>
</td>
</tr>
</table>
<script type="text/javascript">
var refreshEvery = 10;
var currentSec = 0;
var timer = setInterval(function() {
currentSec++;
if (currentSec >= refreshEvery) {
clearInterval(timer);
location.reload();
}
document.getElementById("timeleft").innerHTML = "" + (refreshEvery - currentSec);
}, 1000)
document.getElementById("timeleft").innerHTML = "" + (refreshEvery - currentSec);
// Use this site to create a base64 image http://www.base64-image.de/step-1.php
if (document.domain.indexOf("stacksnippets") >= 0) {
// Cusomise the site here, you can also show hide html content.
document.body.style.backgroundColor = "black";
document.body.style.color = "white";
} else {
// put default stuff here
}
</script>
</body>
</html>
Try to start out with a fresh and simple app_offline.htm file, like
<html><body>offline</body></html>
to see if that fixes the problem. In my case the problem was that the file encoding of the app_offline.htm file was "UTF-8 with BOM" rather than plain UTF-8.
The following handler also needs to be present:
ExtensionlessUrlHandler-Integrated-4.0
Make sure that in IIS Manager, on the website's Properties, the Application name has been created. Properties > Directory > Application settings > Application name.
Tested in IIS V6.0
None of the solutions above worked for us.
When testing on the server with same file but renamed (app_offline.TEMPLATE.htm) the server loaded the htm page without issue.
This was resolved by removing the large-ish Base64 encoded image from the file. (used as a background-image)
The app_offline.htm file still uses a Base64 encoded favicon and company logo image.

Unable to use Liferay Freindly URL Mapper

I was following this document from Liferay Website to work Map Firendly URL Mappings
http://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/adding-friendly-url-mapping-to-the-portlet
I am using Liferay version=6.1.0
During HyperLink navigation , i was getting the following url
http://localhost:8080/web/guest/what-we-do?p_p_id=sai_WAR_Saiportlet&
p_p_lifecycle=0&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1
&_sai_WAR_Saiportlet_jspPage=%2Fhtml%2Fsai%2Fedit.jsp
To modify the above i have tried to use Friendly URL Mapper and i have done the following way
Inside liferay-portlet.xml file .
<portlet>
<portlet-name>sai</portlet-name>
<icon>/icon.png</icon>
<friendly-url-mapper-class>com.liferay.portal.kernel.portlet.DefaultFriendlyURLMapper</friendly-url-mapper-class>
<friendly-url-mapping>sai</friendly-url-mapping>
<friendly-url-routes>com/test/sai-friendly-url-routes.xml</friendly-url-routes>
<instanceable>false</instanceable>
<header-portlet-css>/css/main.css</header-portlet-css>
<footer-portlet-javascript>
/js/main.js
</footer-portlet-javascript>
<css-class-wrapper>sai-portlet</css-class-wrapper>
</portlet>
Created a new file by name sai-friendly-url-routes.xml inside
D:\liferay-plugins-sdk-6.1.0-SNAPSHOT\portlets\Sai-portlet\docroot\WEB-INF\src\com\test\sai-friendly-url-routes.xml
The content inside sai-friendly-url-routes.xml is
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE routes PUBLIC "-//Liferay//DTD Friendly URL Routes 6.1.0//EN" "http://www.liferay.com/dtd/liferay-friendly-url-routes_6_1_0.dtd">
<routes>
<route>
<pattern>/{mvcPathName}</pattern>
<generated-parameter name="mvcPath">/{mvcPathName}.jsp</generated-parameter>
</route>
</routes>
But i observed there is no change in the url
http://localhost:8080/web/guest/what-we-do?p_p_id=sai_WAR_Saiportlet&p_p_lifecycle=0&p_p_state=normal&p_p_mode=view&p_p_col_id=column-1&p_p_col_count=1&_sai_WAR_Saiportlet_jspPage=%2Fhtml%2Fsai%2Fedit.jsp
Please let me know where exactly i am doing mistake .
You leave the values as they are. That is, you leave {mvcPathName} and "mvcPath" as-is.
When the friendly URL is generated, it parses mvcPath (i.e., edit.jsp or view.jsp) from the URL and then the pattern is applied, replacing .../edit.jsp with .../edit.
This example works for the edit JSP. And it works for the view page; but NOT when clicking Save ... which is something I could look into. However, if you go to edit and then click the back link, the friendly URL will show for the view JSP.
I've created a ticket to complete this example so that it also goes to a friendly URL when clicking save. I'll update this section when we've made the fix.
Thanks.

Get displaytag to use an action URL for page switching

I'm trying to use external paging in a JSR-286 portlet with DisplayTag 1.2.
I would like DisplayTag to generate the paging links from a parameterized Action URL that i have defined, but i can't seem to make that work.
Here is the code in my JSP:
<portlet:actionURL var=actionUrl >
<portlet:param name="someParam" value="someValue" >
</portlet:actionURL >
<display-el:table id="personsTable"
name="${portletSessionScope.persons}"
requestURI="${actionUrl}"
partialList="true"
size="${portletSessionScope.total}"
pagesize="${portletSessionScope.pageSize}" >
<display-el:column property="firstName"/ >
</display-el:table >
With the above code, it looks like Display-tag ignores the provided ${actionUrl} and generates a default Render URL. The generated links work fine (i can move through pages), but since my portlet requires an Action request to fetch other pages of data, the list in the session is never updated and the table always contains the same data, regardless of which page i select.
Is there a way i might make that work? Does DisplayTag support what i'm trying to do?
Thanks in advance for your help!
Create a form in your JSP and pass the form name to the displaytag:table as form attribute value. This will invoke the action URL that you have specified.