By Sebastiaan de Jonge, published on Thursday, February 4, 2010 at 18:01

TypoScript can be so useful sometimes! In this example I will display how we can create a nice output of any record in the frontend. And all this without the use of any silly extension.

Explaining the situation and the problem

As easy as some extensions are to be installed, they don't always fit your needs. Today I was working on a problem which came up when I wasn't able to index records user the crawler and indexed_search. There was a small list of front-end users that was displayed, with detailed/single views. The problem was that in this website the extension gsi_feusers_list was used. Which is pretty old, nasty and there was no real possibility to get it indexed. This was partially due to some caching issues, but I will save you the details. 😉

My solution

I chose to recreate the single view with just TypoScript, and I had my reasons for that! First of all, I was not in the mood to rewrite the entire user listing extension or to look for an alternative and reconfigure it. Second, because it took me less than 1 hour to fully create it. And third, because it's possible! 🙂

Getting started

First of all I had to take a look at the original content, it was build up in the following order:

  • Header (name)
  • Image (user image)
  • Introduction (description)
  • Back link

Not so complicated! So I initially started with the template layout, and on the original it looked somewhat like this:

<h1>John Doe</h1>
<div class="imageWrapper">
    <img src="typo3temp/pics/757418ec34.png" alt="" title="" />
</div>
<p class="bodytext">
    A small story about John..
</p>
<p class="bodytext">
    A little about his family...
</p>
<p class="bodytext">
    And something about his professional career
</p>
<p>
    <a href="overview.html">&laquo; back</a>
</p>

I converted this to the following TypoScript (just the setup, no data yet).

lib.frontendUser.detail = CONTENT
lib.frontendUser.detail {
    renderObj = COA
    renderObj {
        ## The header
        10 = TEXT
        10.value.wrap = <h1>|</h1>
        ## The image
        20 = IMAGE
        20.stdWrap.wrap = <div class="imageWrapper">|</div>
        ## The description
        30 = TEXT
        ## The back link
        40 = TEXT
        40.value.wrap = <p>|</p>
    }
}

Getting the record data

The next step is to load the data into the CONTENT object. We do this with the following code:

lib.frontendUser.detail = CONTENT
lib.frontendUser.detail {
  table = fe_users
  select {
    pidInList = 11
    orderBy = name ASC
    andWhere {
        wrap = uid = |
        data = GP:tx_gsifeuserlist_pi1|frontendUser
        # Prevent SQL injections!
        intval = 1
  }
}

So we are selecting everything from the fe_users table, with PID equals 11 and uid equals the id set in the querystring. We also put an intval = 1 at the andWhere statement to prevent SQL injections.

Now that we have the right data available, we just have to put into the data that is outputted. We will go by them, one by one.

Adding the record

We will start off with the header, in this spot we are going to display the users name. So this is what we do.

    10 = TEXT
    10 {
        field = name
        value.wrap = <h1>|</h1>
    }

It's as simple as that! Next comes the image, this will be a little more configurations. Simply because we don't want the image to be bigger than let's say.. 170 pixels.  Notice also that the path has to be set correctly! In my case the images were added with sr_feuser_register, and thus stored here. But this might be different. To check this you may simply check the uploads folder or the extension you are using to upload the images.

    20 = IMAGE
    20 {
        file.import=uploads/tx_srfeuserregister/
        file.import.field = image
        file.maxH = 170
        file.maxW = 170
        wrap = <div class="imageWrapper">|</div>
    }

It all looks a lot more difficult than it actually is! 🙂 Next step the description text. This was taken from an extended field from the fe_users table. Also notice that we user the parseFunc_RTE to render this RTE field properly!

    30 = TEXT
    30 {
        field = tx_myextension_description
        parseFunc < lib.parseFunc_RTE
    }

Finally we finish of with setting the back link. In this case we are linking to a static page (45) containing the user overview.

    40 = HTML
    40.value = &laquo; Back
    40.value.typolink.parameter = 45
    40.value.wrap = <p>|</p>

That's it! All together we have now come up with the following TypoScript:

lib.frontendUser.detail = CONTENT
lib.frontendUser.detail {
    # Query for the user data
    table = fe_users
    select {
        pidInList = 11
        orderBy = name ASC
        andWhere.wrap = uid = |
        andWhere.data = GP:tx_gsifeuserlist_pi1|uid
        # Prevent SQL injections!
        andWhere.intval = 1
    }
    # Render the output
    renderObj = COA
    renderObj {
        # The header
        10 = TEXT
        10 {
            field = name
            wrap = <h1>|</h1>
        }
        # The image
        20 = IMAGE
        20 {
            file {
                import=uploads/media/
                import.field = image
                maxH = 170
                maxW = 170
            }
            wrap = <div class="imageWrapper">|</div>
        }
        # The description
        30 = TEXT
        30 {
            field = tx_myextension_description
            parseFunc < lib.parseFunc_RTE
       }
        # The back link
        40 = TEXT
        40 {
            value = &laquo; Back
            typolink.parameter = 45
            wrap = <p>|</p>
        }
    }
}

The result is the exact same as the extension outputted (in my situation at least), but it allowed me to cache and index these single pages without having to dive into this extension and get my hands really dirty 😉

Comments

BenjaminS
BenjaminS - Thursday, February 4, 2010 at 23:07

cool..! is it btw possible to make your own parseFunc? I see possibilities!
🙂

Pim Broens
Pim Broens - Saturday, February 6, 2010 at 16:45

Sure you can Ben 😉
lib.parseFunc is just some typoscript that is taken from css_styled_content I guess. So writing or overwriting your own should be no problem.
So what possibilities and show me...

Jacco van der Post
Jacco van der Post - Thursday, January 12, 2012 at 16:00

Due to a bug in TYPO3 4.6+ pidInList cannot be 0 ..

http://forge.typo3.org/issues/32212

Took me some hair pulling to find that 😉