You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@roller.apache.org by Matt Raible <ma...@raibledesigns.com> on 2009/11/18 16:38:32 UTC

Adding line breaks to inbound comments

I spend a lot of time formatting comments for readers of my blog. Is there a
way to automate this process so \n is replaced with <br/> when the comment
is submitted? I'd like to keep the HTML subset enabled, but line breaks
should be automatic. I realize I could change my comment renderer, but I
don't want to change past comments, just new ones.

Thanks,

Matt

Re: Adding line breaks to inbound comments

Posted by Matt Raible <ma...@raibledesigns.com>.
Yep. I get comment notifications and go in and add <br/> tags (or wrap with
<p>) tags.

On Wed, Nov 18, 2009 at 11:29 AM, Dave <sn...@gmail.com> wrote:

> I'm not aware of an existing way to do that.
>
> I'm curious, how do you do that formatting? Do you go into the
> database to do it?
>
> - Dave
>
>
> On Wed, Nov 18, 2009 at 10:38 AM, Matt Raible <ma...@raibledesigns.com>
> wrote:
> > I spend a lot of time formatting comments for readers of my blog. Is
> there a
> > way to automate this process so \n is replaced with <br/> when the
> comment
> > is submitted? I'd like to keep the HTML subset enabled, but line breaks
> > should be automatic. I realize I could change my comment renderer, but I
> > don't want to change past comments, just new ones.
> >
> > Thanks,
> >
> > Matt
> >
>

Re: Adding line breaks to inbound comments

Posted by Dave <sn...@gmail.com>.
I'm not aware of an existing way to do that.

I'm curious, how do you do that formatting? Do you go into the
database to do it?

- Dave


On Wed, Nov 18, 2009 at 10:38 AM, Matt Raible <ma...@raibledesigns.com> wrote:
> I spend a lot of time formatting comments for readers of my blog. Is there a
> way to automate this process so \n is replaced with <br/> when the comment
> is submitted? I'd like to keep the HTML subset enabled, but line breaks
> should be automatic. I realize I could change my comment renderer, but I
> don't want to change past comments, just new ones.
>
> Thanks,
>
> Matt
>

Re: theme reloading

Posted by Gr...@ricoh.co.uk.
Matt,

OK, will try and create one.


also forgot to add on the first email:

Yyou also need to delete the style sheet from the db (webpage file) for 
the weblog you are developing with, otherwise roller will use the db 
version rather than the theme version.  N.B. every time the stylesheet tab 
is selected in Design, it will copy a new version to the db!.



Cheers Greg





Matt Raible <ma...@raibledesigns.com> 
19/11/2009 12:18
Please respond to
dev@roller.apache.org


To
dev@roller.apache.org
cc

Subject
Re: theme reloading






Any chance you could provide this as a patch? I believe this would be
a nice feature to have in Roller's core.

Thanks,

Matt

On Thu, Nov 19, 2009 at 6:43 AM,  <Gr...@ricoh.co.uk> wrote:
> Hello,
>
> Remembered a while back someone asked if it was possible to reload a 
theme
> rather than restarting the container for development purposes.
>
> Rather than upgrading my laptop I decided to see if it was possible.
> Roller needs a few mods, but seems to work, also does not seem to be 
much
> of an overhead either.
>
>
> Add a method to theme manager
>
>        /**
>         * This is a development only method which reloads theme data 
from
> themes
>         * stored on the filesystem in the webapp /themes/ directory.
>         *
>         * @param reloadTheme
>         *            the reload theme
>         *
>         * @return true, if theme was reloaded from disk
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme);
>
>
> also impl:
>
>        /**
>         * @see ThemeManager#reLoadThemeFromDisk(String)
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme) {
>
>                boolean reloaded = false;
>
>                try {
>
>                        Theme theme = new 
SharedThemeFromDir(this.themeDir
> + File.separator
>                                        + reloadTheme);
>
>                        if (theme != null) {
>
>                                Theme loadedTheme = (Theme)
> themes.get(theme.getId());
>
>                                if (loadedTheme != null
>                                                && 
theme.getLastModified()
>  .after(loadedTheme.getLastModified())) {
>                                        themes.remove(theme.getId());
>                                        themes.put(theme.getId(), theme);
>                                        reloaded = true;
>                                }
>
>                        }
>
>                } catch (Throwable unexpected) {
>                        log.error("Problem reloading theme " +
> reloadTheme, unexpected);
>                }
>
>                return reloaded;
>
>        }
>
> Modify SharedThemeFromDir to update the last modified in SharedTheme: 
 see
> **** Set Last Modified *****
>
>        /**
>         * Load all the elements of this theme from disk and cache them.
>         */
>        private void loadThemeFromDisk() throws
> ThemeInitializationException {
>
>                log.debug("Parsing theme descriptor for " +
> this.themeDir);
>
>                ThemeMetadata themeMetadata = null;
>                try {
>                        // lookup theme descriptor and parse it
>                        ThemeMetadataParser parser = new
> ThemeMetadataParser();
>                        InputStream is = new 
FileInputStream(this.themeDir
> + File.separator
>                                        + "theme.xml");
>                        themeMetadata = parser.unmarshall(is);
>                } catch (Exception ex) {
>                        throw new ThemeInitializationException(
>                                        "Unable to parse theme descriptor
> for theme "
>                                                        + this.themeDir,
> ex);
>                }
>
>                log.debug("Loading Theme " + themeMetadata.getName());
>
>                // use parsed theme descriptor to load Theme data
>                setId(themeMetadata.getId());
>                setName(themeMetadata.getName());
>                setDescription(themeMetadata.getName());
>                setAuthor(themeMetadata.getAuthor());
>                                 **** Set Last Modified *****
>                // setLastModified(new Date());
>                setEnabled(true);
>
>                // load resource representing preview image
>                File previewFile = new File(this.themeDir + 
File.separator
>                                + themeMetadata.getPreviewImage());
>                if (!previewFile.exists() || !previewFile.canRead()) {
>                        log.warn("Couldn't read theme [" + this.getName()
>                                        + "] preview image file ["
>                                        + themeMetadata.getPreviewImage()
> + "]");
>                } else {
>                        this.previewImage = new
> SharedThemeResourceFromDir(themeMetadata
>                                        .getPreviewImage(), previewFile);
>                }
>
>                // load stylesheet if possible
>                if (themeMetadata.getStylesheet() != null) {
>
>                        ThemeMetadataTemplate stylesheetTmpl =
> themeMetadata
>                                        .getStylesheet();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> stylesheetTmpl.getContentsFile());
>
>                        // read stylesheet contents
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then 
skip
> this one
>                                log.error("Couldn't load stylesheet theme
> [" + this.getName()
>                                                + "] template file [" +
> templateFile + "]");
>                        } else {
>
>                                // construct ThemeTemplate representing
> this file
>                                SharedThemeTemplate theme_template = new
> SharedThemeTemplate(
>                                                this,
> themeMetadata.getId() + ":"
>                                                                +
> stylesheetTmpl.getName(),
>  WebsiteTemplate.ACTION_CUSTOM,
>                                                stylesheetTmpl.getName(),
> stylesheetTmpl
>  .getDescription(), contents, stylesheetTmpl
>  .getLink(), new Date(templateFile
>  .lastModified()), stylesheetTmpl
>  .getTemplateLanguage(), false, false);
>
>                                // store it
>                                this.stylesheet = theme_template;
>
>                                // add it to templates list
>                                addTemplate(theme_template);
>                        }
>
>                        // **** Set Last Modified *****
>                        setLastModified(new
> Date(templateFile.lastModified()));
>                }
>
>                // go through static resources and add them to the theme
>                String resourcePath = null;
>                Iterator resourcesIter =
> themeMetadata.getResources().iterator();
>                while (resourcesIter.hasNext()) {
>                        resourcePath = (String) resourcesIter.next();
>
>                        // construct ThemeResource object from resource
>                        File resourceFile = new File(this.themeDir +
> File.separator
>                                        + resourcePath);
>
>                        // Continue reading theme even if problem
> encountered with one file
>                        if (!resourceFile.exists() ||
> !resourceFile.canRead()) {
>                                log.warn("Couldn't read  theme [" +
> this.getName()
>                                                + "] resource file [" +
> resourcePath + "]");
>                                continue;
>                        }
>
>                        // add it to the theme
>                        setResource(resourcePath, new
> SharedThemeResourceFromDir(
>                                        resourcePath, resourceFile));
>
>                        // **** Set Last Modified *****
>                        Date lstModified = new
> Date(resourceFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>
>                // go through templates and read in contents to a
> ThemeTemplate
>                ThemeTemplate theme_template = null;
>                ThemeMetadataTemplate templateMetadata = null;
>                Iterator templatesIter =
> themeMetadata.getTemplates().iterator();
>                while (templatesIter.hasNext()) {
>                        templateMetadata = (ThemeMetadataTemplate)
> templatesIter.next();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> templateMetadata.getContentsFile());
>
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then 
skip
> this one
>                                throw new
> ThemeInitializationException("Couldn't load theme ["
>                                                + this.getName() + "]
> template file [" + templateFile
>                                                + "]");
>                        }
>
>                        // construct ThemeTemplate representing this file
>                        theme_template = new SharedThemeTemplate(this,
> themeMetadata
>                                        .getId()
>                                        + ":" +
> templateMetadata.getName(), templateMetadata
>                                        .getAction(),
> templateMetadata.getName(), templateMetadata
>                                        .getDescription(), contents,
> templateMetadata.getLink(),
>                                        new
> Date(templateFile.lastModified()), templateMetadata
>  .getTemplateLanguage(),
>                                        templateMetadata.isHidden(),
> templateMetadata.isNavbar());
>
>                        // add it to the theme
>                        addTemplate(theme_template);
>
>                        //  **** Set Last Modified *****
>                        Date lstModified = new
> Date(templateFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>        }
>
>
> Then in PageServlet reload the theme and then clear the caches
>
> // generate cache key
>        String cacheKey = null;
>        if (isSiteWide) {
>            cacheKey = siteWideCache.generateKey(pageRequest);
>        } else {
>            cacheKey = weblogPageCache.generateKey(pageRequest);
>        }
>
> // **** Development only. Reload if theme has been modified  ***
>                if
> (WebloggerConfig.getBooleanProperty("site.themeReloadMode")) {
>                        try {
>
>                                ThemeManager manager = null;
>                                manager =
> WebloggerFactory.getWeblogger().getThemeManager();
>
>                                boolean reloaded =
> manager.reLoadThemeFromDisk(website.getEditorTheme());
>
>                                if (reloaded) {
>
>                                        if (isSiteWide) {
>                                                siteWideCache.clear();
>                                        } else {
>                                                websitePageCache.clear();
>                                        }
>                                }
>
>                        } catch (Exception e1) {
>                                // ignored
>                        }
>
>                }
>
>  // cached content checking
>        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) &&
> request.getAttribute("skipCache") == null) {
>
>
> Cheers Greg
>
>
>
>
> Share our environment commitment - conserve resources and contribute to 
the reduction of CO2 emissions by not printing the email unless absolutely 
necessary to do so.
>
> Any opinions expressed are those of the author, not Ricoh UK Ltd. This 
communication does not constitute either offer or acceptance of any 
contractually binding agreement. Such offer or acceptance must be 
communicated in writing. It is the responsibility of the recipient to 
ensure this email and attachments are free from computer viruses before 
use and the sender accepts no responsibility or liability for any such 
computer viruses.
>
> Ricoh UK Ltd. may monitor the content of emails sent and received via 
its network for the purpose of ensuring compliance with its policies and 
procedures. This communication contains information, which may be 
confidential or privileged. The information is intended solely for the use 
of the individual or entity named above. If you are not the intended 
recipient, be aware that any disclosure, copying, distribution or use of 
the contents of this information is prohibited. If you have received this 
communication in error, please notify the sender immediately by return 
email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 
(0) 208 261 4000 if you need assistance.
>
> Registered in England No: 473236
> VAT No: GB524161280




Share our environment commitment - conserve resources and contribute to the reduction of CO2 emissions by not printing the email unless absolutely necessary to do so. 

Any opinions expressed are those of the author, not Ricoh UK Ltd. This communication does not constitute either offer or acceptance of any contractually binding agreement. Such offer or acceptance must be communicated in writing. It is the responsibility of the recipient to ensure this email and attachments are free from computer viruses before use and the sender accepts no responsibility or liability for any such computer viruses. 

Ricoh UK Ltd. may monitor the content of emails sent and received via its network for the purpose of ensuring compliance with its policies and procedures. This communication contains information, which may be confidential or privileged. The information is intended solely for the use of the individual or entity named above. If you are not the intended recipient, be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this communication in error, please notify the sender immediately by return email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 (0) 208 261 4000 if you need assistance. 

Registered in England No: 473236 
VAT No: GB524161280  

Re: theme reloading

Posted by Gr...@ricoh.co.uk.
Hello,

I have created ROL-1847 with a patch for the trunk.

I also do not have the trunk setup as a project so i have copied the mods 
and therefore unable to test it, but the source project  works OK.

Cheers Greg





Matt Raible <ma...@raibledesigns.com> 
19/11/2009 12:18
Please respond to
dev@roller.apache.org


To
dev@roller.apache.org
cc

Subject
Re: theme reloading






Any chance you could provide this as a patch? I believe this would be
a nice feature to have in Roller's core.

Thanks,

Matt

On Thu, Nov 19, 2009 at 6:43 AM,  <Gr...@ricoh.co.uk> wrote:
> Hello,
>
> Remembered a while back someone asked if it was possible to reload a 
theme
> rather than restarting the container for development purposes.
>
> Rather than upgrading my laptop I decided to see if it was possible.
> Roller needs a few mods, but seems to work, also does not seem to be 
much
> of an overhead either.
>
>
> Add a method to theme manager
>
>        /**
>         * This is a development only method which reloads theme data 
from
> themes
>         * stored on the filesystem in the webapp /themes/ directory.
>         *
>         * @param reloadTheme
>         *            the reload theme
>         *
>         * @return true, if theme was reloaded from disk
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme);
>
>
> also impl:
>
>        /**
>         * @see ThemeManager#reLoadThemeFromDisk(String)
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme) {
>
>                boolean reloaded = false;
>
>                try {
>
>                        Theme theme = new 
SharedThemeFromDir(this.themeDir
> + File.separator
>                                        + reloadTheme);
>
>                        if (theme != null) {
>
>                                Theme loadedTheme = (Theme)
> themes.get(theme.getId());
>
>                                if (loadedTheme != null
>                                                && 
theme.getLastModified()
>  .after(loadedTheme.getLastModified())) {
>                                        themes.remove(theme.getId());
>                                        themes.put(theme.getId(), theme);
>                                        reloaded = true;
>                                }
>
>                        }
>
>                } catch (Throwable unexpected) {
>                        log.error("Problem reloading theme " +
> reloadTheme, unexpected);
>                }
>
>                return reloaded;
>
>        }
>
> Modify SharedThemeFromDir to update the last modified in SharedTheme: 
 see
> **** Set Last Modified *****
>
>        /**
>         * Load all the elements of this theme from disk and cache them.
>         */
>        private void loadThemeFromDisk() throws
> ThemeInitializationException {
>
>                log.debug("Parsing theme descriptor for " +
> this.themeDir);
>
>                ThemeMetadata themeMetadata = null;
>                try {
>                        // lookup theme descriptor and parse it
>                        ThemeMetadataParser parser = new
> ThemeMetadataParser();
>                        InputStream is = new 
FileInputStream(this.themeDir
> + File.separator
>                                        + "theme.xml");
>                        themeMetadata = parser.unmarshall(is);
>                } catch (Exception ex) {
>                        throw new ThemeInitializationException(
>                                        "Unable to parse theme descriptor
> for theme "
>                                                        + this.themeDir,
> ex);
>                }
>
>                log.debug("Loading Theme " + themeMetadata.getName());
>
>                // use parsed theme descriptor to load Theme data
>                setId(themeMetadata.getId());
>                setName(themeMetadata.getName());
>                setDescription(themeMetadata.getName());
>                setAuthor(themeMetadata.getAuthor());
>                                 **** Set Last Modified *****
>                // setLastModified(new Date());
>                setEnabled(true);
>
>                // load resource representing preview image
>                File previewFile = new File(this.themeDir + 
File.separator
>                                + themeMetadata.getPreviewImage());
>                if (!previewFile.exists() || !previewFile.canRead()) {
>                        log.warn("Couldn't read theme [" + this.getName()
>                                        + "] preview image file ["
>                                        + themeMetadata.getPreviewImage()
> + "]");
>                } else {
>                        this.previewImage = new
> SharedThemeResourceFromDir(themeMetadata
>                                        .getPreviewImage(), previewFile);
>                }
>
>                // load stylesheet if possible
>                if (themeMetadata.getStylesheet() != null) {
>
>                        ThemeMetadataTemplate stylesheetTmpl =
> themeMetadata
>                                        .getStylesheet();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> stylesheetTmpl.getContentsFile());
>
>                        // read stylesheet contents
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then 
skip
> this one
>                                log.error("Couldn't load stylesheet theme
> [" + this.getName()
>                                                + "] template file [" +
> templateFile + "]");
>                        } else {
>
>                                // construct ThemeTemplate representing
> this file
>                                SharedThemeTemplate theme_template = new
> SharedThemeTemplate(
>                                                this,
> themeMetadata.getId() + ":"
>                                                                +
> stylesheetTmpl.getName(),
>  WebsiteTemplate.ACTION_CUSTOM,
>                                                stylesheetTmpl.getName(),
> stylesheetTmpl
>  .getDescription(), contents, stylesheetTmpl
>  .getLink(), new Date(templateFile
>  .lastModified()), stylesheetTmpl
>  .getTemplateLanguage(), false, false);
>
>                                // store it
>                                this.stylesheet = theme_template;
>
>                                // add it to templates list
>                                addTemplate(theme_template);
>                        }
>
>                        // **** Set Last Modified *****
>                        setLastModified(new
> Date(templateFile.lastModified()));
>                }
>
>                // go through static resources and add them to the theme
>                String resourcePath = null;
>                Iterator resourcesIter =
> themeMetadata.getResources().iterator();
>                while (resourcesIter.hasNext()) {
>                        resourcePath = (String) resourcesIter.next();
>
>                        // construct ThemeResource object from resource
>                        File resourceFile = new File(this.themeDir +
> File.separator
>                                        + resourcePath);
>
>                        // Continue reading theme even if problem
> encountered with one file
>                        if (!resourceFile.exists() ||
> !resourceFile.canRead()) {
>                                log.warn("Couldn't read  theme [" +
> this.getName()
>                                                + "] resource file [" +
> resourcePath + "]");
>                                continue;
>                        }
>
>                        // add it to the theme
>                        setResource(resourcePath, new
> SharedThemeResourceFromDir(
>                                        resourcePath, resourceFile));
>
>                        // **** Set Last Modified *****
>                        Date lstModified = new
> Date(resourceFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>
>                // go through templates and read in contents to a
> ThemeTemplate
>                ThemeTemplate theme_template = null;
>                ThemeMetadataTemplate templateMetadata = null;
>                Iterator templatesIter =
> themeMetadata.getTemplates().iterator();
>                while (templatesIter.hasNext()) {
>                        templateMetadata = (ThemeMetadataTemplate)
> templatesIter.next();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> templateMetadata.getContentsFile());
>
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then 
skip
> this one
>                                throw new
> ThemeInitializationException("Couldn't load theme ["
>                                                + this.getName() + "]
> template file [" + templateFile
>                                                + "]");
>                        }
>
>                        // construct ThemeTemplate representing this file
>                        theme_template = new SharedThemeTemplate(this,
> themeMetadata
>                                        .getId()
>                                        + ":" +
> templateMetadata.getName(), templateMetadata
>                                        .getAction(),
> templateMetadata.getName(), templateMetadata
>                                        .getDescription(), contents,
> templateMetadata.getLink(),
>                                        new
> Date(templateFile.lastModified()), templateMetadata
>  .getTemplateLanguage(),
>                                        templateMetadata.isHidden(),
> templateMetadata.isNavbar());
>
>                        // add it to the theme
>                        addTemplate(theme_template);
>
>                        //  **** Set Last Modified *****
>                        Date lstModified = new
> Date(templateFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>        }
>
>
> Then in PageServlet reload the theme and then clear the caches
>
> // generate cache key
>        String cacheKey = null;
>        if (isSiteWide) {
>            cacheKey = siteWideCache.generateKey(pageRequest);
>        } else {
>            cacheKey = weblogPageCache.generateKey(pageRequest);
>        }
>
> // **** Development only. Reload if theme has been modified  ***
>                if
> (WebloggerConfig.getBooleanProperty("site.themeReloadMode")) {
>                        try {
>
>                                ThemeManager manager = null;
>                                manager =
> WebloggerFactory.getWeblogger().getThemeManager();
>
>                                boolean reloaded =
> manager.reLoadThemeFromDisk(website.getEditorTheme());
>
>                                if (reloaded) {
>
>                                        if (isSiteWide) {
>                                                siteWideCache.clear();
>                                        } else {
>                                                websitePageCache.clear();
>                                        }
>                                }
>
>                        } catch (Exception e1) {
>                                // ignored
>                        }
>
>                }
>
>  // cached content checking
>        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) &&
> request.getAttribute("skipCache") == null) {
>
>
> Cheers Greg
>
>
>
>
> Share our environment commitment - conserve resources and contribute to 
the reduction of CO2 emissions by not printing the email unless absolutely 
necessary to do so.
>
> Any opinions expressed are those of the author, not Ricoh UK Ltd. This 
communication does not constitute either offer or acceptance of any 
contractually binding agreement. Such offer or acceptance must be 
communicated in writing. It is the responsibility of the recipient to 
ensure this email and attachments are free from computer viruses before 
use and the sender accepts no responsibility or liability for any such 
computer viruses.
>
> Ricoh UK Ltd. may monitor the content of emails sent and received via 
its network for the purpose of ensuring compliance with its policies and 
procedures. This communication contains information, which may be 
confidential or privileged. The information is intended solely for the use 
of the individual or entity named above. If you are not the intended 
recipient, be aware that any disclosure, copying, distribution or use of 
the contents of this information is prohibited. If you have received this 
communication in error, please notify the sender immediately by return 
email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 
(0) 208 261 4000 if you need assistance.
>
> Registered in England No: 473236
> VAT No: GB524161280




Share our environment commitment - conserve resources and contribute to the reduction of CO2 emissions by not printing the email unless absolutely necessary to do so. 

Any opinions expressed are those of the author, not Ricoh UK Ltd. This communication does not constitute either offer or acceptance of any contractually binding agreement. Such offer or acceptance must be communicated in writing. It is the responsibility of the recipient to ensure this email and attachments are free from computer viruses before use and the sender accepts no responsibility or liability for any such computer viruses. 

Ricoh UK Ltd. may monitor the content of emails sent and received via its network for the purpose of ensuring compliance with its policies and procedures. This communication contains information, which may be confidential or privileged. The information is intended solely for the use of the individual or entity named above. If you are not the intended recipient, be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this communication in error, please notify the sender immediately by return email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 (0) 208 261 4000 if you need assistance. 

Registered in England No: 473236 
VAT No: GB524161280  

Re: theme reloading

Posted by Matt Raible <ma...@raibledesigns.com>.
Any chance you could provide this as a patch? I believe this would be
a nice feature to have in Roller's core.

Thanks,

Matt

On Thu, Nov 19, 2009 at 6:43 AM,  <Gr...@ricoh.co.uk> wrote:
> Hello,
>
> Remembered a while back someone asked if it was possible to reload a theme
> rather than restarting the container for development purposes.
>
> Rather than upgrading my laptop I decided to see if it was possible.
> Roller needs a few mods, but seems to work, also does not seem to be much
> of an overhead either.
>
>
> Add a method to theme manager
>
>        /**
>         * This is a development only method which reloads theme data from
> themes
>         * stored on the filesystem in the webapp /themes/ directory.
>         *
>         * @param reloadTheme
>         *            the reload theme
>         *
>         * @return true, if theme was reloaded from disk
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme);
>
>
> also impl:
>
>        /**
>         * @see ThemeManager#reLoadThemeFromDisk(String)
>         */
>        public boolean reLoadThemeFromDisk(String reloadTheme) {
>
>                boolean reloaded = false;
>
>                try {
>
>                        Theme theme = new SharedThemeFromDir(this.themeDir
> + File.separator
>                                        + reloadTheme);
>
>                        if (theme != null) {
>
>                                Theme loadedTheme = (Theme)
> themes.get(theme.getId());
>
>                                if (loadedTheme != null
>                                                && theme.getLastModified()
>  .after(loadedTheme.getLastModified())) {
>                                        themes.remove(theme.getId());
>                                        themes.put(theme.getId(), theme);
>                                        reloaded = true;
>                                }
>
>                        }
>
>                } catch (Throwable unexpected) {
>                        log.error("Problem reloading theme " +
> reloadTheme, unexpected);
>                }
>
>                return reloaded;
>
>        }
>
> Modify SharedThemeFromDir to update the last modified in SharedTheme:  see
> **** Set Last Modified *****
>
>        /**
>         * Load all the elements of this theme from disk and cache them.
>         */
>        private void loadThemeFromDisk() throws
> ThemeInitializationException {
>
>                log.debug("Parsing theme descriptor for " +
> this.themeDir);
>
>                ThemeMetadata themeMetadata = null;
>                try {
>                        // lookup theme descriptor and parse it
>                        ThemeMetadataParser parser = new
> ThemeMetadataParser();
>                        InputStream is = new FileInputStream(this.themeDir
> + File.separator
>                                        + "theme.xml");
>                        themeMetadata = parser.unmarshall(is);
>                } catch (Exception ex) {
>                        throw new ThemeInitializationException(
>                                        "Unable to parse theme descriptor
> for theme "
>                                                        + this.themeDir,
> ex);
>                }
>
>                log.debug("Loading Theme " + themeMetadata.getName());
>
>                // use parsed theme descriptor to load Theme data
>                setId(themeMetadata.getId());
>                setName(themeMetadata.getName());
>                setDescription(themeMetadata.getName());
>                setAuthor(themeMetadata.getAuthor());
>                                 **** Set Last Modified *****
>                // setLastModified(new Date());
>                setEnabled(true);
>
>                // load resource representing preview image
>                File previewFile = new File(this.themeDir + File.separator
>                                + themeMetadata.getPreviewImage());
>                if (!previewFile.exists() || !previewFile.canRead()) {
>                        log.warn("Couldn't read theme [" + this.getName()
>                                        + "] preview image file ["
>                                        + themeMetadata.getPreviewImage()
> + "]");
>                } else {
>                        this.previewImage = new
> SharedThemeResourceFromDir(themeMetadata
>                                        .getPreviewImage(), previewFile);
>                }
>
>                // load stylesheet if possible
>                if (themeMetadata.getStylesheet() != null) {
>
>                        ThemeMetadataTemplate stylesheetTmpl =
> themeMetadata
>                                        .getStylesheet();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> stylesheetTmpl.getContentsFile());
>
>                        // read stylesheet contents
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then skip
> this one
>                                log.error("Couldn't load stylesheet theme
> [" + this.getName()
>                                                + "] template file [" +
> templateFile + "]");
>                        } else {
>
>                                // construct ThemeTemplate representing
> this file
>                                SharedThemeTemplate theme_template = new
> SharedThemeTemplate(
>                                                this,
> themeMetadata.getId() + ":"
>                                                                +
> stylesheetTmpl.getName(),
>  WebsiteTemplate.ACTION_CUSTOM,
>                                                stylesheetTmpl.getName(),
> stylesheetTmpl
>  .getDescription(), contents, stylesheetTmpl
>  .getLink(), new Date(templateFile
>  .lastModified()), stylesheetTmpl
>  .getTemplateLanguage(), false, false);
>
>                                // store it
>                                this.stylesheet = theme_template;
>
>                                // add it to templates list
>                                addTemplate(theme_template);
>                        }
>
>                        // **** Set Last Modified *****
>                        setLastModified(new
> Date(templateFile.lastModified()));
>                }
>
>                // go through static resources and add them to the theme
>                String resourcePath = null;
>                Iterator resourcesIter =
> themeMetadata.getResources().iterator();
>                while (resourcesIter.hasNext()) {
>                        resourcePath = (String) resourcesIter.next();
>
>                        // construct ThemeResource object from resource
>                        File resourceFile = new File(this.themeDir +
> File.separator
>                                        + resourcePath);
>
>                        // Continue reading theme even if problem
> encountered with one file
>                        if (!resourceFile.exists() ||
> !resourceFile.canRead()) {
>                                log.warn("Couldn't read  theme [" +
> this.getName()
>                                                + "] resource file [" +
> resourcePath + "]");
>                                continue;
>                        }
>
>                        // add it to the theme
>                        setResource(resourcePath, new
> SharedThemeResourceFromDir(
>                                        resourcePath, resourceFile));
>
>                        // **** Set Last Modified *****
>                        Date lstModified = new
> Date(resourceFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>
>                // go through templates and read in contents to a
> ThemeTemplate
>                ThemeTemplate theme_template = null;
>                ThemeMetadataTemplate templateMetadata = null;
>                Iterator templatesIter =
> themeMetadata.getTemplates().iterator();
>                while (templatesIter.hasNext()) {
>                        templateMetadata = (ThemeMetadataTemplate)
> templatesIter.next();
>
>                        // construct File object from path
>                        File templateFile = new File(this.themeDir +
> File.separator
>                                        +
> templateMetadata.getContentsFile());
>
>                        String contents = loadTemplateFile(templateFile);
>                        if (contents == null) {
>                                // if we don't have any contents then skip
> this one
>                                throw new
> ThemeInitializationException("Couldn't load theme ["
>                                                + this.getName() + "]
> template file [" + templateFile
>                                                + "]");
>                        }
>
>                        // construct ThemeTemplate representing this file
>                        theme_template = new SharedThemeTemplate(this,
> themeMetadata
>                                        .getId()
>                                        + ":" +
> templateMetadata.getName(), templateMetadata
>                                        .getAction(),
> templateMetadata.getName(), templateMetadata
>                                        .getDescription(), contents,
> templateMetadata.getLink(),
>                                        new
> Date(templateFile.lastModified()), templateMetadata
>  .getTemplateLanguage(),
>                                        templateMetadata.isHidden(),
> templateMetadata.isNavbar());
>
>                        // add it to the theme
>                        addTemplate(theme_template);
>
>                        //  **** Set Last Modified *****
>                        Date lstModified = new
> Date(templateFile.lastModified());
>                        if (getLastModified() == null
>                                        ||
> lstModified.after(getLastModified())) {
>                                setLastModified(lstModified);
>                        }
>                }
>        }
>
>
> Then in PageServlet reload the theme and then clear the caches
>
> // generate cache key
>        String cacheKey = null;
>        if (isSiteWide) {
>            cacheKey = siteWideCache.generateKey(pageRequest);
>        } else {
>            cacheKey = weblogPageCache.generateKey(pageRequest);
>        }
>
> // **** Development only. Reload if theme has been modified  ***
>                if
> (WebloggerConfig.getBooleanProperty("site.themeReloadMode")) {
>                        try {
>
>                                ThemeManager manager = null;
>                                manager =
> WebloggerFactory.getWeblogger().getThemeManager();
>
>                                boolean reloaded =
> manager.reLoadThemeFromDisk(website.getEditorTheme());
>
>                                if (reloaded) {
>
>                                        if (isSiteWide) {
>                                                siteWideCache.clear();
>                                        } else {
>                                                websitePageCache.clear();
>                                        }
>                                }
>
>                        } catch (Exception e1) {
>                                // ignored
>                        }
>
>                }
>
>  // cached content checking
>        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) &&
> request.getAttribute("skipCache") == null) {
>
>
> Cheers Greg
>
>
>
>
> Share our environment commitment - conserve resources and contribute to the reduction of CO2 emissions by not printing the email unless absolutely necessary to do so.
>
> Any opinions expressed are those of the author, not Ricoh UK Ltd. This communication does not constitute either offer or acceptance of any contractually binding agreement. Such offer or acceptance must be communicated in writing. It is the responsibility of the recipient to ensure this email and attachments are free from computer viruses before use and the sender accepts no responsibility or liability for any such computer viruses.
>
> Ricoh UK Ltd. may monitor the content of emails sent and received via its network for the purpose of ensuring compliance with its policies and procedures. This communication contains information, which may be confidential or privileged. The information is intended solely for the use of the individual or entity named above. If you are not the intended recipient, be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this communication in error, please notify the sender immediately by return email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 (0) 208 261 4000 if you need assistance.
>
> Registered in England No: 473236
> VAT No: GB524161280

theme reloading

Posted by Gr...@ricoh.co.uk.
Hello,

Remembered a while back someone asked if it was possible to reload a theme 
rather than restarting the container for development purposes. 

Rather than upgrading my laptop I decided to see if it was possible. 
Roller needs a few mods, but seems to work, also does not seem to be much 
of an overhead either.


Add a method to theme manager

        /**
         * This is a development only method which reloads theme data from 
themes
         * stored on the filesystem in the webapp /themes/ directory.
         * 
         * @param reloadTheme
         *            the reload theme
         * 
         * @return true, if theme was reloaded from disk
         */
        public boolean reLoadThemeFromDisk(String reloadTheme);


also impl:

        /**
         * @see ThemeManager#reLoadThemeFromDisk(String)
         */
        public boolean reLoadThemeFromDisk(String reloadTheme) {

                boolean reloaded = false;

                try {

                        Theme theme = new SharedThemeFromDir(this.themeDir 
+ File.separator
                                        + reloadTheme);

                        if (theme != null) {

                                Theme loadedTheme = (Theme) 
themes.get(theme.getId());

                                if (loadedTheme != null
                                                && theme.getLastModified()
 .after(loadedTheme.getLastModified())) {
                                        themes.remove(theme.getId());
                                        themes.put(theme.getId(), theme);
                                        reloaded = true;
                                }

                        }

                } catch (Throwable unexpected) {
                        log.error("Problem reloading theme " + 
reloadTheme, unexpected);
                }

                return reloaded;

        }

Modify SharedThemeFromDir to update the last modified in SharedTheme:  see 
**** Set Last Modified *****

        /**
         * Load all the elements of this theme from disk and cache them.
         */
        private void loadThemeFromDisk() throws 
ThemeInitializationException {

                log.debug("Parsing theme descriptor for " + 
this.themeDir);

                ThemeMetadata themeMetadata = null;
                try {
                        // lookup theme descriptor and parse it
                        ThemeMetadataParser parser = new 
ThemeMetadataParser();
                        InputStream is = new FileInputStream(this.themeDir 
+ File.separator
                                        + "theme.xml");
                        themeMetadata = parser.unmarshall(is);
                } catch (Exception ex) {
                        throw new ThemeInitializationException(
                                        "Unable to parse theme descriptor 
for theme "
                                                        + this.themeDir, 
ex);
                }

                log.debug("Loading Theme " + themeMetadata.getName());

                // use parsed theme descriptor to load Theme data
                setId(themeMetadata.getId());
                setName(themeMetadata.getName());
                setDescription(themeMetadata.getName());
                setAuthor(themeMetadata.getAuthor());
                                 **** Set Last Modified *****
                // setLastModified(new Date());
                setEnabled(true);

                // load resource representing preview image
                File previewFile = new File(this.themeDir + File.separator
                                + themeMetadata.getPreviewImage());
                if (!previewFile.exists() || !previewFile.canRead()) {
                        log.warn("Couldn't read theme [" + this.getName()
                                        + "] preview image file ["
                                        + themeMetadata.getPreviewImage() 
+ "]");
                } else {
                        this.previewImage = new 
SharedThemeResourceFromDir(themeMetadata
                                        .getPreviewImage(), previewFile);
                }

                // load stylesheet if possible
                if (themeMetadata.getStylesheet() != null) {

                        ThemeMetadataTemplate stylesheetTmpl = 
themeMetadata
                                        .getStylesheet();

                        // construct File object from path
                        File templateFile = new File(this.themeDir + 
File.separator
                                        + 
stylesheetTmpl.getContentsFile());

                        // read stylesheet contents
                        String contents = loadTemplateFile(templateFile);
                        if (contents == null) {
                                // if we don't have any contents then skip 
this one
                                log.error("Couldn't load stylesheet theme 
[" + this.getName()
                                                + "] template file [" + 
templateFile + "]");
                        } else {

                                // construct ThemeTemplate representing 
this file
                                SharedThemeTemplate theme_template = new 
SharedThemeTemplate(
                                                this, 
themeMetadata.getId() + ":"
                                                                + 
stylesheetTmpl.getName(),
 WebsiteTemplate.ACTION_CUSTOM,
                                                stylesheetTmpl.getName(), 
stylesheetTmpl
 .getDescription(), contents, stylesheetTmpl
 .getLink(), new Date(templateFile
 .lastModified()), stylesheetTmpl
 .getTemplateLanguage(), false, false);

                                // store it
                                this.stylesheet = theme_template;

                                // add it to templates list
                                addTemplate(theme_template);
                        }

                        // **** Set Last Modified *****
                        setLastModified(new 
Date(templateFile.lastModified()));
                }

                // go through static resources and add them to the theme
                String resourcePath = null;
                Iterator resourcesIter = 
themeMetadata.getResources().iterator();
                while (resourcesIter.hasNext()) {
                        resourcePath = (String) resourcesIter.next();

                        // construct ThemeResource object from resource
                        File resourceFile = new File(this.themeDir + 
File.separator
                                        + resourcePath);

                        // Continue reading theme even if problem 
encountered with one file
                        if (!resourceFile.exists() || 
!resourceFile.canRead()) {
                                log.warn("Couldn't read  theme [" + 
this.getName()
                                                + "] resource file [" + 
resourcePath + "]");
                                continue;
                        }

                        // add it to the theme
                        setResource(resourcePath, new 
SharedThemeResourceFromDir(
                                        resourcePath, resourceFile));
 
                        // **** Set Last Modified *****
                        Date lstModified = new 
Date(resourceFile.lastModified());
                        if (getLastModified() == null
                                        || 
lstModified.after(getLastModified())) {
                                setLastModified(lstModified);
                        }
                }

                // go through templates and read in contents to a 
ThemeTemplate
                ThemeTemplate theme_template = null;
                ThemeMetadataTemplate templateMetadata = null;
                Iterator templatesIter = 
themeMetadata.getTemplates().iterator();
                while (templatesIter.hasNext()) {
                        templateMetadata = (ThemeMetadataTemplate) 
templatesIter.next();

                        // construct File object from path
                        File templateFile = new File(this.themeDir + 
File.separator
                                        + 
templateMetadata.getContentsFile());

                        String contents = loadTemplateFile(templateFile);
                        if (contents == null) {
                                // if we don't have any contents then skip 
this one
                                throw new 
ThemeInitializationException("Couldn't load theme ["
                                                + this.getName() + "] 
template file [" + templateFile
                                                + "]");
                        }

                        // construct ThemeTemplate representing this file
                        theme_template = new SharedThemeTemplate(this, 
themeMetadata
                                        .getId()
                                        + ":" + 
templateMetadata.getName(), templateMetadata
                                        .getAction(), 
templateMetadata.getName(), templateMetadata
                                        .getDescription(), contents, 
templateMetadata.getLink(),
                                        new 
Date(templateFile.lastModified()), templateMetadata
 .getTemplateLanguage(),
                                        templateMetadata.isHidden(), 
templateMetadata.isNavbar());

                        // add it to the theme
                        addTemplate(theme_template);

                        //  **** Set Last Modified *****
                        Date lstModified = new 
Date(templateFile.lastModified());
                        if (getLastModified() == null
                                        || 
lstModified.after(getLastModified())) {
                                setLastModified(lstModified);
                        }
                }
        }


Then in PageServlet reload the theme and then clear the caches

// generate cache key
        String cacheKey = null;
        if (isSiteWide) {
            cacheKey = siteWideCache.generateKey(pageRequest);
        } else {
            cacheKey = weblogPageCache.generateKey(pageRequest);
        }

// **** Development only. Reload if theme has been modified  ***
                if 
(WebloggerConfig.getBooleanProperty("site.themeReloadMode")) {
                        try {

                                ThemeManager manager = null;
                                manager = 
WebloggerFactory.getWeblogger().getThemeManager();

                                boolean reloaded = 
manager.reLoadThemeFromDisk(website.getEditorTheme());

                                if (reloaded) {

                                        if (isSiteWide) {
                                                siteWideCache.clear();
                                        } else {
                                                websitePageCache.clear();
                                        }
                                }

                        } catch (Exception e1) {
                                // ignored
                        }

                }

 // cached content checking
        if ((!this.excludeOwnerPages || !pageRequest.isLoggedIn()) && 
request.getAttribute("skipCache") == null) {


Cheers Greg




Share our environment commitment - conserve resources and contribute to the reduction of CO2 emissions by not printing the email unless absolutely necessary to do so. 

Any opinions expressed are those of the author, not Ricoh UK Ltd. This communication does not constitute either offer or acceptance of any contractually binding agreement. Such offer or acceptance must be communicated in writing. It is the responsibility of the recipient to ensure this email and attachments are free from computer viruses before use and the sender accepts no responsibility or liability for any such computer viruses. 

Ricoh UK Ltd. may monitor the content of emails sent and received via its network for the purpose of ensuring compliance with its policies and procedures. This communication contains information, which may be confidential or privileged. The information is intended solely for the use of the individual or entity named above. If you are not the intended recipient, be aware that any disclosure, copying, distribution or use of the contents of this information is prohibited. If you have received this communication in error, please notify the sender immediately by return email with a copy to  postmaster@ricoh.co.uk . Please contact us on +44 (0) 208 261 4000 if you need assistance. 

Registered in England No: 473236 
VAT No: GB524161280