Adding Template Select and Image upload to custom post in Wordpress - templates

I have become a bit confused on the best way to move forward with something I'd like to achieve in Wordpress. My problem is partly workflow I think and knowing the correct way to do what I'd like to achieve but also there may be a few blanks on how to actually implement some of what I need to do. I have checked various online resources but they all are specific to what they are doing and I can't easily understand them to apply them in to the context of my own project, which is why I wanted to ask here. I'm sure my initial question will inevitably branch out to sub questions but here we go:
For my website I have created a custom post type called 'projects'. I have successfully set this up.
Then for each project I need to allow the following data to be entered:
Project Title
Project Description
Also post meta data that will display as a list on each project page (I'll need to display both the key and value on the page but only for those fields that contain data 'i.e. I don't want the list to show as Location: blank'):
Client Name:
Location:
Project Value:
Architect:
Engineer:
Site Area:
My main question is this, I need to show images for each project and allow the user to select a 'template' for each project post, this is because there are about 5 grid designs for layout of the images (1 main Image, 1 square image with two small images right side, 3 portrait image cols etc).
I thought the correct way would be to create a custom post type called projects, add write panels to allow easy input of data (I've yet to add image uploads as this will need to vary depending on the template selected and number of images required), at data input stage the user selects the preferred image layout/template and then uploads images for the containers that allow images (I’ll need to id each image upload to position it in the template with CSS, that was the plan).
Firstly, am I approaching this correctly? And secondly, how can I add functionality to the write panel I have created to allow users to a) select a 'Template' (bit like you can with pages but for my custom post type) and b) to add image upload fields which change depending on the template selected?
Finally, I would like to stay away from using plug-ins and try and achieve this myself through functions.php etc. This is to avoid problems later as plugins update or lose support etc.
Any help is appreciated, thank you.

This sort of question seems to come up a lot in regards to Wordpress (I answered essentially the same question the other day). I know you want to avoid plugins but this sounds like a job for Advanced Custom Fields.
You can create exactly the fields you need for your custom post type (including an image upload field), and then add them into the template the corresponds with your custom post type.
ACF does have a 'lite mode' which can be included directly in a theme. This way you needn't worry about updates nuking site functionality. Believe me you will save yourself a lot of time and energy this way.
It's admirable to try and do it with pure WP, but it's a maturing platform, it just doesn't lend itself to this sort of customization easily.

Related

Where to create the Articles in Sitecore?

I'm trying to understand the best approach to create article items in my sitecore 7.2 project.
Basically I'm considering 2 options:
1 - Create an article as a page;
2 - Create an article as a Site Data Item.
1 - Create article pages under a given page (i.e. My Articles). This way each article would have a specific URL out of the box, easier to understand in Content Authors' point of view;
2 - Have a specific folder (i.e. Article Folder) under Site Data. This way we don't need to have a page for each article - I was thinking to have a single Article page that would render the article fields. However this would require more work in terms of URLs, navigation, etc.
Is there any other ideas? Am I missing something? I was also having a look at Buckets...
Thank you
I'm going to disagree with Marek and recommend you opt for option 2.
Storing your articles in folder under a Data node allows those items to be datasourced. This is the principle Sitecore was built on. You can then surface those articles in a number of interesting ways via Widgets such as Promo Panels, prompting the user to click through to read about the article without duplicating its data and requiring Content Editors to manage data multiple times.
It even supports multiple sites, so the Articles can be used in other sites you may add to your Sitecore instance in the future.
As you state it will require extra work in terms of Urls and Navigation but it can be achieved via Sitecore's Wild Card Item and you an even use a great open sourced Module from Sitecore's Marketplace to complete 90% of the work for you. See links below for more information.
You can still implement Marek's point of applying Presentation Details once on the Standard Values of the Wild Cart Item you create. If you are using Sitecore 7 and above you can store all your articles in a Bucket so if you have lots of articles they are stored and searchable in a meaningful way.
http://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2011/09/wildcards-and-data-driven-urls.aspx
https://marketplace.sitecore.net/en/Modules/Wildcard_module.aspx
In a standard one instance setup the easiest implementation is to create articles as pages.
In Sitecore you want to limit the items in a folder to 100 or less which is best practice to keep the content editors experience optimal.
This then leads you needing a folder structure and a couple options:
Manually maintain a folder structure for your articles. For example articles/year/month/day. This gives your editors the most control over the folder structure and allow them to navigate the articles in a more traditional way via a visible folder structure.
Use a bucket which automatically generates the folder structure and hides this complexity from the content editor. This takes the manual folder creation and maintenance away from the content editor and are automatically generated based on the configuration you set out for your bucket. The folders wont be visible to the content editor so they will be forced to search in the bucket for any articles rather then navigate the folders.
Use the shared source News mover module (https://marketplace.sitecore.net/en/Modules/News_mover.aspx). This takes a different approach to the above. It works via a traditional folder structure however it generates folders and moves the item on save based on the date field in the article. So the news mover handles the generation of folders however you will still need to check your not exceeding 100 items per folder again for performance when opening folders with large amounts of items.
With all solutions you must still consider the URLs for your articles as they will include the folder structure by default. This is not always acceptable. I prefer to remove the folder structure from the URL. For this you need to create a custom linkProvider and a custom HttpRequestProcessor. Firstly the linkprovider allows you to ensure the new URL is always created and displayed in your site as you want. Next the HttpRequestProcessor ensures that when navigating to the shortened URL Sitecore recognises it as a valid URL and presents the correct page.
By excluding the folder structure from the URL it also adds the additional benefit that the URL is not dependent on the structure. This means editors can change that folder structure and not need to create redirect items to ensure SEO rankings or users bookmarks are not lost.
The cleaner data model is to use the wildcard approach for the URLs and centralize the storage of articles data in a bucket of datasources. This will give you optimum performance and reuse of the data.
However, this isn't how an author thinks about their website. When they use the system, they tend to navigate to the area where they would view articles and try to create a new one there. Authors tend to think in 'pages', so try to hide whatever data model you are using from them and give them the ability to edit the page with Experience Editor.
Some developers try to optimize too far and forget that the authoring experience is likely the most important piece of the delivered solution. The author doesn't care how efficiently you stored the data, only that they can edit it easily and publish efficiently. Whatever model supports that for your author base is how you should implement it.
My recommendation is a page-based approach where the author creates the URL structure with folders and items, something they understand. Then, if you really need to, you can have the primary article data be a datasource-driven component on the page. The user gets to use all the tools they are familiar with (Experience Editor,preview navigation) but you can still store the raw data in a centralized folder. You could then theoretically swap out the article data using DMS rules, or hide information based on authentication or membership status.
Go with approach 1: article is a page.
Define all your presentation details on Article Page template __Standard Values. All new articles will get them. And you can change some of the presentation details for your chosen articles if you want.
If you know that you'll have lot of articles, think about year/month/day folder structure, e.g. articles/2015/06/12.
Approach 2 doesn't give you anything - you still need to have an item for every article. And as you wrote, it would require additional coding which is not required.

Sitecore - What are the pitfalls of storing content in the renderings field

I'd like to know if anyone has had experience of using rendering parameter fields in Sitecore to store content. If so, what drawbacks are there?
In some respects, this seems like an attractive idea as you can add a sublayout to a page numerous times without needing to create child items and setting each sublayout's datasource to one of these child items.... however putting content into renderings fields has a few disadvantages:
This solution is not localizable since the renderings field is shared, so no good for multi-language sites.
To edit the content (if using the content editor) you need to switch to the presentation tab, click details, select the sublayout then edit the rendering parameters which is all a bit cumbersome.
Are there any more serious consequences of adopting this approach?
There is no way to apply workflow to the fields.
There is no way to enable the fields for the page editor.
You can accomplish this just as easily by using the Page Editor and setting a Datasource Template and Datasource Location on your sublayout.
I'll reiterate something you already pointed out -- it's a shared field, so the content can't be localized.
There's no way to reuse the content stored in parameter fields.
Even if you DID do it, its hard to get the data from the parameters because they are XML-based (hint: add an Image to rendering parameters and look at what value you get back)
Overall, you are breaking the separation of content and presentation that the layout field is intended to provide. Please don't do this, one day a developer following in your footsteps will come across it and then spend all day on http://nooooooooooooooo.com/.

Django strategy for automatically suggesting matching content

I'm looking at porting a custom-written PHP CMS into Django. One of the features the CMS currently has is an image upload function. I write an article, tag it with information, then choose a photo for it. If the system has any photos which have been added to articles with tags in common with the new one, it will suggest the photo for that article too. If there are no matches then a new image can be added.
In case this doesn't make sense, let's say I tag an article as Bruce Springsteen, The Beatles and Led Zeppelin. Next time I add an article with the tag The Beatles, it should suggest I use the image added for the first article.
What would be the best Django-applicable way to implement this? I've looked at the Photologue app and have integrated it, and I know it has tagging support (the problem here is that I'm using django-taggit, whereas Photologue supports django-tagging). One approach could be simply building it myself -- when a user uploads an article, I run a hook after they save it to associate the tags with the image. I'm just not sure how to then autosuggest an image in the admin tools based on that info.
Any ideas/approaches greatly appreciated.
This is almost certainly something you're going to have to build yourself. Django has a moderate number of libraries out there (that you've clearly already found). Unlike other solutions, it doesn't have a lot of things that get you 100% to your desired solution (whereas something like Drupal might get you 100% of the way there).
What you will probably need to do (at a high level) is something like this:
Create an AJAX view that takes the current tags as an argument and does a query on the existing posts to see what tags match and returns images from those posts.
Use jQuery/javascript on your view to call your AJAX view on the page as tags are added
Use jQuery to update a <div> on your page and show all the images that your view returned
Here is a similar example that might help get you started.
You might look into django-ajax as a helper library for your requests, but it definitely isn't necessary.
The hook between the your image module and any other django module can be implemented using django's contenttypes framework which also provides some useful instance methods for returning related/hooked objects.

Django: what is the most appropriate way to provide administrators with the ability to change small snippets of text

Using Django, what is the most appropriate way to provide administrators with the ability to change small snippets of text, for example in one of my sites there is a small piece of text on the front page I would like the administrator to be able to easily change in the backend, however I do not want to create a whole new app or model because then they would be able to create more than one area of text in this way, but I only want it to show up in one place on the homepage.
Any advice?
This might be a bit more than you're looking for, but django-chunks lets you embed snippets of text into your templates and allow administrators to edit them. Because the only way to put a chunk into a template is by embedding it yourself, you don't have to worry about someone creating additional chunks - they just won't show up anywhere on the site.
Create a new setting in the settings file (or if you're using something like Djblets, in the appropriate model [or if you're using something else, wherever it expects settings to be]) for it, and then use it in the template after passing the appropriate context.

Django app that can provide user friendly, multiple / mass file upload functionality to other apps

I'm going to be honest: this is a question I asked on the Django-Users mailinglist last week. Since I didn't get any replies there yet, I'm reposting it on Stack Overflow in the hope that it gets more attention here.
I want to create an app that makes it easy to do user friendly,
multiple / mass file upload in your own apps. With user friendly I
mean upload like Gmail, Flickr, ... where the user can select multiple
files at once in the browse file dialog. The files are then uploaded
sequentially or in parallel and a nice overview of the selected files
is shown on the page with a progress bar next to them. A 'Cancel'
upload button is also a possible option.
All that niceness is usually solved by using a Flash object. Complete
solutions are out there for the client side, like: SWFUpload
http://swfupload.org/ , FancyUpload http://digitarald.de/project/fancyupload/
, YUI 2 Uploader http://developer.yahoo.com/yui/uploader/ and probably
many more.
Ofcourse the trick is getting those solutions integrated in your
project. Especially in a framework like Django, double so if you want
it to be reusable.
So, I have a few ideas, but I'm neither an expert on Django nor on
Flash based upload solutions. I'll share my ideas here in the hope of
getting some feedback from more knowledgeable and experienced people.
(Or even just some 'I want this too!' replies :) )
You will notice that I make a few assumptions: this is to keep the
(initial) scope of the application under control. These assumptions
are of course debatable:
All right, my idea's so far:
If you want to mass upload multiple files, you are going to have a
model to contain each file in. I.e. the model will contain one
FileField or one ImageField.
Models with multiple (but ofcourse finite) amount of FileFields/
ImageFields are not in need of easy mass uploading imho: if you have a
model with 100 FileFields you are doing something wrong :)
Examples where you would want my envisioned kind of mass upload:
An app that has just one model 'Brochure' with a file field, a
title field (dynamically created from the filename) and a date_added
field.
A photo gallery app with models 'Gallery' and 'Photo'. You pick a
Gallery to add pictures to, upload the pictures and new Photo objects
are created and foreign keys set to the chosen Gallery.
It would be nice to be able to configure or extend the app for your
favorite Flash upload solution. We can pick one of the three above as
a default, but implement the app so that people can easily add
additional implementations (kinda like Django can use multiple
databases). Let it be agnostic to any particular client side solution.
If we need to pick one to start with, maybe pick the one with the
smallest footprint? (smallest download of client side stuff)
The Flash based solutions asynchronously (and either sequentially or
in parallel) POST the files to a url. I suggest that url to be local
to our generic app (so it's the same for every app where you use our
app in). That url will go to a view provided by our generic app.
The view will do the following: create a new model instance, add the
file, OPTIONALLY DO EXTRA STUFF and save the instance.
DO EXTRA STUFF is code that the app that uses our app wants to run.
It doesn't have to provide any extra code, if the model has just a
FileField/ImageField the standard view code will do the job.
But most app will want to do extra stuff I think, like filling in
the other fields: title, date_added, foreignkeys, manytomany, ...
I have not yet thought about a mechanism for DO EXTRA STUFF. Just
wrapping the generic app view came to mind, but that is not developer
friendly, since you would have to write your own url pattern and your
own view. Then you have to tell the Flash solutions to use a new url
etc...
I think something like signals could be used here?
Forms/Admin: I'm still very sketchy on how all this could best be
integrated in the Admin or generic Django forms/widgets/...
(and this is were my lack of Django experience shows):
In the case of the Gallery/Photo app:
You could provide a mass Photo upload widget on the Gallery detail
form. But what if the Gallery instance is not saved yet? The file
upload view won't be able to set the foreignkeys on the Photo
instances. I see that the auth app, when you create a user, first asks
for username and password and only then provides you with a bigger
form to fill in emailadres, pick roles etc. We could do something like
that.
In the case of an app with just one model:
How do you provide a form in the Django admin to do your mass
upload? You can't do it with the detail form of your model, that's
just for one model instance.
There's probably dozens more questions that need to be answered before
I can even start on this app. So please tell me what you think! Give
me input! What do you like? What not? What would you do different? Is
this idea solid? Where is it not?
Thank you!
I just released a simple app for this about a month ago: django-uploadify.
It's basically a Django template tag that acts as a wrapper for the very nifty Uploadify (requires jQuery). Using it is as simple as adding this to your template...
{% load uploadify_tags }{% multi_file_upload ‘/upload/complete/url/’ %}
The tag will fire events (1 per file) on both the client-side and server-side (Django signal) to indicate when an incoming file has been received.
For example, assuming you have a model 'Media' that handles all user-uploaded files...
def upload_received_handler(sender, data, **kwargs):
if file:
new_media = Media.objects.create(
file = data,
new_upload = True,
)
new_media.save()
upload_recieved.connect(upload_received_handler, dispatch_uid=‘whatever.upload_received’)
Check out the wiki for info on how to set it up and create the signal handlers (client/server).
About your conceptual implementation from above, here's a few points of consideration:
Having the app automatically create the "File Model" instance probably isn't as robust as people may already have their own models they're working with
If you want to implement any type of security or authentication, you need an open system and less of an 'auto-create' type
I really think signals/events are the way to handle this, and also handle the 'DO OTHER STUFF' part of what you mentioned.
My conclusion was that multi-upload can never really be a form widget in the sense that Django implements form widgets. 1 file will most likely be represented by 1 model instance (with some exceptions), which means that we end up with a situation where 1 widget can represent N model instances. However Django is setup so that a widget represents 1 value for 1 field in 1 instance. It just doesn't fit for the majority of use-cases to have it as a widget (hence why I went the template tag route).