You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/11/28 13:29:49 UTC
svn commit: r721453 - in /incubator/sling/trunk: ./ samples/espblog/
samples/espblog/src/ samples/espblog/src/main/
samples/espblog/src/main/java/ samples/espblog/src/main/java/org/
samples/espblog/src/main/java/org/apache/ samples/espblog/src/main/jav...
Author: bdelacretaz
Date: Fri Nov 28 04:29:48 2008
New Revision: 721453
URL: http://svn.apache.org/viewvc?rev=721453&view=rev
Log:
SLING-673, ESP-based blog sample, based on a contribution by Michael Marth, thanks!
Added:
incubator/sling/trunk/samples/espblog/ (with props)
incubator/sling/trunk/samples/espblog/README.txt (with props)
incubator/sling/trunk/samples/espblog/pom.xml (with props)
incubator/sling/trunk/samples/espblog/src/
incubator/sling/trunk/samples/espblog/src/main/
incubator/sling/trunk/samples/espblog/src/main/java/
incubator/sling/trunk/samples/espblog/src/main/java/org/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java (with props)
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/
incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java (with props)
incubator/sling/trunk/samples/espblog/src/main/resources/
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css (with props)
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png (with props)
incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
Modified:
incubator/sling/trunk/pom.xml
Modified: incubator/sling/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/pom.xml?rev=721453&r1=721452&r2=721453&view=diff
==============================================================================
--- incubator/sling/trunk/pom.xml (original)
+++ incubator/sling/trunk/pom.xml Fri Nov 28 04:29:48 2008
@@ -121,6 +121,7 @@
<module>samples/path-based-rtp</module>
<module>samples/webloader/service</module>
<module>samples/webloader/ui</module>
+ <module>samples/espblog</module>
<!-- Launchpad -->
<module>launchpad/base</module>
Propchange: incubator/sling/trunk/samples/espblog/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Fri Nov 28 04:29:48 2008
@@ -0,0 +1,11 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders
+maven-eclipse.xml
+
Added: incubator/sling/trunk/samples/espblog/README.txt
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/README.txt?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/README.txt (added)
+++ incubator/sling/trunk/samples/espblog/README.txt Fri Nov 28 04:29:48 2008
@@ -0,0 +1,46 @@
+Sling ESP blog sample
+---------------------
+
+WHY THIS SAMPLE?
+----------------
+This demonstrates the use of ESP server-side javascript to implement a simple
+blog, with file attachments.
+
+A java service uses JCR observation to detect incoming files (either uploaded
+via the blog forms, or copied via WebDAV), and creates thumbnails of files image
+files, to demonstrate observation and OSGi SCR services.
+
+HOW TO INSTALL
+--------------
+Build this bundle and install it in Sling.
+
+For example, if Sling is running on port 8888 (which happens if you start
+the launchpad/testing module with "mvn jetty:run"), this will build and
+install it:
+
+ mvn -P autoInstallBundle clean install -Dsling.url=http://localhost:8888/system/console
+
+To verify that the bundle is correctly installed:
+
+1) http://localhost:8888/apps/espblog/html.esp must return the html.esp
+ script.
+
+2) The console at http://localhost:8888/system/console/bundles must
+ list the bundle named "Sling - ESP blog sample" as active.
+
+You also need to set "allow anonymous access" to false in the
+SlingAuthenticator config, via http://localhost:8888/system/console/configMgr
+
+HOW TO TEST
+-----------
+http://localhost:8888/content/espblog/*.html must display the "Sling ESP
+blog sample" page, with the Home/Admin/New Post/... menu.
+
+Create a new post using the "New Post" menu.
+
+The post can include an attachment, if that's an image the included
+ThumbnailGeneratorService generates thumbnails in different sizes, displayed
+on the post's page. This happens asynchronously, so depending on your
+machine's speed the thumbnails might only appear after a few seconds.
+
+The ESP scripts are found under /apps/espblog in the repository.
\ No newline at end of file
Propchange: incubator/sling/trunk/samples/espblog/README.txt
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sling/trunk/samples/espblog/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/pom.xml?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/pom.xml (added)
+++ incubator/sling/trunk/samples/espblog/pom.xml Fri Nov 28 04:29:48 2008
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+ <!--
+ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for
+ additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not
+ use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+ applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>sling</artifactId>
+ <version>3-incubator</version>
+ <relativePath>../../../parent/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.sling.samples</groupId>
+ <artifactId>org.apache.sling.samples.espblog</artifactId>
+ <packaging>bundle</packaging>
+ <version>2.0.3-incubator-SNAPSHOT</version>
+ <name>Sling - ESP blog sample</name>
+ <description>
+ Sample Sling application - blog written using ESP scripts.
+ </description>
+
+ <scm>
+ <connection>scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/samples/espblog</connection>
+ <developerConnection>scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/samples/espblog</developerConnection>
+ <url>http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog</url>
+ </scm>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-scr-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Sling-Initial-Content>initial-content</Sling-Initial-Content>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <excludePackageNames>org.apache.sling.samples.espblog.internal</excludePackageNames>
+ </configuration>
+ </plugin>
+ </plugins>
+ </reporting>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.0.2-incubator</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.api</artifactId>
+ <version>2.0.2-incubator</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
\ No newline at end of file
Propchange: incubator/sling/trunk/samples/espblog/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java (added)
+++ incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java Fri Nov 28 04:29:48 2008
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.samples.espblog;
+
+/** Empty interface, the SCR plugin requires one
+ * to process our service implementation.
+ */
+public interface ThumbnailGeneratorService {
+}
\ No newline at end of file
Propchange: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/ThumbnailGeneratorService.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java (added)
+++ incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java Fri Nov 28 04:29:48 2008
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sling.samples.espblog.internal;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.imageio.ImageIO;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+import javax.jcr.observation.ObservationManager;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.samples.espblog.ThumbnailGeneratorService;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Observe the espblog content for changes, and generate
+ * thumbnails when images are added.
+ *
+ * @scr.service
+ * @scr.component immediate="true" metatype="false"
+ * @scr.property name="service.description" value="Sling ESP blog sample thumbnails generator"
+ * @scr.property name="service.vendor" value="Apache Software Foundation"
+ *
+ */
+public class ThumbnailGeneratorServiceImpl implements ThumbnailGeneratorService, EventListener {
+
+ private Session session;
+ private ObservationManager observationManager;
+
+ /** @scr.reference */
+ private SlingRepository repository;
+
+ /** @scr.property value="/content/espblog" */
+ private static final String CONTENT_PATH_PROPERTY = "content.path";
+
+ private static final Logger log = LoggerFactory
+ .getLogger(ThumbnailGeneratorServiceImpl.class);
+
+ private Map<String, String> supportedMimeTypes = new HashMap<String, String>();
+
+ protected void activate(ComponentContext context) throws Exception {
+ supportedMimeTypes.put("image/jpeg", ".jpg");
+ supportedMimeTypes.put("image/png", ".png");
+
+ String contentPath = (String)context.getProperties().get(CONTENT_PATH_PROPERTY);
+
+ session = repository.loginAdministrative(null);
+ if (repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED).equals("true")) {
+ observationManager = session.getWorkspace().getObservationManager();
+ String[] types = { "nt:file" };
+ observationManager.addEventListener(this, Event.NODE_ADDED, contentPath, true, null, types, false);
+ }
+ }
+
+ protected void deactivate(ComponentContext componentContext) throws RepositoryException {
+ if(observationManager != null) {
+ observationManager.removeEventListener(this);
+ }
+ if (session != null) {
+ session.logout();
+ session = null;
+ }
+ }
+
+ public void onEvent(EventIterator it) {
+ while (it.hasNext()) {
+ Event event = it.nextEvent();
+ try {
+ if (event.getType() == Event.NODE_ADDED && !(event.getPath().contains("thumbnails"))) {
+ log.info("new upload: {}", event.getPath());
+ Node addedNode = session.getRootNode().getNode(event.getPath().substring(1));
+ processNewNode(addedNode);
+ log.info("finished processing of {}", event.getPath());
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ }
+ }
+
+ private String getMimeType(Node n) throws RepositoryException {
+ String result = null;
+ final String mimeType = n.getProperty("jcr:mimeType").getString();
+
+ for(String key : supportedMimeTypes.keySet()) {
+ if(mimeType!=null && mimeType.startsWith(key)) {
+ result = key;
+ break;
+ }
+ }
+
+ if(result == null) {
+ log.info("Node {} rejected, unsupported mime-type {}", n.getPath(), mimeType);
+ }
+
+ if(n.getName().startsWith(".")) {
+ log.info("Node {} rejected, name starts with '.'", n.getPath(), mimeType);
+ result = null;
+ }
+
+ return result;
+ }
+
+ private void processNewNode(Node addedNode) throws Exception {
+ final String mimeType = getMimeType(addedNode);
+ if (mimeType == null) {
+ return;
+ }
+ final String suffix = supportedMimeTypes.get(mimeType);
+
+ // Scale to a temp file for simplicity
+ log.info("Creating thumbnails for node {}", addedNode.getPath());
+ final int [] widths = { 50, 100, 250 };
+ for(int width : widths) {
+ createThumbnail(addedNode, width, mimeType, suffix);
+ }
+ }
+
+ private void createThumbnail(Node image, int scalePercent, String mimeType, String suffix) throws Exception {
+ final File tmp = File.createTempFile(getClass().getSimpleName(), suffix);
+ try {
+ scale(image.getProperty("jcr:data").getStream(), scalePercent, new FileOutputStream(tmp), suffix);
+
+ // Create thumbnail node and set the mandatory properties
+ Node thumbnailFolder = getThumbnailFolder(image);
+ Node thumbnail = thumbnailFolder.addNode(image.getParent().getName() + "_" + scalePercent + suffix, "nt:file");
+ Node contentNode = thumbnail.addNode("jcr:content", "nt:resource");
+ contentNode.setProperty("jcr:data", new FileInputStream(tmp));
+ contentNode.setProperty("jcr:lastModified", Calendar.getInstance());
+ contentNode.setProperty("jcr:mimeType", mimeType);
+
+ session.save();
+
+ log.info("Created thumbnail " + contentNode.getPath());
+ } finally {
+ if(tmp != null) {
+ tmp.delete();
+ }
+ }
+
+ }
+
+ private Node getThumbnailFolder(Node addedNode) throws Exception {
+ Node post = addedNode.getParent().getParent().getParent();
+ if (post.hasNode("thumbnails")) {
+ log.info("thumbnails node exists already at " + post.getPath());
+ return post.getNode("thumbnails");
+ } else {
+ Node t = post.addNode("thumbnails", "nt:folder");
+ session.save();
+ return t;
+ }
+ }
+
+ public void scale(InputStream inputStream, int width, OutputStream outputStream, String suffix) throws IOException {
+ if(inputStream == null) {
+ throw new IOException("InputStream is null");
+ }
+
+ final BufferedImage src = ImageIO.read(inputStream);
+ if(src == null) {
+ final StringBuffer sb = new StringBuffer();
+ for(String fmt : ImageIO.getReaderFormatNames()) {
+ sb.append(fmt);
+ sb.append(' ');
+ }
+ throw new IOException("Unable to read image, registered formats: " + sb);
+ }
+
+ final double scale = (double)width / src.getWidth();
+
+ int destWidth = width;
+ int destHeight = new Double(src.getHeight() * scale).intValue();
+ log.debug("Generating thumbnail, w={}, h={}", destWidth, destHeight);
+ BufferedImage dest = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
+ Graphics2D g = dest.createGraphics();
+ AffineTransform at = AffineTransform.getScaleInstance((double) destWidth / src.getWidth(), (double) destHeight / src.getHeight());
+ g.drawRenderedImage(src, at);
+ ImageIO.write(dest, suffix.substring(1), outputStream);
+ }
+}
\ No newline at end of file
Propchange: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/samples/espblog/src/main/java/org/apache/sling/samples/espblog/internal/ThumbnailGeneratorServiceImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/admin.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<html>
+<%
+pageTitle = "Blog admin"
+load("header.esp")
+%>
+ <body>
+ <div class="title">
+ <div class="logo">
+ <a href="http://incubator.apache.org/sling">
+ <img border="0" src="/apps/espblog/sling-logo.png"/>
+ </a>
+ </div>
+ </div>
+
+ <div class="menu">
+ <%
+ load("menu.esp");
+ %>
+ </div>
+
+ <div class="main">
+ <h1><%= pageTitle %></h1>
+
+ <table>
+ <tr>
+ <th>Title</th>
+
+ <th>Date</th>
+ <th colspan="2">Controls</th>
+ </tr>
+
+ <%
+ df = new java.text.SimpleDateFormat( "yyyy-MM-dd HH:mm" );
+
+ posts = currentNode.getNodes()
+ for (a in posts) {
+ post = posts[a]
+ if(!post.created) {
+ // does not look like one of our posts
+ continue;
+ }
+ %>
+
+ <tr>
+ <td><%=post.title%></td>
+ <td><%=df.format(post.created.getTime())%></td>
+ <td><a href="/content/espblog/posts/<%=a%>.html">View</a> <a href="/content/espblog/posts/<%=a%>.edit.html">Edit</a></td>
+ <td>
+ <form method="POST" action="/content/espblog/posts/<%=a%>">
+ <input name=":redirect" type="hidden" value="/content/espblog/posts.admin.html"/>
+ <input name=":operation" type="hidden" value="delete"/>
+ <input type="submit" value="Delete">
+ </form>
+ </td>
+ </tr>
+
+ <%}%>
+ </table>
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/constants.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,22 @@
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+BLOG_TITLE="Sling ESP blog sample";
+%>
\ No newline at end of file
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/edit.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<html>
+<%
+pageTitle = currentNode.title ? currentNode.title : "New post";
+load("header.esp");
+%>
+ <body>
+
+ <div class="title">
+ <div class="logo">
+ <a href="http://incubator.apache.org/sling">
+ <img border="0" src="/apps/espblog/sling-logo.png"/>
+ </a>
+ </div>
+ </div>
+
+ <div class="menu">
+ <%
+ load("menu.esp");
+ %>
+ </div>
+
+ <div class="main">
+ <h1><%= pageTitle %></h1>
+
+ <form class="hform" method="POST" action="<%= currentNode.getPath().lastIndexOf("*") != currentNode.getPath().length-1 ? currentNode : "/content/espblog/posts/*" %>" enctype="multipart/form-data">
+
+ <p><label>Title</label>
+ <input name="title" type="text" size="80" value="<%= currentNode.getPath().lastIndexOf("*") != currentNode.getPath().length-1 ? currentNode.title : "" %>"></p>
+
+ <p><label>Body</label>
+ <textarea name="posttext" cols="40" rows="5"><%= currentNode.getPath().lastIndexOf("*") != currentNode.getPath().length-1 ? currentNode.posttext : "" %></textarea></p>
+
+ <p><label>File</label><input type="file" name="attachments/*"/></p>
+
+
+ <input type="hidden" name="created"/>
+ <input name=":redirect" type="hidden" value="/content/espblog/posts.admin.html"/>
+
+ <input type="submit" value="Post" class="button">
+ </form>
+ </div>
+ </body>
+</html>
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css Fri Nov 28 04:29:48 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* @override http://incubator.apache.org/sling/site/media.data/site.css */
+
+body { background-color: #ffffff; color: #3b3b3b; font-family: Tahoma, Arial, sans-serif; font-size: 10pt; line-height: 140% }
+h1, h2, h3, h4, h5, h6 { font-weight: normal; color: #000000; line-height: 100%; }
+h1 { font-size: 200% }
+h2 { font-size: 175% }
+h3 { font-size: 150% }
+h4 { font-size: 140% }
+h5 { font-size: 130% }
+h6 { font-size: 120% }
+a { color: #1980af }
+a:visited { color: #1980af }
+a:hover { color: #1faae9 }
+.title { position: absolute; left: 1px; right: 1px; top:25px; height: 81px; background: url(http://incubator.apache.org/sling/site/media.data/gradient.png) repeat-x; background-position: bottom; }
+.logo { position: absolute; width: 15em; height: 81px; text-align: center; }
+.header { text-align: right; margin-right: 20pt; }
+.menu { border-top: 10px solid #f9bb00; position: absolute; top: 107px; left: 1px; width: 15em; bottom: 0px; padding: 0px; background-color: #fcfcfc }
+.menu ul { background-color: #fdf5d9; list-style: none; padding-left: 4em; margin-top: 0px; padding-top: 2em; padding-bottom: 2em; margin-left: 0px; color: #4a4a43}
+.menu a { text-decoration: none; color: #4a4a43 }
+.main { position: absolute; border-top: 10px solid #cde0ea; top: 107px; left: 15em; right: 1px; margin-left: 2px; padding-right: 4em; padding-left: 1em; padding-top: 1em;}
+.code { color: black; background-color: #eeeeee; border: solid 1px black; margin-top: 0.5em; margin-bottom: 0.5em; }
+.codeHeader { text-align: center; font-family: monospace; border-bottom:1px solid black; padding-top: 0.5em; padding-bottom: 0.5em; margin-bottom: 0.5em; }
+.codeContent { padding: 0.5em }
+.codeContent pre { margin: 0em }
+.code-keyword { color: #880000 }
+.code-quote { color: #008800 }
+.code-object { color: #0000dd }
+.code-java { margin: 0em }
+.preformatted { color: black; background-color: #eeeeee; border: solid 1px black; padding: 0.5em }
+.preformattedContent pre { margin: 0em }
+table.confluenceTable { border-collapse:collapse; margin:5px; }
+table.confluenceTable th.confluenceTh { background-color:#FDF5D9; border:1px solid #CCCCCC; padding:3px 4px; text-align:center; }
+table.confluenceTable td.confluenceTd { border:1px solid #CCCCCC; padding:3px 4px; }
+.infoMacro { background-color: #D8E4F1; border: 1px solid #3C78B5; }
+.noteMacro { background-color: #FFFFCE; border: 1px solid #F0C000; }
+.tipMacro { background-color: #DDFFDD; border: 1px solid #009900; }
+.warningMacro { background-color: #FFCCCC; border: 1px solid #CC0000; }
+.note { font-size: 80%; }
\ No newline at end of file
Propchange: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
svn:executable = *
Propchange: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/espblog.css
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/header.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,31 @@
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+load("constants.esp");
+if(typeof(pageTitle) == "undefined") {
+ pageTitle = BLOG_TITLE;
+}
+%>
+
+<head>
+ <link rel="stylesheet" href="/apps/espblog/espblog.css" type="text/css" media="screen" charset="utf-8">
+ <link rel="alternate" type="application/rss+xml" title="RSS Entries" href="http://<%=request.getServerName()%>:<%=request.getServerPort()%>/content/espblog/posts.xml"/>
+ <title><%= pageTitle %></title>
+</head>
\ No newline at end of file
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/html.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<html>
+<%
+load("header.esp");
+load("constants.esp");
+
+function render(attachmentNode) {
+ if(attachmentNode.getNode("jcr:content").getProperty("jcr:mimeType").getString().substring(0,5) == "image") {
+ %><p><img src="<%=attachmentNode%>"></p><%
+ } else {
+ %><p><a href="<%=attachmentNode%>">Download <%=attachmentNode.getName()%></a></p><%
+ }
+}
+
+function renderMedia(postNode, mediaFolderName) {
+ if(postNode.hasNode(mediaFolderName)) {
+ %><h3><%= mediaFolderName %></h3><%
+ var nodes = currentNode.getNode(mediaFolderName).getNodes();
+ for(i in nodes) {
+ render(nodes[i]);
+ }
+ }
+}
+%>
+ <body>
+ <div class="title">
+ <div class="logo">
+ <a href="http://incubator.apache.org/sling">
+ <img border="0" src="/apps/espblog/sling-logo.png"/>
+ </a>
+ </div>
+ </div>
+
+ <div class="menu">
+ <%
+ load("menu.esp");
+ %>
+ </div>
+
+ <div class="main">
+ <h1><%= BLOG_TITLE %></h1>
+ <div id="postbody">
+ <h2><%=currentNode.title ? currentNode.title : ""%></h2>
+ <p><%=currentNode.posttext ? currentNode.posttext : ""%></p>
+
+ <%
+ if(currentNode.hasNode("comments")) {
+ %><h3>Comments</h3><%
+ comments = currentNode.getNode("comments").getNodes()
+ for (a in comments) {
+ comment = comments[a]
+ if(comment.commenttext){
+ %>
+
+ <div>
+ <%=comment.commenter ? comment.commenter : "an anonymous coward"%> said:
+ <p><%=comment.commenttext%></p>
+ </div>
+
+ <%
+ }
+ }
+ }
+ %>
+
+ <% if(currentNode.title) { %>
+ <h3>Comment on this post</h3>
+ <form class="hform" method="POST" action="<%=currentNode%>/comments/*">
+ <p><label>Your name</label><input type="text" size="80" name="commenter"/></p>
+ <p><label>Your comment</label>
+ <textarea name="commenttext" cols="40"></textarea></p>
+ <input name=":redirect" type="hidden" value="<%=currentNode%>.view.html"/>
+ <input type="submit" value="Submit" class="button"/>
+ </form>
+ <% } %>
+ </div>
+ <div id="resources">
+ <% renderMedia(currentNode, "attachments"); %>
+ <% renderMedia(currentNode, "thumbnails"); %>
+ </div>
+ </div>
+ </body>
+</html>
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/list.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+ var queryManager = currentNode.getSession().getWorkspace().getQueryManager();
+ if(request.getParameter('qt')) {
+ var query = queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, nt:unstructured)[jcr:contains(., '"+request.getParameter("qt")+"')] order by @created descending", "xpath");
+ } else {
+ var query = queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, nt:unstructured) order by @created descending", "xpath");
+ }
+ var result = query.execute().getNodes();
+%>
+
+<html>
+
+ <%
+ load("header.esp");
+ %>
+
+ <body>
+ <div class="title">
+ <div class="logo">
+ <a href="http://incubator.apache.org/sling">
+ <img border="0" src="/apps/espblog/sling-logo.png"/>
+ </a>
+ </div>
+ </div>
+
+ <div class="menu">
+ <%
+ load("menu.esp");
+ %>
+ </div>
+
+ <div class="main">
+ <h1><%= pageTitle %></h1>
+ <h2><%= request.getParameter('qt') ? "Search results" : "Recent posts" %></h2>
+
+ <div id="postbody">
+ <%
+ df = new Packages.java.text.SimpleDateFormat( "yyyy-MM-dd HH:mm" );
+
+ while(result.hasNext()) {
+ post = result.nextNode()
+ %>
+
+ <h3><a href="<%= post.getPath() %>.html"><%=post.title%></a></h3>
+ <strong>Posted at <%=df.format(post.created.getTime())%></strong><br>
+ <p><%=post.posttext%><br/><strong class="highlight"><a href="<%=post%>.html"><%=post.hasNode("comments") ? "See comments" : "Be the first to comment"%> </a></strong> </p>
+ <%}%>
+ </div>
+ </div>
+ </body>
+</html>
\ No newline at end of file
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/menu.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,32 @@
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+load("constants.esp");
+%>
+
+<div id="header">
+ <ul class="tabs">
+ <li><a href="/content/espblog/posts.list.html">Home</a></li>
+ <li><a href="/content/espblog/posts.admin.html">Admin</a></li>
+ <li><a href="/content/espblog/posts/*.edit.html">New Post</a></li>
+ <li><a href="/content/espblog/posts.xml">RSS feed</a></li>
+ <li><form method="GET" action="/content/espblog/posts.list.html"><input type="text" name="qt" size="10" value="Search"/></form></li>
+ </ul>
+</div>
\ No newline at end of file
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png?rev=721453&view=auto
==============================================================================
Binary file - no diff available.
Propchange: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
------------------------------------------------------------------------------
svn:executable = *
Propchange: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/sling-logo.png
------------------------------------------------------------------------------
svn:mime-type = image/png
Added: incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp?rev=721453&view=auto
==============================================================================
--- incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp (added)
+++ incubator/sling/trunk/samples/espblog/src/main/resources/initial-content/apps/espblog/xml.esp Fri Nov 28 04:29:48 2008
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+
+<%
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+%>
+
+<%
+ var queryManager = currentNode.getSession().getWorkspace().getQueryManager();
+ var query = queryManager.createQuery("/jcr:root/content/espblog/posts/element(*, nt:unstructured) order by @created descending", "xpath");
+ var result = query.execute().getNodes();
+
+%>
+
+<rss version="2.0">
+ <channel>
+ <title>My Sling Blog</title>
+ <link><%=request.getRequestURL()%></link>
+ <description>RSS 2.0 feed of my Sling blog</description>
+
+ <%
+ df = new java.text.SimpleDateFormat( "EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z", Packages.java.util.Locale.US);
+ var counter = 0;
+ while(result.hasNext() && counter < 10) {
+ counter++;
+ post = result.nextNode()
+ %>
+
+ <item>
+ <title><%=post.title%></title>
+ <link>http://<%=request.getServerName()%>:<%=request.getServerPort()%><%=post%>.html</link>
+ <description><%=post.posttext%></description>
+ <pubDate><%=df.format(post.created.getTime())%></pubDate>
+ </item>
+
+ <%
+ }
+ %>
+
+ </channel>
+</rss>
\ No newline at end of file