How to change css, templates, translation in SRM (>= 7.6.04, 8.0, 8.1)

Version 7
    Share This:

    Hi

     

    This document is here to summarize some work we made on the BMC Community on SRM customization.

     

     

    I°) Disclaimer:

    1°) Modifications:

    Most of the examples involve modifications of a jar (SRMSServiceRequestBrowser.jar) file that is stored in form "Data Visualization Module" in ARS.

    Basically a "jar" file is merely a "zip" file.

    This jar contains some html templates (how to display questions for example), css files and java code necessary to display / fill the service requests.

    It is "downloaded" by the Mid-tier and stored in the "/arsys/PluginsCache/servername/" folder at first use.

     

     

    Warning:

    As you modify a BMC file, don't forget to note your modifications since during an upgrade or hotifx there are possibilities that this "jar" file is overwritten by a more recent one.

    In this case you will have to alter this new jar file and insert your modifications.

     

     

    2°) Video:

    The video has been done "live" so please forgive the french accent as well as possible small mistakes here and then.

     

     

    3°) 7.6.04 and 8.x differences:

    This document show some examples for 7.6.04 and 8.x versions.

    Though "SRMSServiceRequestBrowser.jar" isn't stored in the same record in "Data Visualization modules" depending on the SRM version and the prefix isn't the same as well (used in "AR System User Preferences" for localization).

    So if you want to apply them on your environment, be sure to get the right files and prefixes (see IV°)).

     

     

    4°) example list:

    Several examples are discussed in this document taken from real cases seen in the BMC community:

    SRM CSS Stylesheet

    How to hide "Save as Draft" in SRM 7.6.04

    Field Length On SR

    SRM8 Service Request Console localization

    In the Request Entry Console Field label wanted to display in French Locale.

     

     

    5°) tools used in the video and document (all freewares):

    Firefox: http://www.mozilla.org/en-US/

    Firebug (you can find it from Firefox modules):https://addons.mozilla.org/fr/firefox...

    Notepad ++: http://notepad-plus-plus.org/

    7zip: http://www.7-zip.org/

     

     

    II°) Css and templates modifications:

    There were quite some questions on how to alter some characteristics of a standard Service Request, or hide "draft" button (How to hide "Save as Draft" in SRM 7.6.04) for example.

    Sadly this isn't possible using Developer Studio and you need to alter a jar file named "SRMSServiceRequestBrowser.jar" that contains all those css and html templates (for questions for example).

     

    It can be used to change question's properties, for example changing from:

    01.png

    To:

    02.png

     

    You have some examples in those threads which give all directions:

    SRM CSS Stylesheet

    How to hide "Save as Draft" in SRM 7.6.04

    Field Length On SR

     

     

     

    I made a video that replies to a BMC community thread "SRM CSS Stylesheet" from Mohammed Shaheen.

    It gives a full tutorial on how to define what you want to change, how to find where it's "stored" and how to change it, beeing css or "html" template.

    I'm using SRM 8.1 for this demonstration.

     

     

    III°) Translation:

    Some words aren't translated in SRM and you need to create an entry in "AR System Message Catalog".

     

    Note:

    I won't explain how to extract the jar file, create it again and use it since it's in the video in the previous chapter or in this thread where all steps are detailed:

    Re: Field Length On SR

     

     

    1°) First example:

    In this thread "In the Request Entry Console Field label wanted to display in French Locale." Aniyan tried to change the "E-mail" to translate it.

    04.png

     

    He found that the "html template" for this was in file "\resources\templates\questions\display-sr-details.st" and was the variable "emailLabel":

    $if(showEmail)$

    <tdclass="srDetailsCellStub1"><labelfor="requester-email"class="labeltext">$emailLabel$</label></td>

    <tdclass="srDetailsCellContent"><input type="text"id="requester-email" name="requester-email"></td>

     

    In the file "SRDetailsContributor.class" I saw that the localization was using this code:

     

    srDetailsHTML.setAttribute("emailLabel", TranslationTable.getLocalizedString("questions.requester.email", "Email:"));

     


    And that actually the localization was stored in "AR System Message Catalog" with Message Identifier "SRMSServiceRequestBrowser:Messages:questions.requester.email":

    05.png

     

     

     

     

    2°) second example:

    In this other example "SRM8 Service Request Console localization" michep tried to localize "Description":

    03.png

     

    If you extract the html template file "\resources\templates\velocity\categories\services.vm" from the "SRMSServiceRequestBrowser.jar" you can see that there is a "serviceDescription" variable that should be used for the translation:

    <div id="srd_description">

        <div class="bold">$!{serviceDescripption}:</div>

        <div id="srd_description_text">$serviceData[0].description</div>

    </div>

     

    Though this time we didn't find anything in "AR System Message Catalog", so we had to create an entry there, but which one?

     

    "LocalizedStringKeys.class" file gave the solution, in this file you have all the "codes" you need:

     

    public class LocalizedStringKeys
    {
      public static final String FREQUENT_ICON_ALT = "hotlist.icon.alt";
      public static final String COMMON_ICON_ALT = "system.icon.alt";
      public static final String FAVORITE_ICON_ALT = "favorite.icon.alt";
      public static final String ADD_TO_FAVORITES_ICON_ALT = "add.to.favorites.icon.alt";
      public static final String REMOVE_FROM_FAVORITES_ICON_ALT = "remove.from.favorites.alt";
      public static final String SELECT_SERVICE_BUTTON_LABEL = "select.service.button.label";
      public static final String ADD_TO_CART_SERVICE_BUTTON_LABEL = "add.to.cart.button.label";
      public static final String SHOW_SERVICE_DETAILS_BUTTON_LABEL = "show.service.details.button.label";
      public static final String LIST_ALL_SERVICES_LINK = "list.all.services.link";
      public static final String BROWSE_CATEGORIES_LINK = "browse.categories.link";
      public static final String NO_DATA_FOUND = "no.data.found";
      public static final String MORE_CATEGORIES_LINK = "browse.categories.more.link";
      public static final String UNHANDLED_EXCEPTION = "unhandled.exception";
      public static final String QUAL_PARSE_EXCEPTION = "qualification.parsing.exception";
      public static final String SERVICE_SUBCATEGORY_TITLE = "service.subcategory.title";
      public static final String SEARCH_SERVICE_RESULTS_TITLE = "service.searchresults.title";
      public static final String SERVICE_PRICE_LABEL = "service.price.label";
      public static final String SERVICE_SRDPRICE_LABEL = "service.srdprice.label";
      public static final String SERVICE_SOPRICE_LABEL = "service.soprice.label";
      public static final String REGULAR_EXPRETION_ERROR_MSG = "regular.expretion.error.msg";
      public static final String QUESTIONS_REQ_NAME = "questions.requester.name";
      public static final String QUESTIONS_REQ_PHONE = "questions.requester.phone";
      public static final String QUESTIONS_REQ_EMAIL = "questions.requester.email";
      public static final String QUESTIONS_REQ_EDIT = "questions.requester.edit";
      public static final String QUESTIONS_REQ_LABEL = "questions.requester.label";
      public static final String QUESTIONS_REQUEST_NAME = "questions.request.name";
      public static final String QUESTIONS_REQUEST_REQDATE = "questions.request.reqdate";
      public static final String QUESTIONS_REQUEST_QTY = "questions.request.qty";
      public static final String QUESTIONS_REQUEST_EXPDATE = "questions.request.expdate";
      public static final String QUESTIONS_REQUEST_PRICE = "questions.request.price";
      public static final String QUESTIONS_REQUIRED_LABEL = "questions.required.label";
      public static final String QUESTIONS_DATEFIELD_LABEL = "questions.datefield.label";
      public static final String QUESTIONS_TIMEFIELD_LABEL = "questions.timefield.label";
      public static final String QUESTIONS_FORM_SUBMIT = "questions.form.submit";
      public static final String QUESTIONS_FORM_ADDATTACH = "questions.form.addattach";
      public static final String QUESTIONS_FORM_SUMMARY = "questions.form.summary";
      public static final String QUESTIONS_FORM_ADDCART = "questions.form.addcart";
      public static final String QUESTIONS_FORM_UPDATECART = "questions.form.updatecart";
      public static final String QUESTIONS_FORM_SAVEDRAFT = "questions.form.savedraft";
      public static final String QUESTIONS_FORM_CANCEL = "questions.form.cancel";
      public static final String QUESTIONS_FORM_PI = "questions.form.provideinfo";
      public static final String QUESTIONS_INS_LABEL = "questions.ins.label";
      public static final String QUESTIONS_RQD_LABEL = "questions.rqd.label";
      public static final String QUESTIONS_LABEL = "questions.label";
      public static final String QUESTIONS_JSMSG_REQUIRED = "questions.javascript.requiredquestions";
      public static final String QUESTIONS_JSMSG_REQ_NAME_BLANK = "questions.javascript.validrequestname";
      public static final String QUESTIONS_JSMSG_VALIDDATE = "questions.javascript.invaliddate";
      public static final String QUESTIONS_JSMSG_VALIDTIME = "questions.javascript.invalidtime";
      public static final String QUESTIONS_JSMSG_VALIDQTY = "questions.javascript.invalidqty";
      public static final String QUESTIONS_JSMSG_REQDATE = "questions.javascript.requireddate";
      public static final String QUESTIONS_JSMSG_TEXTLIMIT = "questions.javascript.textlimit";
      public static final String QUESTIONS_JSMSG_VALIDMENU = "questions.javascript.invlidmenuentry";
      public static final String QUESTIONS_JSMSG_REQDATECURRTIME = "questions.javascript.requireddatecurrtime";
      public static final String QUESTIONS_JSCAL_MONSHORT = "questions.jscalendar.monthsshort";
      public static final String QUESTIONS_JSCAL_MONLONG = "questions.jscalendar.monthslong";
      public static final String QUESTIONS_JSCAL_DAYS1CHAR = "questions.jscalendar.weekdays1char";
      public static final String QUESTIONS_JSCAL_DAYSSHORT = "questions.jscalendar.weekdaysshort";
      public static final String QUESTIONS_JSCAL_DAYSMED = "questions.jscalendar.weekdaysmedium";
      public static final String QUESTIONS_JSCAL_DAYSLONG = "questions.jscalendar.weekdayslong";
      public static final String QUESTIONS_JSCAL_DATEFORMAT = "questions.jscalendar.dateformat";
      public static final String QUESTIONS_JSCAL_FIRSTDAY = "questions.jscalendar.firstdayofweek";
      public static final String QUESTIONS_JSCAL_AM = "questions.jscalendar.am";
      public static final String QUESTIONS_JSCAL_PM = "questions.jscalendar.pm";
      public static final String QUESTIONS_JSCAL_OK = "questions.jscalendar.ok";
      public static final String QUESTIONS_JSCAL_SELECTMESSAGE = "questions.jscalendar.selectmessage";
      public static final String QUESTIONS_JSMENU_CLEAR = "questions.menu.clear";
      public static final String QUESTIONS_JSMENU_SELECTMESSAGE = "questions.menu.selectmessage";
      public static final String QUESTIONS_JSCAL_HOUR = "questions.calendar.hour";
      public static final String QUESTIONS_JSCAL_MINUTE = "questions.calendar.minute";
      public static final String QUESTIONS_JSCAL_TIME = "questions.calendar.time";
      public static final String QUESTIONS_JSCAL_NOW = "questions.calendar.now";
      public static final String QUESTIONS_JSCAL_DONE = "questions.calendar.done";
      public static final String QUESTIONS_JSCAL_CHOOSETIME = "questions.calendar.choosetime";
      public static final String CATEGORIES_ALL_TEXT = "categories.all.text";
      public static final String CATEGORIES_AVAILABLE_REQUEST = "categories.available.requests";
      public static final String CATEGORIES_SUB_CATAGORIES = "subcategory.lable.msg";
      public static final String SERVICE_DESCRIPTION_LABEL = "select.service.description.label";
      public static final String[] KEYS = { "hotlist.icon.alt", "system.icon.alt", "favorite.icon.alt", "add.to.favorites.icon.alt", "remove.from.favorites.alt", "select.service.button.label", "show.service.details.button.label", "list.all.services.link", "browse.categories.link", "no.data.found", "browse.categories.more.link", "unhandled.exception", "qualification.parsing.exception", "service.subcategory.title", "service.searchresults.title", "service.price.label", "service.srdprice.label", "service.soprice.label", "add.to.cart.button.label", "questions.requester.edit", "questions.requester.email", "questions.requester.label", "questions.requester.name", "questions.requester.phone", "questions.request.expdate", "questions.request.name", "questions.request.price", "questions.request.qty", "questions.request.reqdate", "questions.form.addattach", "questions.form.addcart", "questions.form.savedraft", "questions.form.submit", "questions.form.summary", "questions.form.cancel", "questions.form.provideinfo", "questions.form.updatecart", "questions.ins.label", "questions.javascript.invaliddate", "questions.javascript.invalidtime", "questions.rqd.label", "questions.label", "questions.javascript.validrequestname", "questions.javascript.requireddate", "questions.javascript.requiredquestions", "questions.javascript.requireddatecurrtime", "questions.javascript.textlimit", "questions.javascript.invaliddate", "questions.javascript.invalidqty", "questions.javascript.invalidtime", "questions.javascript.invlidmenuentry", "questions.jscalendar.am", "questions.jscalendar.dateformat", "questions.jscalendar.weekdays1char", "questions.jscalendar.weekdayslong", "questions.jscalendar.weekdaysmedium", "questions.jscalendar.weekdaysshort", "questions.jscalendar.firstdayofweek", "questions.jscalendar.monthslong", "questions.jscalendar.monthsshort", "questions.jscalendar.ok", "questions.jscalendar.pm", "questions.jscalendar.selectmessage", "questions.menu.clear", "questions.menu.selectmessage", "questions.calendar.hour", "questions.calendar.minute", "questions.calendar.time", "questions.calendar.now", "questions.calendar.done", "questions.calendar.choosetime", "categories.all.text", "categories.available.requests", "subcategory.lable.msg", "select.service.description.label" };
    }

     

     

    So for "Description" one record should be created in "AR System Message Catalog" with code:

    SRSServiceRequestConsole:Messages:select.service.description.label

     

     

     

    IV°) 7.6.04 / 8.x differences:

    There are some differences between 7.6.04 and 8.x SRM versions, so be careful to take the right records and right prefixes.

     

     

    1°) jar file:

    The file "SRMSServiceRequestBrowser.jar" is in the record "SRMSServiceRequestBrowser" in 7.6.04:

    06.png

     

    and in record "SRSServiceRequestConsole" in 8.x (beware, both records exist in 8.0).

    07.png

     

    2°) template files:

    In 7.6.04, the templates are ".st" files:

    $if(showEmail)$

    <tdclass="srDetailsCellStub1"><labelfor="requester-email"class="labeltext">$emailLabel$</label></td>

    <tdclass="srDetailsCellContent"><input type="text"id="requester-email" name="requester-email"></td>

     

    In 8.x, they are ".vm" files:

    <div id="srd_description">

        <div class="bold">$!{serviceDescripption}:</div>

        <div id="srd_description_text">$serviceData[0].description</div>

    </div>

     

    3°) Entries in "AR System Message Catalog":

    Some localizations are stored in the form "AR System Message Catalog" with those kind of code, the prefix isn't the same.

     

    In 7.6.04:

    SRMSServiceRequestBrowser:Messages:questions.requester.email

     

    In 8.x:

     

    SRSServiceRequestConsole:Messages:select.service.description.label

     

     

    V°) Another example: "How to show instructions zone by default in a service request? (SRM 8.1)":

    In this thread, Make Instructions auto-open on SRDs in Remedy 8.1, Tamara Scanlon wants the "instructions" part of a service request displayed by default when you open a service request.

     

    It's possible but you have to do some kind of light of javascript coding, still in the "jar" file, here is the video that shows how to do it:

     

     

     

    VI°) Interesting case, How to skin "All Categories" in the SRM Console?:

    Ekaterina Afanasyeva asked in the comment how to skin the "All Categories" link in the SRM Console:

    01.png

    03.png

     

    And it's actually a very interesting case because for once, the css file isn't in the jar file, nor in "AR System Resource Definition", but in "Data Visualization Definition", as a special case.

    02.png

     

    To do it short, the css used is "categories.css" is actually in the jar file and in "AR System Resource Definition".

    Though nor of those versions are used. Why? Because BMC put some of those css files in "Data Visualization Definition" so we can alter those css without altering the jar file and so without rebooting Tomcat, interesting indeed (when you know it).

     

    I thought it was interesting enough to do a video about it on the whole process that you can find here:

     

    In this test, I just changed its color to red, adding a new css class for that (all is described in the video):

    05.png

    04.png

     

    At the end of the video I was wondering what woud happen if the records with "categories.css" didn't exist / was inactive in "Data Visualization Definition". Well in this case, it falls back and take the one from the jar file

     

     

    VII°) Change the marketing slide delay:

    It's pretty easy

    Re: marketing slides

     

    A function is generated in a javascript code with the delay, hardcoded.

    The code is in file"/resources/templates/velocity/marketing/marketing_slides.vm" from the jar file "SRMSServiceRequestBrowser.jar".

    01.png

     

    To change the delay between two slides, just change the "play" value:

    02.png

     

    Of course, you will have to:

    • Extract the jar file,
    • Modify the "marketing_slides.vm" file,
    • Build the jar file,
    • Upload the new jar file,
    • Stop tomcat,
    • Empty the different caches folders content ("/cache/", "/pluginscache/", "/pluginsdefcache/"),
    • Empty your web browser cache,
    • Try

     

    Those steps are already defined more in details in the previous examples

     

     

    VIII°) Show off :

    All is explained in this thread (well at least what was done):

    [NYF] SRM Skinning example ^_^

     

    Full skinning of the Service Request Console,

    • Colors,
    • Pictures / Logos, Sub windows,
    • Gradients,
    • Multi-tenancy "aware",

    Special things:

    And in guest star, in a standard request:

    • Having a "bubble popup" for help on fields,
    • Adding dynamically buttons that call javascript code,
    • Adding dynamically buttons that call Remedy workflow ,
    • Comparing two dates using Remedy workflow

     

    [SRM 8.1] Skinning on steroids - YouTube